17

Вопрос по java – Остановка пакета JUnit в случае сбоя конкретного теста

У меня есть набор тестов JUnit в виде:

@RunWith(Suite.class)
@Suite.SuiteClasses( { xx.class, yy.cass })

public class AllTests {

public static Test suite() {
    TestSuite suite = new TestSuite(AllTests.class.getName());
    //$JUnit-BEGIN$

    //$JUnit-END$
    return suite;
}
}

Это тогда вызывает ванильные тесты как это:

public class xxx {

@Test
public void test () throws {
    ...

У меня возникла ситуация, когда я хотел бы остановить выполнение остальной части набора тестов, если в первом тесте произошла ошибка или произошел сбой. Но в других случаях ошибки / сбои в порядке, и набор должен выполнить как можно больше других тестов. По существу, первый неудачный тест показал бы, что остальные не безопасны.

Это возможно?

  • Error: User Rate Limit ExceededFailureListenerError: User Rate Limit ExceededExceptionError: User Rate Limit ExceededFirstTestClassError: User Rate Limit Exceededfailure.getException()Error: User Rate Limit Exceeded

    от
  • Error: User Rate Limit Exceeded

    от Jonathan
  • Error: User Rate Limit Exceeded

    от
  • Error: User Rate Limit Exceeded

    от Jonathan
  • Error: User Rate Limit Exceeded

    от Jonathan
  • Error: User Rate Limit Exceeded

    от
  • Error: User Rate Limit Exceeded

    от Jonathan
  • Error: User Rate Limit Exceeded

    от
7 ответов
  • 8

    Что не так с звонком

    System.exit()?

  • 4

    Если это

    first test затем рассмотрите возможность перемещения его проверки в @BeforeClass и выбросите исключение, если оно завершится неудачно. Тогда только метод @AfterClass будет запущен в случае этого исключения.

    Конечно, в этом случае вам не хватает всех артефактов прибора, созданных в методе (-ах) тестовой настройки.

  • 2

    Нравится ваш ответ, но с помощью

    @Before в интеграционном тесте я сделал что-то вроде этого:

    public class FooTest {
    
       private static boolean bar;
    
       @BeforeClass
       public static void setUpBeforeClass() throws Exception {
             bar = false;
       }
    
       @Before
       public void setUp() throws Exception {
             assertTrue(bar);
       }
    
       @Test
       public void test() {
             System.out.println("something");
             assertTrue(true);
       }
    
       @Test
       public void test1() {
             System.out.println("Something2");
             assertTrue(true);
       }
    }
    

    С уважением!

  • 0

    Вы проводите тесты с использованием муравья?

    Вы можете написать собственный тестовый слушатель. Вы можете установить это в муравьеhttp://ant.apache.org/manual/Tasks/junit.html (enableTestListenerEvents).

  • 11

    Для начала вам нужен junit RunListener:

    import org.junit.runner.notification.Failure;
    import org.junit.runner.notification.RunListener;
    import org.junit.runner.notification.RunNotifier;
    
    public class FailureListener extends RunListener {
    
        private RunNotifier runNotifier;
    
        public FailureListener(RunNotifier runNotifier) {
            super();
            this.runNotifier=runNotifier;
        }
    
        @Override
        public void testFailure(Failure failure) throws Exception {
            super.testFailure(failure);
            this.runNotifier.pleaseStop();
        }
    }
    

    Затем подготовьте набор:

    public class StopOnFailureSuite extends Suite {
    
        public StopOnFailureSuite(Class<?> klass, Class<?>[] suiteClasses) throws InitializationError {
            super(klass, suiteClasses);
        }
    
        public StopOnFailureSuite(Class<?> klass) throws InitializationError {
            super(klass, klass.getAnnotation(SuiteClasses.class).value());
        }
    
        @Override
        public void run(RunNotifier runNotifier) {
            runNotifier.addListener(new FailureListener(runNotifier));
            super.run(runNotifier);
        }
    }
    

    И запустить свой набор:

    @RunWith(StopOnFailureSuite.class)
    @Suite.SuiteClasses({
        FirstTestClass.class,
        SecondTestClass.class,
        ...
    })
    

  • 1

    Во-первых

    вы должны поймать ошибку и проверить ее, прежде чем запускать второй тест.

    @Rule
    public ErrorCollector collector = new ErrorCollector();
    

    1. Add Error.

    collector.addError(new Throwable("first thing went wrong"));
    

    2. Check before the dependent run.

    collector.checkThat(getResult(), not(containsString("ERROR!")));
    

    Ссылка -ErrorCollector

  • 3

    Основываясь на ответе Hiro2k (спасибо!)

    Я использовал следующее решение. Это что-то вроде взлома, но это работает.

    Тест, который может помешать запуску других тестов, находится вверху списка @ Suite.SuiteClasses. Этот тест тогда имеет следующее:

    private static boolean shouldStopRestOfSuite = false;
    
        @Test
        public void test () throws Throwable {
        try {
                ... run some test code...
        }
        catch (Throwable e) {
            shouldStopRestOfSuite = true;
            throw e;
        }
    }
    

    Обратите внимание, что выше необходимо перехватить Throwable (не исключение), чтобы он улавливал ошибки утверждений. Он также повторно выдает ошибку, так что она регистрируется JUnit для анализа.

    Тогда есть другой метод испытаний:

    @Test
    public void testKillIfNeeded () throws Exception {
        if (!shouldStopRestOfSuite) {
            return;
        }
    
        System.out.println ("Test suite killed due to dangerous error / failure");
        System.exit(1);
    }
    

    Вышеуказанное выполняется вторым и завершит процесс JUnit.

    При использовании этого метода тест JUnit не завершается при сбое / ошибке, если существует проблема, но сбой / ошибка регистрируется для анализа JUnit, и дальнейшие тесты не запускаются.

    Не слишком красиво, но это делает работу :)