【问题标题】:Test order with espresso用浓缩咖啡测试订单
【发布时间】:2014-08-14 12:40:25
【问题描述】:

有没有办法在android中设置测试运行顺序?
我使用 Espresso 框架,需要测试很多活动和它们之间的转换。我想为这些活动编写不同的测试,但我需要一个特定的顺序来运行这些测试。

【问题讨论】:

  • 作为良好的测试实践,您的测试确实不应该有顺序。您可能想退后一步分析您的情况。
  • @spinster - 我同意单元测试应该以任何顺序运行,但是测试框架现在已经扩展到集成/组件以及最经常需要订购的功能测试。例如,您需要先存在数据库表,然后才能对 CRUD 操作进行组件测试。也许我们可以争辩说那些框架,如 Spring、Android Espresso 等应该提供这样的排序。但是,这需要更改核心库,因此在 Junit 中使用套件级排序将是一个不错的功能。

标签: android testing android-espresso


【解决方案1】:

espresso 设置测试的运行顺序

从 Junit 4.11 开始带有 @FixMethodOrder 注释。无需使用自定义解决方案,只需升级您的 junit 版本并使用 FixMethodOrder(MethodSorters.NAME_ASCENDING) 注释测试类。详情请查看发行说明。

这是一个示例:

import org.junit.runners.MethodSorters;

import org.junit.FixMethodOrder;
import org.junit.Test;

@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class SampleTest {

   @Test
   public void A_firstTest() {
      System.out.println("first");
   }

   @Test
   public void B_secondTest() {
      System.out.println("second");
   }
}

【讨论】:

  • 如果要按顺序运行测试(带类名)怎么办?
【解决方案2】:

正如@spinster 上面所说,您应该以一种顺序无关紧要的方式编写测试。

我相信 Junit 3 将按照完全限定类名的字母顺序运行测试,所以理论上你可以通过按照你希望它们执行的顺序按字母顺序命名它们(包名、类名、方法名)来控制顺序,但我不建议这样做。

见: How to run test methods in specific order in JUnit4? How to pre-define the running sequences of junit test cases?

【讨论】:

  • 哇...这对我来说听起来很疯狂...如果每个测试方法都需要自己的设置,那么测试套件可能会永远持续下去...特别是如果设置功能已经由之前运行的测试测试方法..使用该方法,您将一遍又一遍地重新测试场景,只是为了达到每个给定测试方法所需的状态...如果指定测试顺序是一个坏主意...强制字母顺序更糟糕一。
  • 是的,这有点“疯狂”,我不会推荐它,但它是对所提出问题的回答。
  • 我不同意,如果您正在测试将 api 令牌存储在内存中的 api 调用(使用单例)并且其他测试访问该令牌怎么办。你还觉得顺序不重要吗?
【解决方案3】:

您可以添加注释作为测试运行器夹具,如下所示:

@FixMethodOrder(MethodSorters.NAME_ASCENDING)

就在类名的上方

