【问题标题】:Is there a way to run Espresso test with multiple test methods but only one setup method?有没有办法使用多种测试方法但只有一种设置方法来运行 Espresso 测试?
【发布时间】:2015-05-29 09:03:32
【问题描述】:

我今天有一个简单的测试:

@RunWith(AndroidJUnit4.class)
@LargeTest
public class WhenNavigatingToUsersView {

    @Rule
    public ActivityTestRule<MainActivity> mActivityRule = 
        new ActivityTestRule(MainActivity.class);
    private MainActivity mainActivity;

    @Before
    public void setActivity() {
        mainActivity = mActivityRule.getActivity();
        onView(allOf(withId(R.id.icon), hasSibling(withText(R.string.users)))).perform(click());
    }

    @Test
    public void thenCorrectViewTitleShouldBeShown() {
        onView(withText("This is the Users Activity.")).check(matches(isDisplayed()));
    }

    @Test
    public void thenCorrectUserShouldBeShown() {
        onView(withText("Donald Duck (1331)")).check(matches(isDisplayed()));
    }
}

但是对于每个测试方法,setActivity 都会运行,如果您有 10-15 个方法,最终会很耗时(如果您也有很多视图)。

@BeforeClass 似乎不起作用,因为它必须是静态的,因此也迫使 ActivityTestRule 也是静态的。

那么还有其他方法可以做到这一点吗?而不是在同一个测试方法中有多个断言?

【问题讨论】:

    标签: android junit4 android-espresso


    【解决方案1】:

    @Before 注释只能在包含初步设置的方法之前。初始化所需对象,获取当前会话或当前活动,您就明白了。

    它正在替换 ActivityInstrumentationTestCase2 中的旧 setUp() 方法,就像 @After 替换 tearDown() 一样。 这意味着它打算在类中的每个测试之前执行,并且应该保持这种状态。

    此方法中不应有 ViewInteractionDataInteractionAssertionsView 操作,因为这不是它的目的。

    在您的情况下,只需从 setActivity() 中删除 onView() 调用并将其放入实际测试方法中,如有必要,在每个测试方法中,如下所示:

    @RunWith(AndroidJUnit4.class)
    @LargeTest
    public class WhenNavigatingToUsersView {
    
        @Rule
        public ActivityTestRule<MainActivity> mActivityRule = 
            new ActivityTestRule(MainActivity.class);
        private MainActivity mainActivity;
    
        @Before
        public void setActivity() {
            mainActivity = mActivityRule.getActivity();
            // other required initializations / definitions
        }
    
        @Test
        public void thenCorrectViewTitleShouldBeShown() {
            onView(allOf(withId(R.id.icon), hasSibling(withText(R.string.users)))).perform(click());
            onView(withText("This is the Users Activity.")).check(matches(isDisplayed()));
        }
    
        @Test
        public void thenCorrectUserShouldBeShown() {
            onView(allOf(withId(R.id.icon), hasSibling(withText(R.string.users)))).perform(click());
            onView(withText("Donald Duck (1331)")).check(matches(isDisplayed()));
        }
    }
    

    【讨论】:

    • 你有点忽略了我的意思......有没有办法不必为每个测试方法定义视图交互?对我来说,一个好的单元测试是一个测试方法每个测试应该只有一个断言,并且在另一种方法中进行设置。考虑这个视图将充满我想要验证它们是否存在的字段,每次测试与视图交互会非常昂贵。当我只想“打开”该视图一次并执行多个测试时。
    • 为什么setActivity中不能有view交互等东西?更好的名称是 setupContext 或其他名称,并将所有先决条件添加到那里的测试中。这就是 junit 中 @Before 关键字的意图...
    【解决方案2】:

    您的另一个选择是将这些测试分开。

    单击用户的图标将在 HomeActivity 测试类中,而其余测试将在 UserActivity 测试类中。

    UserActivity 测试类将使用正确的 Intent 启动 UserActivity(您可以通过将 false 布尔值传递到 Rule 构造函数并手动调用 launchActivity(intent) 来实现)。

    这将消除每次设置活动的必要性。它还将摆脱对主要活动的持续依赖。如果出现问题,您的 UserActivity 测试将完好无损并产生结果,而 MainActivity 中的测试将发现问题。

    实际上,通过这样做,您的测试可能会变成 M​​ediumSize,因为运行时间会急剧减少。

    【讨论】:

    • 我可能会这样做。但是 UsersActivity 不是一个活动,它是一个片段。到目前为止,我只有一项活动;主要活动。并且所有导航都转到不同的片段。
    【解决方案3】:

    你可以试试这个:

    **** Setting ****
    public void testStory() throws Exception {
    
    }
    
    public void testStory2() throws Exception {
    
    }
    
    public void testStory3() throws Exception {
    
    }
    

    尝试通过以下命令运行您的测试:

    ./gradlew cC 
    

    【讨论】:

      【解决方案4】:

      您是否尝试按照以下方式进行操作或对其进行小幅改动以满足您的需求:

      @Rule
      public ActivityTestRule<MainActivity> mActivityRule = new ActivityTestRule(MainActivity.class);
      private MainActivity mainActivity = mActivityRule.getActivity();
      
      @BeforeClass
      public static void setActivity() {
          onView(allOf(withId(R.id.icon), hasSibling(withText(R.string.users)))).perform(click());
      }
      

      这样,您的“mainActivity”不必是静态的。此外,setActivity() 方法只会被调用一次。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多