我正在测试一个不寻常的情况。我正在使用 Espresso 来编写我的测试。我知道 Espresso 和 InstrumentationTestCase 不适合这样做。

我在一个类中创建了一个侦听器,它会通知我某个值的更改。我在我的测试套件中使用监听器。

当我从侦听器获取值时,我需要断言该值已更改。

我的问题是测试将在我收到侦听器的值之前结束。

    private void sendSpeedChanges() {
    setStaticSpeed(new Random().nextInt(10) + 2);
    try {
        runTestOnUiThread(new Runnable() {
            @Override
            public void run() {
                consoleActivity.onSpeedChanged(getStaticSpeed(), false);
            }
        });
    } catch (Throwable throwable) {
        throwable.printStackTrace();
    }

}

private void createSpeedDelegate() {
    EspressoMachineValues.setOnSpeedChangeListener(new EspressoMachineValues.OnSpeedChangeListener() {
        @Override
        public void onSpeedChanged(double speed) {
            //assert speed is correct.
            assertTrue(getStaticSpeed() == speed);
        }
    });

}

这是我正在使用的两种方法。这 createSpeedDelegate() 是在一开始就调用的。然后我打电话 sendSpeedChanges. 。我需要执行 X 次。


笔记:

  • 检索信息大约需要 200 毫秒(平均)。
  • 我无法打电话 sendSpeedChanges() 直到我检查了值 onSpeedChange()
  • 我无法使用 Thread.sleep(); 因为监听器位于主线程上。

我努力了 添加一个 getInstrumentation().wait(2000); 并且 getInstrumentation().waitForIdleSync(); 显然,两者都不起作用。

在完美的世界中,我会这样做:

   for (int i = 0; i < 42; i++) {
        sendSpeedChanges();
        i++;
    }

但是,这不会等待检查值。如果我确实等待该值,测试运行程序会认为所有测试都已完成并终止。

我的问题 是,有没有办法控制测试何时退出?尽管我的测试 出现 待完成。

有帮助吗?

解决方案

在您的测试中,您将需要创建一个控制语句,以便在您希望测试运行时保持该测试运行。

while(myTestNeedsToRun) {
    if(speedChangeReceived) {
        sendSpeedChange();
        speedChangeReceived = false;
    }
}

private void createSpeedDelegate() {
   EspressoMachineValues.setOnSpeedChangeListener(new EspressoMachineValues.OnSpeedChangeListener() {
    @Override
    public void onSpeedChanged(double speed) {
        //assert speed is correct.
        assertTrue(getStaticSpeed() == speed);
        speedChangedReceived = true;
    }
});

一旦你决定完成运行你刚刚设置的测试 myTestNeedsToRun = false 然后你的测试就会结束。

其他提示

或者,您可以创建 IdlingResource 来监控您的速度。IdlingResource 是 Espresso 用于验证主线程空闲或 AsyncTask 池中没有运行 AsyncTask 的方法。

看看 计算空闲资源 库源代码中的类。你可以实现类似的东西。在你的情况下,它可能是这样的:

[...]

private int mTargetSpeed;
private volatile ResourceCallback resourceCallback;

@Override
public boolean isIdleNow() {
  boolean isIdle = false;
  if (getStaticSpeed() == mTargetSpeed) {
     isIdle = true;
     resourceCallback.onTransitionToIdle();
  } else {
     isIdle = false;
  }

  return isIdle;
}

在测试中,每当您想要等待速度达到所需水平时,您应该执行以下操作:

[...]
SpeedIdlingResource speedIdlingResource = new SpeedIdlingResource ("my_idling_resource");
Espresso.registerIdlingResources(speedIdlingResource);

这样,Espresso 将阻塞,直到您的空闲资源告诉框架您的 SpeedMonitor 空闲。这很好,因为您利用所有 Espresso 同步框架来监控何时达到目标速度,因此您的测试将比忙碌的等待更可靠、更快。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top