Очистка после всех тестов junit

В моем проекте мне нужно настроить репозиторий перед всеми тестами. Это делается с помощью некоторых хитрых статических правил. Однако я понятия не имею, как сделать очистку после всех тестов. Я не хочу хранить какое-то волшебное статическое число, относящееся к количеству всех методов тестирования, которое я должен поддерживать все время.

Наиболее ценный способ — добавить слушателя, который будет вызываться после всех тестов. Есть ли для него какой-либо интерфейс уже в JUnit4?


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


person Mateusz Chromiński    schedule 28.03.2012    source источник
comment
Чистое решение TestNG можно найти здесь: stackoverflow.com/a/26381858/1857897.   -  person dedek    schedule 15.07.2015


Ответы (5)


Я использую JUnit 4.9. Поможет ли это?:

import junit.framework.TestCase;

import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;

@RunWith(Suite.class)
@SuiteClasses({First.class,Second.class,Third.class})
public class RunTestSuite extends TestCase {
    @BeforeClass
    public static void doYourOneTimeSetup() {
        ...
    }

    @AfterClass
    public static void doYourOneTimeTeardown() {
        ...
    }    
}

Редактировать: я совершенно уверен (если я неправильно понимаю ваш вопрос), что мое решение - это то, что вы ищете. то есть один метод демонтажа после того, как все ваши тесты были запущены. Слушатель не требуется, у JUnit есть такая возможность. Спасибо.

person HellishHeat    schedule 28.03.2012
comment
Я почти уверен, что это достигнет вашей цели, если я неправильно понимаю ваш вопрос. - person HellishHeat; 28.03.2012
comment
Пришлось бы перечислять все тестовые классы (которых и сейчас несколько, и счет будет быстро расти), так что, к сожалению, это неприемлемо - person Mateusz Chromiński; 29.03.2012
comment
Извини, чувак, я просто не знаю, что ты пытаешься сделать. Не понимаю, зачем вам что-то перечислять. Я предлагаю вам более подробно изложить свой вопрос, потому что в его нынешнем виде он выглядит так, как будто вы хотите, чтобы какое-то статическое поведение выполнялось в конце вашего тестового прогона, после того, как все ваши тесты были запущены. Это все, что вы указали. Если это так, то мое решение делает это. Обратите внимание, что я НЕ запускаю AfterClass после каждого из ваших тестов. Я использую аннотацию AfterClass для AllTests. ТАК он будет вызываться после всех тестов. Может я просто не понимаю :) - person HellishHeat; 30.03.2012
comment
Я не привык использовать наборы и TestCase, так что это, вероятно, мое недоразумение ;). Но если это то, что вы говорите, то как насчет этой строки: @SuiteClasses({First.class,Second.class,Third.class})? Разве это не перечисление всех классов, тесты которых должны быть завершены, чтобы вызвать желаемый метод очистки? - person Mateusz Chromiński; 30.03.2012
comment
Думайте о Test Suite как о доме для всех ваших тестов. Таким образом, внутри First.java у вас может быть много тестов (@Test), или, действительно, First.java может быть самим TestSuite. Выше RunTestSuite назван неудачно, традиционное название для него — «AllTests». В любом случае, да, вы правы, говоря, что все тесты, найденные в First....Third, будут завершены до того, как будет выполнен doYourOneTimeTeardown(). Это то, что вы хотели подумать, верно? - person HellishHeat; 31.03.2012
comment
Да, поведение этого класса на самом деле то, что я искал, однако это перечисление тестовых классов в аннотации @SuiteClasses отбрасывает это решение. Мне трудно поддерживать, если будет несколько тестовых классов. Боюсь, в этой теме особо нечего делать, так что спасибо за помощь. - person Mateusz Chromiński; 31.03.2012
comment
Можно ли в этом случае запустить только один TestCase? Или мне всегда нужно запускать весь TestSuite? Можно ли легко интегрировать это решение с инструментом сборки (например, Maven surefire) без дополнительной настройки? - person dedek; 16.10.2014
comment
Если вы не хотите перечислять свои тесты, вы можете сделать точно такое же решение, предложенное здесь, с помощью ClasspathSuite (github.com/takari/takari-cpsuite), который использует сканирование путей к классам для поиска тестов. - person NamshubWriter; 27.03.2015
comment
для той же функциональности без необходимости перечисления тестов см. ответ @serup ниже: stackoverflow.com/a/38264405/1663987 - person simpleuser; 06.03.2017
comment
Если вы используете этот метод, удаление/очистка не произойдет, если тесты будут преждевременно уничтожены с помощью [Ctrl] + [C]. См. @Alexander answer для лучшего решения, которое всегда выполняет очистку. - person stiemannkj1; 15.10.2018

