等待回调而不阻塞主线程
Wait for callback without blocking main thread
我被困住了,很乐意得到任何帮助!
我正在为 android 库编写测试。任务是在 activity 中执行一些操作并检查库是否正确响应。
我的问题是我的测试在 activity 中的所有操作完成后立即完成,但我通过回调获得测试结果(并且我仅在测试结束时收到此回调)。所以,我想以某种方式告诉测试框架,直到收到回调(或直到时间用完),测试才结束。这是我现在拥有的:
@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();
}
我预计此测试会失败,但实际上 onTestResult
是在 testSimpleSetup
完成后调用的,断言对测试结果没有影响。
提前致谢。
检查this post. I modified a bit the code, since I read the following:
As in the one argument version, interrupts and spurious wakeups are
possible, and this method should always be used in a loop:
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();
}
}
感谢@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();
}
我被困住了,很乐意得到任何帮助!
我正在为 android 库编写测试。任务是在 activity 中执行一些操作并检查库是否正确响应。 我的问题是我的测试在 activity 中的所有操作完成后立即完成,但我通过回调获得测试结果(并且我仅在测试结束时收到此回调)。所以,我想以某种方式告诉测试框架,直到收到回调(或直到时间用完),测试才结束。这是我现在拥有的:
@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();
}
我预计此测试会失败,但实际上 onTestResult
是在 testSimpleSetup
完成后调用的,断言对测试结果没有影响。
提前致谢。
检查this post. I modified a bit the code, since I read the following:
As in the one argument version, interrupts and spurious wakeups are possible, and this method should always be used in a loop:
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();
}
}
感谢@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();
}