Android中的Toast是我们经常会使用的,能够方便的在界面上弹出一个提示语句,还可以控制显示的时长,十分方便。使用Espresso测试Toast的弹出内容不是很好操作,主要由于Toast的布局并不是属于我们当前应用的,而是通过另一个Sevice控制的,这个原理可以看看相关的一些博文,我这里不再详细说明。当时为了测试Toast是否显示正确,也是查了不少文章,最后在Stack Overflow找到了解决的办法,这里给大家介绍一下,但是并不是很完美,后面会详细说明。

我们采用TDD的模式做我们的简单Demo,我们希望界面上有一个文本为点击的按钮,点击该按钮,会弹出一个文本为clicked的Toast,按照这个说明,编写我们的测试代码(项目的Gradle配置见上一篇文章)

package com.yjp.toasttest;

import android.support.test.rule.ActivityTestRule;

import android.support.test.runner.AndroidJUnit4;

import android.widget.Button;

import org.junit.Rule;

import org.junit.Test;

import org.junit.runner.RunWith;

import static android.support.test.espresso.Espresso.onView;

import static android.support.test.espresso.action.ViewActions.click;

import static android.support.test.espresso.assertion.ViewAssertions.matches;

import static android.support.test.espresso.matcher.RootMatchers.withDecorView;

import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;

import static android.support.test.espresso.matcher.ViewMatchers.withText;

import static org.hamcrest.Matchers.allOf;

import static org.hamcrest.Matchers.instanceOf;

import static org.hamcrest.Matchers.not;

@RunWith(AndroidJUnit4.class)

public class MainActivityTest {

@Rule

public ActivityTestRule mActivityRule =

new ActivityTestRule<>(MainActivity.class);

@Test

public void testClickButtonToast() throws Exception {

//界面上有一个文本为点击的按钮并点击按钮

onView(allOf(withText(R.string.click), instanceOf(Button.class)))

.check(matches(isDisplayed()))

.perform(click());

//会弹出一个文本为clicked的Toast

Thread.sleep(1000);

onView(withText(R.string.clicked_en))

.inRoot(withDecorView(not(mActivityRule.getActivity().getWindow().getDecorView())))

.check(matches(isDisplayed()));

}

}

首先,我们使用withText和instanceOf两个View Matcher选择出了我们的Button,检查该Button是否显示,执行了click()操作(View Action)。然后我们sleep了1s,这个就是我上面提到的不太完美的地方,如果不加延时,可能Toast会检测不到。休眠1s后,找到Toast的布局,这里通过withText找到对应的Toast的视图,但这无法保证就是Toast

,也有可能在我们的界面中会有其他的控件使用了clicked这个文本,所以,我们还需要保证我们找的Toast视图不在主界面的DecorView中,这里使用了withDecorView和not两个Matcher。最后,通过check检查是否显示。

上面的代码中,我们将点击和clicked两个文本定义为了两个字符串资源,可以看到withText可以直接传递字符串资源。

点击

clicked

现在运行测试,会报错,错误不贴了,意思就是找不到满足条件的按钮,毕竟我们的MainActivity还没有完成。我们完成我们的布局,添加一个按钮,文本为点击(R.string.click)。

xmlns:app="http://schemas.android.com/apk/res-auto"

xmlns:tools="http://schemas.android.com/tools"

android:layout_width="match_parent"

android:layout_height="match_parent"

tools:context="com.yjp.toasttest.MainActivity">

android:id="@+id/click_button"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="@string/click"

app:layout_constraintBottom_toBottomOf="parent"

app:layout_constraintLeft_toLeftOf="parent"

app:layout_constraintRight_toRightOf="parent"

app:layout_constraintTop_toTopOf="parent"

app:layout_constraintVertical_bias="0.501" />

布局我只是基于项目自动生成的,修改TextView为Button,text设置为点击,我们再次运行测试,这次报错变了,告诉我们找不到Toast的布局。我们添加代码

package com.yjp.toasttest;

import android.os.Bundle;

import android.support.v7.app.AppCompatActivity;

import android.view.View;

import android.widget.Button;

import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

Button clickButton = (Button) findViewById(R.id.click_button);

clickButton.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

String toast = getString(R.string.clicked_en);

Toast.makeText(MainActivity.this, toast, Toast.LENGTH_SHORT).show();

}

});

}

}

再次运行测试,这次测试通过,说明为我们的代码已经满足了需求的要求。

0818b9ca8b590ca3270a3433284dd417.png

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