Я рекомендую использовать org.junit.runner.notification.RunListener, пример:

public class TestListener extends RunListener {
  @Override
  public void testRunStarted(Description description) throws Exception {
     // Called before any tests have been run.
  }
  @Override
  public void testRunFinished(Result result) throws Exception {
     // Called when all tests have finished
  }
}

Подробнее читайте непосредственно в документе JUnit java. Вы можете использовать это даже с плагином Maven surefire (модульные тесты) или отказоустойчивым плагином (интеграционные тесты), добавив следующий код в конфигурацию плагина:

<properties>
  <property>
    <name>listener</name>
    <value>com.innovatrics.afismq.it.TestListener</value>
  </property>
</properties>
person Juraj Michalak    schedule 08.02.2013
comment
Мне это решение нравится намного больше. Вам не нужно называть все классы - person committedandroider; 23.05.2017
comment
Если вы используете этот метод, удаление/очистка не произойдет, если тесты будут преждевременно уничтожены с помощью [Ctrl] + [C]. См. @Alexander answer для лучшего решения, которое всегда выполняет очистку. - person stiemannkj1; 15.10.2018
comment
@ stiemannkj1 А что, если вы преждевременно остановите тесты, уничтожив сам процесс Java? Ни одно решение не может быть полностью гарантировано. - person Ryan Lundy; 24.12.2018
comment
@RyanLundy, конечно, ничего не гарантировано. kill -9 остановит процесс java без запуска хука выключения. Но хук выключения по-прежнему предпочтительнее testRunFinished(), когда есть вероятность, что JVM exit() выполнит все тесты. Это очистит во многих других случаях. Возможно, «всегда выполняет уборку» — не лучший выбор слов. В этом блоге содержится дополнительная информация о том, когда запустится ловушка отключения: geeksforgeeks.org/jvm- выключение-хука-java - person stiemannkj1; 25.12.2018

Только что столкнулся с такой же проблемой.
Мое решение:

  • Для глобальной настройки: используйте (ленивый) синглтон для доступа к чему-то глобальному, что требует создания экземпляра перед тестами. Первый тест, обращающийся к этому синглтону, запустит процесс глобальной настройки.
  • Для глобального разрыва: используйте хук завершения работы Java:
    Runtime.getRuntime().addShutdownHook(new Thread(() -> do_your_global_cleanup())));
person Alexander    schedule 23.03.2018
comment
Этот метод намного лучше, чем любой из приведенных выше ответов, поскольку он по-прежнему будет выполнять демонтаж / очистку, когда тесты преждевременно уничтожаются с помощью [Ctrl] + [C]. Подробнее читайте в мой блог. . - person stiemannkj1; 15.10.2018

Вы всегда можете написать свой собственный TestRunner. Однако, прежде чем сделать это, необходимо оценить потребность в том же самом. Лучше использовать @BeforeClass и @AfterClass. Еще один пример, на который я могу указать, это способ, которым спящий режим позволяет пользователям выполнять модульное тестирование с использованием «import.sql».

person questzen    schedule 28.03.2012

Не нужно использовать набор, просто добавьте @BeforeClass и @AfterClass как статические

public class Tests {

    @BeforeClass
    public static void doYourOneTimeSetup()
    {
        ...
    }

    @AfterClass
    public static void doYourOneTimeTeardown() {
        ...
    }    

    @Test
    public void testYourTestcase()
    {
        ...
    }
}
person serup    schedule 08.07.2016
comment
Это не работает, если у вас более одного тестового класса. - person Daniel Kaplan; 21.06.2017
comment
@DanielKaplan У меня не было с этим проблем - не могли бы вы привести пример, когда это не сработает? - person serup; 10.11.2020