【讨论】:

    【解决方案4】:

    是的,您可以使用带有 test_name 的订单号来设置订单,请参见下面的示例-

    public class MyEspressoTest
            extends ActivityInstrumentationTestCase2<UserLoginActivity> {
    
        private UserLoginActivity mActivity;
    
        public MyEspressoTest() {
            super(UserLoginActivity.class);
        }
    
        @Before
        public void setUp() throws Exception {
            super.setUp();
            injectInstrumentation(InstrumentationRegistry.getInstrumentation());
            mActivity = getActivity();
        }
    
        public void test1InvalidPropigerLogin() {
            // Type text and then press the button.
    
            //setContentView function to see the layout
    
            onView(withId(R.id.username))
                    .perform(typeText("hill.hacker@gmail.com"), closeSoftKeyboard());
            onView(withId(R.id.password))
                    .perform(typeText("hhhhh"), closeSoftKeyboard());
    
            onView(withId(R.id.user_login_button)).perform(click());
            // Check that the text was changed.
            onView(withId(R.id.login_status))
                    .check(matches(withText("Invalid username or password")));
    
            //System.out.println("Test pass with invalid user and password");
        }
    
        public void test2ValidPropigerLogin() {
            // Type text and then press the button.
    
            onView(withId(R.id.username))
                    .perform(typeText("hill.hacker@like.com"), closeSoftKeyboard());
            onView(withId(R.id.password))
                    .perform(typeText("gggggg"), closeSoftKeyboard());
    
            onView(withId(R.id.user_login_button)).perform(click());
    
            //System.out.println("Test pass with valid user and password");
        }
    
        public void test3ForgetPasswordButton() {
    
            onView(withId(R.id.forgot_pwd_button)).perform(click());
    
            //onView(isRoot()).perform(ViewActions.pressBack());
    
            onView(withId(R.id.email_edittext))
                    .perform(typeText("hill.hacker@propiger.in"), closeSoftKeyboard());
            onView(withId(R.id.reset_password_button)).perform(click());
            // Check that the text was changed.
            onView(withId(R.id.reset_result))
                    .check(matches(withText("Email not registered with propiger")));
        }
        public void test4ForgetPasswordButton2() {
    
            onView(withId(R.id.forgot_pwd_button)).perform(click());
    
            onView(withId(R.id.email_edittext))
                    .perform(typeText("Hill.Hacker@like.com"), closeSoftKeyboard());
            onView(withId(R.id.reset_password_button)).perform(click());
            // Check that the text was changed.
            onView(withId(R.id.reset_result))
                    .check(matches(withText("Reset password link sent successfully")));
        }
        public void test5RegisterButton() {
            onView(withId(R.id.register_button)).perform(click());
    
                  //onView(isRoot()).perform(ViewActions.pressBack());
    
            onView(withId(R.id.register_name_edittext))
                    .perform(typeText("Hill Hacker"), closeSoftKeyboard());
            onView(withId(R.id.register_email_edittext))
                    .perform(typeText("Hill.Hacker+888@gmail.com"), closeSoftKeyboard());
            onView(withId(R.id.register_mobileno_edittext))
                    .perform(typeText("9090909090"), closeSoftKeyboard());
            onView(withId(R.id.register_password_edittext))
                    .perform(typeText("password111"), closeSoftKeyboard());
            onView(withId(R.id.register_confirm_password_edittext))
                    .perform(typeText("password111"), closeSoftKeyboard());
            //onView(withId(R.id.register_country_spinner)).perform(click());
            //onView(isRoot()).perform(withId(R.id.register_country_spinner, Sampling.SECONDS_15));
            onData(allOf(is(instanceOf(String.class)), is("India")))
                    .perform(click());
    
           onView(withId(R.id.register_country_spinner)).check(matches(withText(containsString("India"))));
    
            onView(withId(R.id.register_button)).perform(click());
    
        }
    
    
    }
    

    【讨论】:

      【解决方案5】:

      我需要先测试 loginActivity 测试,如果成功,它将登录用户。然后我应该测试其他活动。 LogoutActivity 测试应该在最后运行。因此,需要进行活动序列测试。

      【讨论】:

      • 您可以将一些授权\取消授权功能从测试中放到特定的方法中。然后从 LoginTest 你只需调用授权方法,从 LogoutTest - 授权然后取消授权。然后其他测试将扩展一些 BaseTest,这些 BaseTest 将在 setUp 方法中获得授权,如果需要,在 tearDown 中取消授权
      【解决方案6】:

      你有 3 种方法:



      方式 1:JUnit 4 和 5 工作

      @Test
      public void testFunctionMain() {
          test1(); 
          test2()
          test3(); 
      }
      

      方式 2: JUnit 4 和 5 工作

      使用@FixMethodOrder

      @FixMethodOrder(MethodSorters.NAME_ASCENDING)
      @RunWith(AndroidJUnit4::class)
      class LoginActivityTest {
      }
      

      方式 3:Junit5 工作

      使用@Order

      @Test
      @Order(2)
      public void testFunction(){
      }
      

      【讨论】:

        【解决方案7】:

        在类名上方添加注解@FixMethodOrder(MethodSorters.NAME_ASCENDING),并按升序命名方法。

        请参阅以下链接。答案就是满足您的需求。

        https://stackoverflow.com/a/41198659/4675067

        https://stackoverflow.com/a/34456810/4675067

        【讨论】:

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