如何使用 Espresso 测试特定活动?

Posted

技术标签:

【中文标题】如何使用 Espresso 测试特定活动?【英文标题】:How to test a specific Activity with Espresso? 【发布时间】:2016-07-25 13:59:56 【问题描述】:

我才刚刚开始在 android 中进行测试,这似乎非常基础,但经过大量谷歌搜索后,我仍然无法在任何地方找到答案。

在我的 Android 应用中,显示的第一个活动是登录屏幕,然后是主屏幕,其中包含导航到其他活动的选项。为了测试我想要的活动,我目前必须先完成这两个活动。

如何设置 Espresso 测试(使用 ActvityTestRule/JUnit4)以便它立即启动我想要测试的活动?

编辑

更具体地说,我的问题是,在我看到的所有 Espresso 测试教程中,所有测试都从应用程序的主要活动开始,ActivityTestRule 看起来像这样

@Rule
public final ActivityTestRule<MainActivity> mRule = new ActivityTestRule<MainActivity>(MainActivity.class);

我希望测试从指定的活动开始,目前我通过不断重复这样的测试代码来导航到该活动

onView(withId(R.id.go_to_other_activity_button)).perform(click())

【问题讨论】:

我可以建议this link 和this one吗? 我已经看到了这些链接,你指的是哪些具体信息可以帮助我解决我的问题? 抱歉@Moses,但从您的问题来看,您并不清楚您在此处发布之前搜索了一些解决方案 我已经编辑了我的问题以反映这一点。 我意识到这应该是一件简单的事情,您可以将上面示例中的 MainActivity 替换为您想要测试的任何活动,但这对我不起作用,这导致了我的困惑。我仍然不知道为什么要启动默认活动而不是我在 ActivityTestRule 中声明的活动。 【参考方案1】:

如果你想运行特定的活动,那么: ActivityTestRule 或 IntentTestRule 是您所需要的。

合同很容易解释,只需将您想要开始的活动设置为第一个参数。

ActivityTestRule<>(ActivityYouWantToStart.class, initialTouchMode, launchActivity) //rule for activity start


IntentTestRule<>(ActivityYouWantToStart.class, initialTouchMode, launchActivity) //used for testing intents and activities

这里需要注意的是 launchActivity 布尔值。 如果将此设置为 true,则每个测试都会自动启动活动。

它的其他用途是,如果某些活动希望在运行之前向其发送一些意图、数据或类似内容,您可以将此参数设置为 false 并在运行测试/活动之前准备您的应用.

例如,如果您需要保存在共享首选项中的登录用户来运行活动 B,并且该活动的逻辑显示:

if(!userIsLoggedIn())

    jumpToMainActivity();


然后,您可以在运行该测试之前保存一些模拟用户,或者例如用模拟对象填充数据库,并在为活动 B 准备好环境之后,然后调用。

mActivityRule.launchActivity(null);

注意launchActivity有一个参数,这实际上是Activity B收到的Intent,如果它期望一些额外的数据,你可以在开始测试之前准备好Intent。

运行自定义活动的完整示例:

/**
* Testing of the snackbar activity.
**/
@RunWith(AndroidJUnit4.class)
@LargeTest
public class SnackbarActivityTest
    //espresso rule which tells which activity to start
    @Rule
    public final ActivityTestRule<SnackbarActivity> mActivityRule = 
        new ActivityTestRule<>(SnackbarActivity.class, true, false);


    @Override
    public void tearDown() throws Exception 
        super.tearDown();
        //just an example how tear down should cleanup after itself
        mDatabase.clear();
        mSharedPrefs.clear();
    

    @Override
    public void setUp() throws Exception 
        super.setUp();
        //setting up your application, for example if you need to have a user in shared
        //preferences to stay logged in you can do that for all tests in your setup
        User mUser = new User();
        mUser.setToken("randomToken");
    

    /**
    *Test methods should always start with "testXYZ" and it is a good idea to 
    *name them after the intent what you want to test
    **/
    @Test
    public void testSnackbarIsShown() 
        //start our activity
        mActivityRule.launchActivity(null);
        //check is our text entry displayed and enter some text to it
        String textToType="new snackbar text";
        onView(withId(R.id.textEntry)).check(matches(isDisplayed()));
        onView(withId(R.id.textEntry)).perform(typeText(textToType));
        //click the button to show the snackbar
        onView(withId(R.id.shownSnackbarBtn)).perform(click());
        //assert that a view with snackbar_id with text which we typed and is displayed
        onView(allOf(withId(android.support.design.R.id.snackbar_text), 
        withText(textToType))) .check(matches(isDisplayed()));
    

【讨论】:

以上是关于如何使用 Espresso 测试特定活动?的主要内容,如果未能解决你的问题,请参考以下文章

如何让 Espresso 单击特定的 RecyclerView 项目?

Android Marshmallow:使用 Espresso 测试权限?

Espresso:如何测试 ImageButton 的背景可绘制对象

从 Maps Intent espresso 回到活动 - UI 测试

使用 Espresso 和 Spoon 运行特定测试

Android - Espresso:为每次测试重新创建活动