不能仅一次启动活动-您是否忘记通过调用getActivity()或startActivitySync或类似方法来启动活动?

时间:2019-06-10 09:01:37

标签: android-espresso

在所有测试之前,我只需一次启动活动。 因此,我为此使用注释@BeforeClass

这里是意式浓缩咖啡的测试:

@RunWith(AndroidJUnit4::class)
class JsonViewActivityTest {

    companion object {
        init {
            // things that may need to be setup before companion class member variables are instantiated
        }

        @get:Rule
var jsonViewIntentsTestRule = IntentsTestRule(JsonViewActivity::class.java, false, false)

        private val instrumentation = InstrumentationRegistry.getInstrumentation()
        private val context = instrumentation.getContext()
        private val targetContext = instrumentation.getTargetContext()
        private val intent = Intent(targetContext, JsonViewActivity::class.java)

        @BeforeClass
        @JvmStatic
        fun beforAll() {
            Intent(targetContext, JsonViewActivity::class.java)
            val bundle = Bundle()
            val inputStream = context.assets.open(StubUtil.TradersStub.ONE_TRADER_HAS_WALLETS.stubName)
            val content = inputStream.readBytes().toString(StandardCharsets.UTF_8)
            val jsonArray = GsonUtil.gson.fromJson(content, JsonArray::class.java)
            val jsonTrader = jsonArray.get(0)
            val trader = GsonUtil.gson.fromJson(jsonTrader, Trader::class.java)
            val wallet = trader.wallets[0]
            bundle.putString(JsonViewActivity.WALLET_JSON, GsonUtil.gson.toJson(wallet))
            intent.putExtras(bundle)

            jsonViewIntentsTestRule.launchActivity(intent)
        }

        @AfterClass
        @JvmStatic
        fun afterAll() {
            jsonViewIntentsTestRule.finishActivity()
        }
    }

    @Test
    fun toolBar_height() {
        onView(withId(R.id.toolBar))
                .check(ViewAssertions.matches(CustomMatchers.withHeightResId(R.dimen.tool_bar_height)))
    }
}

但是测试toolBar_height失败,并显示以下消息:

Client not ready yet..
Started running tests

java.lang.RuntimeException: No activities found. Did you forget to launch the activity by calling getActivity() or startActivitySync or similar?
at androidx.test.espresso.base.RootViewPicker.waitForAtLeastOneActivityToBeResumed(RootViewPicker.java:169)
at androidx.test.espresso.base.RootViewPicker.get(RootViewPicker.java:83)
at androidx.test.espresso.ViewInteractionModule.provideRootView(ViewInteractionModule.java:77)
at androidx.test.espresso.ViewInteractionModule_ProvideRootViewFactory.provideRootView(ViewInteractionModule_ProvideRootViewFactory.java:35)
at androidx.test.espresso.ViewInteractionModule_ProvideRootViewFactory.get(ViewInteractionModule_ProvideRootViewFactory.java:24)
at androidx.test.espresso.ViewInteractionModule_ProvideRootViewFactory.get(ViewInteractionModule_ProvideRootViewFactory.java:10)
at androidx.test.espresso.base.ViewFinderImpl.getView(ViewFinderImpl.java:62)
at androidx.test.espresso.ViewInteraction$2.call(ViewInteraction.java:276)
at androidx.test.espresso.ViewInteraction$2.call(ViewInteraction.java:268)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

1 个答案:

答案 0 :(得分:0)

我跟踪了AndroidJUnit4代码,直到发现发生了什么。快速的答案是,在每次测试开始之前,所有打开的活动都会自动“完成”。这是在android.support.test.runner.MonitoringInstrumentation中完成的。该类包含一个公共的内部类ActivityFinisher,该类实现一个Runnable。在每次测试开始之前,将调用该类的run方法。该代码的作用如下:

public void run() {
  List<Activity> activities = new ArrayList<>();

  for (Stage s : EnumSet.range(Stage.CREATED, Stage.STOPPED)) {
    activities.addAll(mLifecycleMonitor.getActivitiesInStage(s));
  }

  Log.i(TAG, "Activities that are still in CREATED to STOPPED: " + activities.size());

  for (Activity activity : activities) {
    if (!activity.isFinishing()) {
      try {
        Log.i(TAG, "Finishing activity: " + activity);
        activity.finish();
      } catch (RuntimeException e) {
        Log.e(TAG, "Failed to finish activity.", e);
      }
    }
  }
}

对activity.finish()的调用是导致您收到消息“找不到活动”的罪魁祸首。简而言之,没有实现AndroidJUnit4来执行您要尝试执行的操作。我能理解您为什么要这样做,但是现有的AndroidJUnit4Runner不能那样工作。

我还没有研究是否有一种简单的方法来解决此问题。您可以做的一件简单的事情就是将测试类构造为仅包含一个测试。在@Before方法中启动所需的活动,并在单个@Test方法中执行所有活动测试。这样可以防止每次测试再次“结束”和“开始”活动。解决此问题的另一种可能方法是编写自己的自定义运行器类,这可能比您想做的工作还要多。不幸的是,我不知道这种方法是否真的有效。还是您仍然会遇到相同的问题。

我会留下我的答案,但是否有一个简单的方法可以让android活动在多个测试中保持打开状态。