Запуск JUnit-тестов программно из Java-приложения

Выполнение тестов 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.