1. Обзор
В этом руководстве мы покажем, как запускать тесты JUnit непосредственно из кода Java — есть сценарии, в которых эта опция пригодится.
Если вы новичок в JUnit или хотите перейти на JUnit 5, вы можете ознакомиться с некоторыми из многочисленных руководств по этой теме, которые у нас есть.
2. Зависимости Maven
Нам понадобится пара основных зависимостей для запуска тестов JUnit 4 и JUnit 5:
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-launcher</artifactId>
<version>1.2.0</version>
</dependency>
</dependencies>
// for JUnit 4
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
Последние версии JUnit 4, JUnit 5 и JUnit Platform Launcher можно найти на Maven Central.
3. Запуск тестов JUnit 4
3.1. Сценарий тестирования
Как для JUnit 4, так и для JUnit 5 мы создадим несколько тестовых классов-заполнителей, которых будет достаточно для демонстрации наших примеров:
public class FirstUnitTest {
@Test
public void whenThis_thenThat() {
assertTrue(true);
}
@Test
public void whenSomething_thenSomething() {
assertTrue(true);
}
@Test
public void whenSomethingElse_thenSomethingElse() {
assertTrue(true);
}
}
public class SecondUnitTest {
@Test
public void whenSomething_thenSomething() {
assertTrue(true);
}
@Test
public void whensomethingElse_thenSomethingElse() {
assertTrue(true);
}
}
При использовании JUnit 4 мы создаем тестовые классы, добавляя аннотацию @Test
к каждому тестовому методу.
Мы также можем добавить другие полезные аннотации, такие как @Before
или @After
, но это не входит в задачи данного руководства.
3.2. Запуск одного тестового класса
Чтобы запустить тесты JUnit из кода Java, мы можем использовать класс JUnitCore
(с добавлением класса TextListener
, используемого для отображения вывода в System.out
):
JUnitCore junit = new JUnitCore();
junit.addListener(new TextListener(System.out));
junit.run(FirstUnitTest.class);
В консоли мы увидим очень простое сообщение об успешных тестах:
Running one test class:
..
Time: 0.019
OK (2 tests)
3.3. Запуск нескольких тестовых классов
Если мы хотим указать несколько тестовых классов с помощью JUnit 4, мы можем использовать тот же код, что и для одного класса, и просто добавить дополнительные классы:
JUnitCore junit = new JUnitCore();
junit.addListener(new TextListener(System.out));
Result result = junit.run(
FirstUnitTest.class,
SecondUnitTest.class);
resultReport(result);
Обратите внимание, что результат хранится в экземпляре класса JUnit Result
, который мы распечатываем с помощью простого служебного метода:
public static void resultReport(Result result) {
System.out.println("Finished. Result: Failures: " +
result.getFailureCount() + ". Ignored: " +
result.getIgnoreCount() + ". Tests run: " +
result.getRunCount() + ". Time: " +
result.getRunTime() + "ms.");
}
3.4. Запуск набора тестов
Если нам нужно сгруппировать некоторые тестовые классы для их запуска, мы можем создать TestSuite
. Это просто пустой класс, в котором мы указываем все классы с помощью аннотаций JUnit:
@RunWith(Suite.class)
@Suite.SuiteClasses({
FirstUnitTest.class,
SecondUnitTest.class
})
public class MyTestSuite {
}
Чтобы запустить эти тесты, мы снова будем использовать тот же код, что и раньше:
JUnitCore junit = new JUnitCore();
junit.addListener(new TextListener(System.out));
Result result = junit.run(MyTestSuite.class);
resultReport(result);
3.5. Выполнение повторных тестов
Одной из интересных особенностей JUnit является то, что мы можем повторять тесты, создавая экземпляры RepeatedTest
. Это может быть очень полезно, когда мы тестируем случайные значения или проверяем производительность.
В следующем примере мы запустим тесты из MergeListsTest
пять раз:
Test test = new JUnit4TestAdapter(FirstUnitTest.class);
RepeatedTest repeatedTest = new RepeatedTest(test, 5);
JUnitCore junit = new JUnitCore();
junit.addListener(new TextListener(System.out));
junit.run(repeatedTest);
Здесь мы используем JUnit4TestAdapter
в качестве оболочки для нашего тестового класса.
Мы даже можем создавать наборы программно, применяя повторное тестирование:
TestSuite mySuite = new ActiveTestSuite();
JUnitCore junit = new JUnitCore();
junit.addListener(new TextListener(System.out));
mySuite.addTest(new RepeatedTest(new JUnit4TestAdapter(FirstUnitTest.class), 5));
mySuite.addTest(new RepeatedTest(new JUnit4TestAdapter(SecondUnitTest.class), 3));
junit.run(mySuite);
4. Запуск тестов JUnit 5
4.1. Сценарий тестирования
В JUnit 5 мы будем использовать те же тестовые классы, что и в предыдущей демонстрации — FirstUnitTest
и SecondUnitTest
, с некоторыми незначительными отличиями из-за другой версии JUnit framework, например, пакет для @Test
и методы утверждения.
4.2. Запуск одного тестового класса
Чтобы запустить тесты JUnit 5 из кода Java, мы настроим экземпляр LauncherDiscoveryRequest
. Он использует класс построителя, в котором мы должны установить селекторы пакетов и фильтры имен тестовых классов, чтобы получить все тестовые классы, которые мы хотим запустить.
Затем этот запрос связывается со средством запуска, и перед выполнением тестов мы также настраиваем план тестирования и прослушиватель выполнения.
Оба они предложат информацию о тестах, которые будут выполнены, и о результатах:
public class RunJUnit5TestsFromJava {
SummaryGeneratingListener listener = new SummaryGeneratingListener();
public void runOne() {
LauncherDiscoveryRequest request = LauncherDiscoveryRequestBuilder.request()
.selectors(selectClass(FirstUnitTest.class))
.build();
Launcher launcher = LauncherFactory.create();
TestPlan testPlan = launcher.discover(request);
launcher.registerTestExecutionListeners(listener);
launcher.execute(request);
}
// main method...
}
4.3. Запуск нескольких тестовых классов
Мы можем установить селекторы и фильтры для запроса на запуск нескольких тестовых классов.
Давайте посмотрим, как мы можем установить селекторы пакетов и фильтры имен тестовых классов, чтобы получить все тестовые классы, которые мы хотим запустить:
public void runAll() {
LauncherDiscoveryRequest request = LauncherDiscoveryRequestBuilder.request()
.selectors(selectPackage("com.foreach.junit5.runfromjava"))
.filters(includeClassNamePatterns(".*Test"))
.build();
Launcher launcher = LauncherFactory.create();
TestPlan testPlan = launcher.discover(request);
launcher.registerTestExecutionListeners(listener);
launcher.execute(request);
}
4.4. Тестовый вывод
В методе main()
мы вызываем наш класс, а также используем прослушиватель для получения сведений о результате. На этот раз результат сохраняется как TestExecutionSummary
.
Самый простой способ извлечь его информацию — просто напечатать в поток вывода консоли:
public static void main(String[] args) {
RunJUnit5TestsFromJava runner = new RunJUnit5TestsFromJava();
runner.runAll();
TestExecutionSummary summary = runner.listener.getSummary();
summary.printTo(new PrintWriter(System.out));
}
Это даст нам детали нашего тестового прогона:
Test run finished after 177 ms
[ 7 containers found ]
[ 0 containers skipped ]
[ 7 containers started ]
[ 0 containers aborted ]
[ 7 containers successful ]
[ 0 containers failed ]
[ 10 tests found ]
[ 0 tests skipped ]
[ 10 tests started ]
[ 0 tests aborted ]
[ 10 tests successful ]
[ 0 tests failed ]
5. Вывод
В этой статье мы показали, как программно запускать тесты JUnit из кода Java, охватывая JUnit 4, а также недавнюю версию JUnit 5 этой среды тестирования.
Как всегда, реализация показанных здесь примеров доступна на GitHub как для примеров JUnit 5 , так и для JUnit 4 .