Тест JUnit с динамическим числом тестов
в нашем проекте у меня есть несколько JUnit тесты, которые, например, берут каждый файл из каталога и запускают тест на нем. Если я реализую testEveryFileInDirectory метод TestCase Это показывает, как только один тест, который может потерпеть неудачу или успех. Но меня интересуют результаты по каждому отдельному файлу. Как я могу написать TestCase/TestSuite таким образом, что каждый файл будет отображаться как отдельный тест, например, в графическом TestRunner затмения? (Кодирование явного метода тестирования для каждого файла не является выбор.)
сравните также вопрос ParameterizedTest с именем в Eclipse Testrunner.
7 ответов:
посмотри Параметризованные Тесты в JUnit 4.
на самом деле я сделал это несколько дней назад. Я постараюсь объяснить ...
сначала создайте свой тестовый класс нормально, так как вы просто тестируете с одним входным файлом. Украсьте свой класс с:
@RunWith(Parameterized.class)построить один конструктор, который принимает входные данные, которые будут меняться в каждом тестовый звонок (в этом случае это может быть сам файл)
затем создайте статический метод, который вернет a
Collectionиз массивов. Каждый массив в коллекции будет содержать аргументов для конструктора класса, например, файл. Украсьте этот метод с:@Parametersвот пример класса.
@RunWith(Parameterized.class) public class ParameterizedTest { private File file; public ParameterizedTest(File file) { this.file = file; } @Test public void test1() throws Exception { } @Test public void test2() throws Exception { } @Parameters public static Collection<Object[]> data() { // load the files as you want Object[] fileArg1 = new Object[] { new File("path1") }; Object[] fileArg2 = new Object[] { new File("path2") }; Collection<Object[]> data = new ArrayList<Object[]>(); data.add(fileArg1); data.add(fileArg2); return data; } }также проверить это пример
JUnit 3
public class XTest extends TestCase { public File file; public XTest(File file) { super(file.toString()); this.file = file; } public void testX() { fail("Failed: " + file); } } public class XTestSuite extends TestSuite { public static Test suite() { TestSuite suite = new TestSuite("XTestSuite"); File[] files = new File(".").listFiles(); for (File file : files) { suite.addTest(new XTest(file)); } return suite; } }JUnit 4
import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.junit.runners.Parameterized.Parameters; @RunWith(Parameterized.class) public class TestY { @Parameters public static Collection<Object[]> getFiles() { Collection<Object[]> params = new ArrayList<Object[]>(); for (File f : new File(".").listFiles()) { Object[] arr = new Object[] { f }; params.add(arr); } return params; } private File file; public TestY(File file) { this.file = file; } @Test public void testY() { fail(file.toString()); } }
Junit 5 Параметризованные Тесты
JUnit 5 параметризованные тесты поддерживают это, позволяя использовать метод как источник данных:
@ParameterizedTest @MethodSource("fileProvider") void testFile(File f) { // Your test comes here } static Stream<File> fileProvider() { return Arrays.asList(new File(".").list()).stream(); }JUnit 5 DynamicTests
JUnit 5 также поддерживает это через понятие
DynamicTest, который должен быть создан в@TestFactory, С помощью статического методаdynamicTest.import org.junit.jupiter.api.DynamicTest; import org.junit.jupiter.api.TestFactory; import static org.junit.jupiter.api.DynamicTest.dynamicTest; import java.util.stream.Stream; @TestFactory public Stream<DynamicTest> testFiles() { return Arrays.asList(new File(".").list()) .stream() .map((file) -> dynamicTest( "Test for file: " + file, () -> { /* Your test comes here */ })); }тесты выполняются в вашей среде IDE (IntelliJ здесь) будет отображаться следующим образом:
должно быть возможно в JUnit 3 путем наследования от
TestSuiteи переопределитьtests()метод для перечисления файлов и для каждого возвращаемого экземпляра подклассаTestCase, который принимает имя файла в качестве параметра конструктора и метода тестов, который проверяет файл при в конструкторе.В JUnit 4 это может быть еще проще.
вы могли бы рассмотреть, используя библиотека JUnitParams, так что у вас будет еще несколько (более чистых) вариантов:
@org.junit.runner.RunWith(junitparams.JUnitParamsRunner.class) public class ParameterizedTest { @org.junit.Test @junitparams.Parameters(method = "data") public void test1(File file) throws Exception { } @org.junit.Test @junitparams.Parameters(method = "data") public void test2(File file) throws Exception { } public static File[] data() { return new File[] { new File("path1"), new File("path2") }; } }
@org.junit.runner.RunWith(junitparams.JUnitParamsRunner.class) public class ParameterizedTest { @org.junit.Test @junitparams.Parameters(value = { "path1", "path2" }) public void test1(String path) throws Exception { File file = new File(path); } @org.junit.Test @junitparams.Parameters(value = { "path1", "path2" }) public void test2(String path) throws Exception { File file = new File(path); } }
Вы можете видеть больше примеры использования здесь.
кроме того о JUnitParams, почему писать параметризованные тесты с ним проще и читабельнее:
проект JUnitParams добавляет новый раннер в JUnit и предоставляет многое более легкий и читаемый параметризованный тесты для JUnit >=4.6.
основные отличия от стандартного JUnit параметризованного бегуна:
- более явные-параметры находятся в параметрах метода тестирования, а не в полях класса
- меньше кода - вам не нужен конструктор для настройки параметров
- вы можете смешивать параметризованные и непараметризованные методы в одном классе
- параметры могут быть переданы в виде строки CSV или из класса поставщика параметров
- параметры класс provider может иметь столько параметров, предоставляющих методы, сколько вы хотите, чтобы вы могли группировать разные случаи
- вы можете иметь метод тестирования, который предоставляет параметры (никаких внешних классов или статики больше)
- вы можете видеть фактические значения параметров в вашей IDE (в Параметризованном JUnit это только последовательные числа параметров)
Если TestNG является опцией, вы можете использовать параметры с DataProviders.
тест каждого отдельного файла будет иметь свой результат, показанный в текстовом отчете или Eclipse TestNG plugin UI. Количество выполненных тестов будет подсчитываться для каждого из ваших файлов в отдельности.
это поведение отличается от JUnit теории, в котором все результаты объединяются под одной записью "теория" и учитываются только как 1 Тест. Если вы хотите отдельный отчет о результатах Джунит, ты можешь попробовать Параметризованные Тесты.
тестирование и входы
выходpublic class FileTest { @DataProvider(name="files") public File[][] getFiles(){ return new File[][] { { new File("file1") }, { new File("file2") } }; // or scan a directory } @Test(dataProvider="files") public void testFile(File file){ //run tests on file } }PASSED: testFile(file1) PASSED: testFile(file2) =============================================== Default test Tests run: 2, Failures: 0, Skips: 0 ===============================================
У меня была аналогичная проблема, и в итоге я написал простой JUnit 4 runner, который позволяет med динамически генерировать тесты.

Comments