2

我很少有课程可以测试我的应用程序。如果持续时间超过 4 秒,我想测试失败。我的代码破坏了测试,但在某些情况下它不会执行下一个测试类。

当我写的时候(和超时无关,只是fail()的一个例子):

public void testSmth() {
    fail("msg");
}

失败跟踪是空的,它会中断测试并开始另一个。但是当我想让它像超时一样时:

public void testSmth() {
    Timer timer = new Timer();
    timer.schedule(new TimerTask() {
        @Override
        public void run() {
            fail("msg");
        }
    }, 4000);

    // some tests (that even lasts more than 4 secons) like clickOnImage() etc.
}

它破坏了测试,但它不执行下一个测试,并且在失败跟踪中有:

测试未能完成。原因:“仪器运行因“junit.framework.AssertionFailedError”而失败。检查设备 logcat 以获取详细信息

在 LogCat 中我得到了:

07-26 11:46:07.428:E/AndroidRuntime(6195):致命异常:Timer-1

07-26 11:46:07.428: E/AndroidRuntime(6195): junit.framework.AssertionFailedError: msg

07-26 11:46:07.428: E/AndroidRuntime(6195): at junit.framework.Assert.fail(Assert.java:47)

07-26 11:46:07.428: E/AndroidRuntime(6195): 在 java.util.Timer$TimerImpl.run(Timer.java:284)

或者也许还有其他方法可以做我想做的事?

谢谢。

4

2 回答 2

1

您必须使用以下内容覆盖 runTest() 方法:

[编辑] 此代码创建一个新线程并在其上运行实际测试。Future 类允许我们在这个线程的执行上设置一个超时,当达到超时时,它就会停止。它还负责捕获异常。(我是否提到其余的测试仍将运行?)

如果您想使用此超时来确保测试不会在被测代码中的某处保持“挂起”,这将非常有用。

public class MyTestClass extends
                ActivityInstrumentationTestCase2<EditorActivity> {

@Override
public void runTest() throws Throwable {
    final Throwable[] exceptions = new Throwable[1];

    ExecutorService executor = Executors.newCachedThreadPool();
    Callable<Object> task = new Callable<Object>() {
        public Object call() throws Exception {

            try {
                doRunTest();
            }
            catch (Throwable t) {
                exceptions[0] = t;
            }

            return Boolean.TRUE;
        }
    };

    int timeOutMinutes = 10;
    String testCaseName = String.format("%s.%s", getClass().getName(), getName());

    Future<Object> future = executor.submit(task);
    try {
        future.get(timeOutMinutes, TimeUnit.MINUTES);
    } catch (TimeoutException ex) {
        Assertions.fail("[Test method timed out after " + timeOutMinutes + " minutes.]\n" + testCaseName);
    } catch (Throwable e) {
        throw e;
    } finally {
        future.cancel(true); // may or may not desire this
    }

    if (exceptions[0] != null) {
        throw exceptions[0];
    }
}


private void doRunTest() throws Throwable {
    super.runTest();
}

}
于 2013-11-21T08:06:30.730 回答
1

如果您只想在达到超时的情况下使测试失败,这应该足够了:

public void test1() throws Exception {
    long start = System.currentTimeMillis();
    solo.sleep(5000);
    if (System.currentTimeMillis() - start > 4000) {
        fail("msg");
    }
}

public void test2() throws Exception {
    long start = System.currentTimeMillis();
    solo.sleep(3000);
    if (System.currentTimeMillis() - start > 4000) {
        fail("msg");
    }
}

在执行过程中很难破坏测试,您也可以在每个命令后检查超时,但是检查它需要时间并且您的测试方法会持续更长时间。

于 2013-11-21T20:02:48.137 回答