2

我正在测试一个不寻常的情况。我正在使用 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++;
    }

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

我的问题是,是否有办法控制测试何时退出?即使我的测试似乎已经完成。

4

2 回答 2

8

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

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

[...]

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 同步框架来监控您何时达到目标速度,因此您的测试将比进行占用等待更可靠和更快。

于 2014-01-27T11:00:12.827 回答
2

在您的测试中,您将需要创建一个控制语句,只要您希望它运行,它就会保持该测试运行。

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,然后您的测试将结束。

于 2014-01-09T01:27:40.800 回答