Не удается запустить действие только один раз - Вы забыли запустить действие, вызвав getActivity () или startActivitySync или подобное? - PullRequest
0 голосов
/ 10 июня 2019

Мне нужно запустить действие только один раз перед всеми тестами. Поэтому я использую аннотацию @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 голосов
/ 16 июля 2019

Я отслеживал код 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. Это препятствует тому, чтобы действие было «закончено» и «запущено» снова для каждого теста. Другой возможный способ обойти это - написать свой собственный класс бегуна, который может быть немного больше работы, чем вы хотите. К сожалению, я не знаю достаточно, если этот подход будет работать на самом деле; или вы все равно столкнетесь с той же проблемой.

Я оставляю свой ответ в виде открытого вопроса другим о том, существует ли простой способ сохранить активность андроида открытым в течение нескольких тестов.

...