2017-01-22 8 views
0

Я нашел следующий пример в JUnit документации:JUnit и InterruptedException

public static class HasGlobalLongTimeout { 

    @Rule 
    public Timeout globalTimeout= new Timeout(20); 

    @Test 
    public void run1() throws InterruptedException { 
     Thread.sleep(100); 
    } 

    @Test 
    public void infiniteLoop() { 
     while (true) {} 
    } 
} 

Я понимаю, что всякий раз, когда JUnit пытается прервать первый тест, он будет прерывать нить, в которой он работает на, и это будет бросаться InterruptedException, что приведет к завершению проверки.

Но как насчет второго теста (infinLoop)? Это ничего не бросает. Как это прекратится после таймаута?

ответ

1

Правило тайм-аута запускает каждый тест в отдельном потоке и ждет тайм-аута. После таймаута поток прерывается. Затем тестовый бегун продолжит переход к следующему тесту. Он не ждет ответа на прерывание, поэтому тест может продолжать работать в фоновом режиме.

infiniteLoop не будет выбрасывать InterruptedException, но продолжать работать, пока выполняются все оставшиеся тесты.

Как только все тесты закончатся, JVM, выполняющий тесты, как правило, завершается вместе со всеми потоками внутри него. Либо потому, что потоки отмечены как потоки демона, либо через вызов System.exit.

См исходный код:

  • FailOnTimeout.java - запуск потоков для каждого теста.
  • RemoteTestRunner.java - Испытуемый бегун Eclipse с явным System.exit в основном методе.
+0

Я понимаю из вашего комментария (и посмотрев исходный код), что junit попытается присоединиться к потоку с таймаутом и проверить, все ли он работает после таймаута. Если это так, тест завершится неудачно. I.e., даже если тест работает в фоновом режиме, он не удастся после неудачного вызова для соединения. – sapito

0

Он должен быть брошен в обоих тестах, аннотация @Rule прикрепляет таймер к каждому тесту. Если тест длится более 20 мс, генерируется исключение. Поэтому в вашей программе второй тест должен также запустить InterruptedException.

+0

Что делать, если бы у нас был второй тест в одиночку? Будет ли работать навсегда, даже если есть тайм-аут? – sapito

+0

Нет, он бы выбрал 'InterrupedException', поскольку он все равно имел бы тайм-аут. Аннотации позволяют коду локализовать исключение с этим тестом, но в этом случае другой тест вызовет другое исключение. –

+0

Куда это брошено? Мне кажется, что это сбивает с толку :) Кажется, второй тест не может вообще что-то бросить, это всего лишь простая петля. – sapito

0

Я пробовал следующий код и работает нормально (т. Е. Оба теста не работают из-за таймаута 20 мс) Я использую Java 8 и JUnit 4.12.

import java.util.concurrent.TimeUnit; 

import org.junit.Rule; 
import org.junit.Test; 
import org.junit.rules.Timeout; 

public class HasGlobalLongTimeout { 

    @Rule 
    public Timeout globalTimeout = new Timeout(20, TimeUnit.MILLISECONDS); 

    @Test 
    public void run1() throws InterruptedException { 
     Thread.sleep(100); 
    } 

    @Test 
    public void infiniteLoop() { 
     while (true) { 
     } 
    } 
} 

Обратите внимание, что я удалить модификатор static в объявлении класса (насколько я знаю, это не допускается для классов), и я изменил Timeout заявление (что один осуждается в настоящее время).

 Смежные вопросы

  • Нет связанных вопросов^_^