JUnit: timeout некорректно работает?

278
15 января 2017, 15:45

Есть следующий тест:

@Test(timeout = 15)
public void test() throws Exception {
    AesCrypt aes = new AesCrypt("password");
    String crypted = aes.encrypt("Test string");
    Assert.assertEquals("Test string", aes.decrypt(crypted));
}

По идее, он должен проваливаться, если время выполнения превысит 15ms. В тоже время, как видно на скриншоте, тест выполнялся 23ms, но всё равно считается пройденным.

Из-за чего так?

Answer 1

Использование @Test(timeout = 15) не является потокобезопасным, использование может привести к неправильным результатом. Используйте следующий код.

public class Test {
    @Rule
    public Timeout globalTimeout= new Timeout(9);
    @org.junit.Test()
    public void test() throws InterruptedException {
        Thread.sleep(8);
    }
    @org.junit.Test()
    public void test2() throws InterruptedException {
        Thread.sleep(10);
    }
}

вывод

org.junit.runners.model.TestTimedOutException: test timed out after 9 milliseconds
at java.lang.Thread.sleep(Native Method)
at Test.test2(Test.java:22)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.FailOnTimeout$CallableStatement.call(FailOnTimeout.java:298)
at org.junit.internal.runners.statements.FailOnTimeout$CallableStatement.call(FailOnTimeout.java:292)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.lang.Thread.run(Thread.java:745)

Такой подход позволяет отловить даже 1 миллисекунду.

Также в jUnit5 можно использовать

    assertTimeoutPreemptively(ofSeconds(15), () -> {
        // This method takes 20 seconds to run
        myMethod();
    } , () -> "myMethod() method took more than 15 seconds and was aborted.");
Answer 2

Запустите тест вне IDE и перед запуском теста выполните очистку (clean).

READ ALSO
Что такое External library?

Что такое External library?

external libraries intellij - это список подключенных по умолчанию библиотек? что то вроде include cstdlib?

310
DrawerLayout с fragment с разными toolbar

DrawerLayout с fragment с разными toolbar

Мне нужно реализовать такую структуруВыдвижная панель, кликая по варианту из списка в главную активности заместо FrameLayout загружается фрагмент

409
Получить массив из отдельного класса

Получить массив из отдельного класса

Нужно передать массив List из отдельного класса на IntentService, который позволяет в фоновом режиме проверять на наличие новых фотографий в сервере

292