【问题标题】:How to Access Activity from ActivityScenarioRule如何从 ActivityScenarioRule 访问活动
【发布时间】:2020-05-22 10:47:01
【问题描述】:

我正在使用 ActivityScenarioRule 进行 Espresso UI 测试,我想访问方法 getStringArray(),调用它需要 Activity。那么,有什么方法可以通过ActivityScenarioRule 检索Activity,可能类似于ActivityTestRule 中的getActivity

@Rule
    public ActivityScenarioRule activityScenarioRule = new ActivityScenarioRule<>(MainActivity.class);

我没有使用ActivityTestRule,因为它已被弃用!

【问题讨论】:

标签: java android android-espresso


【解决方案1】:

既然您似乎在使用 Java,那么您应该这样做:

@Rule
ActivityScenarioRule<MainActivity> activityScenarioRule = new ActivityScenarioRule<>(MainActivity.class);

@Test
public void test() {
    activityScenarioRule.getScenario().onActivity(activity -> {
        // use 'activity'.
    });
}

请阅读documentation,了解有关这些与被测活动交互的新方式的更多信息。

【讨论】:

  • 如何从 ActivityTestRule 升级到 ActivityScenarioRule 而不重写每个测试用例以适应这种模式?
  • @Phlip 在下面查看我的答案
【解决方案2】:

一种相当简单的 Java 获取方式:

private ActivityScenario mActivityScenario;

@After
public void tearDown() throws Exception {
  if (mActivityScenario != null) {
    mActivityScenario.close();
  }
  mActivityScenario = null;
}

@Override
public Activity getActivity() {
  if (mActivityScenario == null) {
    mActivityScenario = ActivityScenario.launch(getActivityClassForScenario());
  }
  return tryAcquireScenarioActivity(mActivityScenario);
}

protected static Activity tryAcquireScenarioActivity(ActivityScenario activityScenario) {
  Semaphore activityResource = new Semaphore(0);
  Activity[] scenarioActivity = new Activity[1];
  activityScenario.onActivity(activity -> {
    scenarioActivity[0] = activity;
    activityResource.release();
  });
  try {
    activityResource.tryAcquire(15000, TimeUnit.MILLISECONDS);
  } catch (InterruptedException e) {
    Assert.fail("Failed to acquire activity scenario semaphore");
  }
  Assert.assertNotNull("Scenario Activity should be non-null", scenarioActivity[0]);
  return scenarioActivity[0];
}

【讨论】:

    【解决方案3】:

    Espresso 声明如下:

    同时,框架阻止直接访问活动 和应用程序的视图,因为持有这些对象和 在 UI 线程之外对它们进行操作是主要的测试来源 片状。

    当没有其他方法时,我使用以下方法从 ActivityScenarioRule 获取任意活动。它使用接受的答案中提到的 onActivity

    private <T extends Activity> T getActivity(ActivityScenarioRule<T> activityScenarioRule) {
            AtomicReference<T> activityRef = new AtomicReference<>();
            activityScenarioRule.getScenario().onActivity(activityRef::set);
            return activityRef.get();
        }
    

    onActivity 中的任何 onView(...) 代码都会导致我的测试用例超时。因此,我提取了该活动并在 onActivity 之外成功使用它。当心寿!请参阅上面的声明。

    【讨论】:

    • 必须将活动打包在某个东西中,以避免 Java 中的有效最终错误。
    【解决方案4】:
    @Test
        fun checkForUpdate() {
            val scenario = ActivityScenario.launch(MainActivity::class.java)
            scenario.onActivity {
                UpdateTool.checkForUpdate(it)
            }
        }
    

    【讨论】:

    • 虽然此代码可能会回答问题,但提供有关它如何和/或为什么解决问题的额外上下文将提高​​答案的长期价值。
    猜你喜欢
    • 1970-01-01
    • 2021-05-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-15
    • 2021-11-21
    • 1970-01-01
    相关资源
    最近更新 更多