it-roy-ru.com

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

Можно ли запустить тесты JUnit изнутри моего Java-приложения?

Могу ли я использовать тестовые среды (например, JUnit.jar?) Или я вынужден искать тестовые файлы, вызывать методы и самостоятельно отслеживать исключения?

Причина, по которой я спрашиваю, заключается в том, что моему приложению требуется много работы для запуска (много зависимостей, конфигураций и т.д.), А использование внешнего инструмента тестирования (например, задачи JUnit Ant) потребует много работы для настройки.

Проще запустить приложение, а затем внутри приложения запустить мои тесты.

Существует ли простая тестовая среда, которая запускает тесты и выводит результаты из приложения Java, или я вынужден написать свою собственную структуру?

48
corgrath

Да, ты можешь. Я делал это пару раз, чтобы проводить диагностические/дымовые тесты в производственных системах. Это фрагмент ключевой части кода, вызывающего JUnit:

JUnitCore junit = new JUnitCore();
Result result = junit.run(testClasses);

НЕ используйте JUnit.mainвнутри вашего приложения, оно вызывает System.exit после завершения тестов и, таким образом, может остановить процесс JVM.

Возможно, вы захотите захватить «обычный» вывод консоли JUnit (точки и простой отчет). Это можно легко сделать, зарегистрировав TextListener (этот класс предоставляет этот простой отчет).

Также обратите внимание на несколько осложнений, связанных с использованием этого метода:

  1. Тестирование любого «тестового фреймворка», в том числе такого маленького, хотя и довольно простое, может сбить с толку. Например, если вы хотите проверить, возвращает ли ваш «тестовый фреймворк» результат сбоя в случае сбоя одного из тестов, вы можете (должны?) Создать тестовый тест JUnit, который всегда не пройден, и выполнить этот тест с «тестовым фреймворком». В этом случае неудачный тестовый пример фактически является тестовыми данными и не должен выполняться как «обычный» JUnit. В качестве примера таких тестов вы можете обратиться к внутренним тестам JUnit.

  2. Если вы хотите подготовить/отобразить свой собственный отчет, вам лучше зарегистрировать свой собственный RunListener, поскольку результат, возвращаемый JUnit, не содержит (напрямую) информацию о пройденных тестах и ​​методе тестирования (он только «жестко закодирован» как часть теста Description) ).

81
kopper

Как описано в JUnit FAQ :

public static void main(String args[]) {
  org.junit.runner.JUnitCore.main("junitfaq.SimpleTest");
}
13
Tomislav Nakic-Alfirevic

Причиной, по которой я спрашиваю, является мой Приложение требует много работы для начать запуск (множество зависимостей и конфигураций и т. д.) и использовать инструмент внешнего тестирования (например, JUnit Ant task) потребовал бы много работы для настроить.

Вам необходимо удалить эти зависимости из кода, который вы тестируете. Зависимости и конфигурации - это именно то, чего вы пытаетесь избежать при написании тестовой среды. Для каждого теста вы должны ориентироваться на наименьшую тестируемую часть приложения.

Например, если вам требуется соединение с базой данных для выполнения какого-либо процесса в классе, который вы пытаетесь протестировать - отсоедините объект обработки базы данных от вашего класса, передайте его через метод конструктора или метода установки, а в своем тесте используйте инструмент, такой как JMock (или написать класс-заглушку) для создания поддельного объекта обработки базы данных. Таким образом вы убедитесь, что тесты не зависят от конкретной конфигурации базы данных, и вы тестируете только небольшую часть кода, которая вас интересует, а не весь уровень обработки базы данных.

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

10
seanhodges

В JUnit 5 вы можете использовать Launcher API для этих целей. 

    final LauncherDiscoveryRequest request = LauncherDiscoveryRequestBuilder.request()
            .selectors(
                    selectPackage("path_to_folder_with_tests")
            )
            .build();

    final Launcher launcher = LauncherFactory.create();

    final boolean pathContainsTests = launcher.discover(request).containsTests()
    if (!pathContainsTests) {
        System.out.println("This path is invalid or folder doesn't consist tests");
    }

    final SummaryGeneratingListener listener = new SummaryGeneratingListener();

    launcher.execute(request, listener);

    final TestExecutionSummary summary = listener.getSummary();

    final long containersFoundCount = summary.getContainersFoundCount();
    System.out.println("containers Found Count  " + containersFoundCount);

    final long containersSkippedCount = summary.getContainersSkippedCount();
    System.out.println("containers Skipped Count  " + containersSkippedCount);

    final long testsFoundCount = summary.getTestsFoundCount();
    System.out.println("tests Found Count  " + testsFoundCount);

    final long testsSkippedCount = summary.getTestsSkippedCount();
    System.out.println("tests Skipped Count  " + testsSkippedCount);
3
makson

Согласно API JUnit, JUnitCore имеет несколько методов для выполнения тестов внутри Java.

Спасибо Томиславу Накичу-Альфиревичу за указание на это.

http://junit.sourceforge.net/javadoc/org/junit/runner/JUnitCore.html

2
corgrath
1
Raffi Khatchadourian