Выполнение тестов JUnit программно из приложения Java
1. обзор
В этом уроке мы покажемhow to run JUnit tests directly from Java code - есть сценарии, в которых этот параметр может пригодиться.
Если вы новичок в JUnit или хотите перейти на JUnit 5, вы можете проверить некоторые изmany tutorials, которые у нас есть по этой теме.
2. Maven Зависимости
Нам понадобится пара основных зависимостей для запуска тестов JUnit 4 и JUnit 5:
org.junit.jupiter
junit-jupiter-engine
5.2.0
test
org.junit.platform
junit-platform-launcher
1.2.0
// for JUnit 4
junit
junit
4.12
test
Последние версии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. Запуск нескольких тестовых классов
Если мы хотимto specify multiple test classes с JUnit 4, мы можем использовать тот же код, что и для одного класса, и просто добавить дополнительные классы:
JUnitCore junit = new JUnitCore();
junit.addListener(new TextListener(System.out));
Result result = junit.run(
FirstUnitTest.class,
SecondUnitTest.class);
resultReport(result);
Обратите внимание, что результат сохраняется в экземпляре класса JUnitResult, который мы распечатываем с помощью простого служебного метода:
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 заключается в том, что мы можемrepeat tests by creating instances of 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, например, пакет для@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.example.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 examples, так и дляJUnit 4.