Тест JUnit с динамическим числом тестов



в нашем проекте у меня есть несколько JUnit тесты, которые, например, берут каждый файл из каталога и запускают тест на нем. Если я реализую testEveryFileInDirectory метод TestCase Это показывает, как только один тест, который может потерпеть неудачу или успех. Но меня интересуют результаты по каждому отдельному файлу. Как я могу написать TestCase/TestSuite таким образом, что каждый файл будет отображаться как отдельный тест, например, в графическом TestRunner затмения? (Кодирование явного метода тестирования для каждого файла не является выбор.)



сравните также вопрос ParameterizedTest с именем в Eclipse Testrunner.

754   7  

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 здесь) будет отображаться следующим образом:

Output in 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 динамически генерировать тесты.

https://github.com/kimble/junit-test-factory

Comments

    Ничего не найдено.