Как запустить набор кода до и после любых тестов в любом классе?

Здесь мой тестовый код:

public class Test1 {
 @BeforeClass
 public void setUp() {
 EmbeddedTomcat.start();
 }
 // test methods...
 @AfterClass
 public void tearDown() {
 EmbeddedTomcat.stop();
 } 
}
public class Test2 {
 @BeforeClass
 public void setUp() {
 EmbeddedTomcat.start();
 }
 // test methods...
 @AfterClass
 public void tearDown() {
 EmbeddedTomcat.stop();
 }
}
// ...

Как вы можете видеть, я дублирую старт и останавливаю вызовы на встроенный tomcat в каждом классе Test. Как избежать этого дублирования с помощью JUnit?

Требование:  - Запускать и останавливать вызовы должны быть вызваны ONCE для всех тестовых классов

JUnit 4.11

2 ответа

В дополнение к созданию родительского класса, который запускает @BeforeClass и @AfterClass. вы можете создать JUnit Rule. Вы можете сделать свой подкласс правил ExternalResource, у которого есть методы переопределения для добавления поведения до и после выполнения (класс или тесты).

public class EmbeddedTomcatServer extends ExternalResource {
 ...
 @Override
 protected void before() throws Throwable {
 EmbeddedTomcat.start();
 };
 @Override
 protected void after() {
 EmbeddedTomcat.stop();
 };
 }

Затем в вашем тесте используйте @ClassRule, который запускает методы before() и after() сервера во время BeforeClass и AfterClass.

public class Test1 {
 @ClassRule
 public static EmbeddedTomcatServer tomcat = new EmbeddedTomcatServer();
 //tests as normal, no more @BeforeClass or @AfterClass
}
public class Test2 {
 @ClassRule
 public static EmbeddedTomcatServer tomcat = new EmbeddedTomcatServer();
 //tests as normal, no more @BeforeClass or @AfterClass
}

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

ИЗМЕНИТЬ только запуск start() и stop() один раз

Немного неясно, имеете ли вы в виду запуск запуска и остановку один раз на тестовый класс (в качестве исходного кода с использованием @BeforeClass и @AfterClass)

Или, если вы хотите запустить запуск и остановить только один раз через ВСЕ тесты во всех запущенных тестовых классах.

Если вы хотите сделать последнее, здесь также полезны @ClassRules. Просто создайте тестовый набор с использованием тестовых классов, а затем включите ClassRule ТОЛЬКО В ЛЮБОМ КЛАССе

@RunWith(Suite.class)
@SuiteClasses({ Test1.class, Test2.class })
public class AllTests {
 @ClassRule
 public static EmbeddedTomcatServer tomcat = new EmbeddedTomcatServer();
}

Это запустит tomcat, когда будет запущен пакет AllTests, а затем остановите tomcat, когда все тесты в тестовом наборе будут запущены.


Если это возможно для вашего проекта, вы можете создать класс TestParent, который определит эти методы @BeforeClass и @AfterClass и сделает ваши классы Test1 и Test2 продолженными.

public class TestParent {
 @BeforeClass
 public void setUp() {
 EmbeddedTomcat.start();
 }
 @AfterClass
 public void tearDown() {
 EmbeddedTomcat.stop();
 } 
}
public class Test1 extends TestParent {
 //...
}
public class Test2 extends TestParent {
 //...
}

licensed under cc by-sa 3.0 with attribution.