等待回调而不阻塞主线程

时间:2015-05-26 18:27:10

标签: java android android-testing android-espresso android-instrumentation

我被困住了,很乐意得到任何帮助!

我正在为Android库编写测试。任务是在活动中执行某些操作并检查库是否正确响应。 我的问题是我的测试在活动中的所有操作完成后完成,但我通过回调得到测试结果(并且只有在测试结束时我才会收到此回调)。所以,我想以某种方式告诉测试框架测试没有结束,直到收到回调(或直到时间用完)。这就是我现在所拥有的:

@Test
public void testSimpleSetup() {

    /* ... */

    InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
        @Override
        public void run() {
            testManager.startTest(MAX_WAIT_TIME); // this object calls onTestResult(boolean) after time t (t <= MAX_WAIT_TIME)

            /* working with activity here */
        }
    });
    InstrumentationRegistry.getInstrumentation().waitForIdleSync();
}

@Override
public void onTestResult(boolean passed) {
    // assertTrue(passed);
    Assert.fail();
}

我希望这个测试失败,但实际上onTestResulttestSimpleSetup完成后调用{As}不会影响测试结果。

提前致谢。

2 个答案:

答案 0 :(得分:2)

检查this post。我修改了一下代码,因为我读了following

  

在一个参数版本中,中断和虚假唤醒是   可能,这个方法应该总是在循环中使用:

Object mon = new Object(); //reference in your Activity
boolean testOnGoing = true;
/*...*/

InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
        @Override
        public void run() {
           synchronized (mon) {
           testManager.startTest(MAX_WAIT_TIME); 
           /* working with activity here */
           while(testOnGoing)
              mon.wait();
           } 
        }
});

InstrumentationRegistry.getInstrumentation().waitForIdleSync();
}

@Override
public void onTestResult(boolean passed) {
synchronized (mon) {    
    //assertTrue(passed);
    Assert.fail();
    testOnGoing = false;
    mon.notify();
   } 
}

答案 1 :(得分:1)

感谢@Gordak。他的回答几乎奏效了。但是,不幸的是,它阻止了主线程,因此测试永远不会结束。我对它进行了一些修改,现在它可以正常工作。

@Before
public void setUp() throws Exception {
    activity = testRule.getActivity();
    latch = new CountDownLatch(1);
}

@Test
public void testSimpleSetup() {

    /* ... */

    InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
        @Override
        public void run() {
            testManager.startTest(MAX_WAIT_TIME); // this object calls onTestResult(boolean) after time t (t <= MAX_WAIT_TIME)

            /* working with activity here */
        }
    });
    InstrumentationRegistry.getInstrumentation().waitForIdleSync();

    latch.await(); // here we block test thread and not UI-thread
                   // presumably, you will want to set the timeout here
}

@Override
public void onTestResult(boolean passed) {
    // assertTrue(passed);
    Assert.fail();
    latch.countDown();
}