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

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

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


person Hans-Peter Störr    schedule 11.12.2008    source источник
comment
См. Также stackoverflow.com/questions/3257080/   -  person Vadzim    schedule 23.07.2016


Ответы (7)


Взгляните на параметризованные тесты в JUnit 4.

На самом деле я сделал это несколько дней назад. Попробую объяснить ...

Сначала создайте свой тестовый класс обычным образом, поскольку вы просто тестируете с одним входным файлом. Украсьте свой класс:

@RunWith(Parameterized.class)

Создайте один конструктор, который принимает входные данные, которые будут изменяться при каждом тестовом вызове (в этом случае это может быть сам файл)

Затем создайте статический метод, который вернет 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;
    }
}

Также проверьте этот s_parameterized_tests" rel="noreferrer">пример

person bruno conde    schedule 11.12.2008
comment
Спасибо! Метод JUnit 4 лучше, чем метод JUnit 3, указанный в другом ответе, поскольку JUnit 3 сбивает с толку средство запуска тестов eclipse, а с помощью метода JUnit 4 вы можете повторно выполнить тесты и т. Д. Мне только интересно, как я могу показать затмение название теста - показывает только [0], [1] и т. д. - person Hans-Peter Störr; 12.12.2008
comment
@hstoerr, Похоже, это будет в следующем выпуске JUnit :-) - person rescdsk; 13.04.2012
comment
Как бы вы это изменили, если бы вы хотели, чтобы каждый запуск [с другой комбинацией данных] изменял имя этого тестового прогона? [Т.е. Файл Path1 будет протестирован как: test1Path1, test2Path? - person monksy; 02.09.2012

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());
    }

}
person McDowell    schedule 11.12.2008

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

«Вывод

person avandeursen    schedule 27.03.2017

Должно быть возможно в JUnit 3 путем наследования от TestSuite и переопределения метода tests() для перечисления файлов и для каждого возврата экземпляра подкласса TestCase, который принимает имя файла в качестве параметра конструктора и имеет метод тестирования, который проверяет файл, указанный в конструкторе .

В JUnit 4 это могло быть еще проще.

person Michael Borgwardt    schedule 11.12.2008

Вы можете рассмотреть возможность использования библиотеки 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 Parametrised runner:

  • более явный - параметры находятся в параметрах метода тестирования, а не в полях класса
  • меньше кода - вам не нужен конструктор для настройки параметров
  • вы можете смешивать параметризованные и непараметризованные методы в одном классе
  • params можно передать как строку CSV или из класса поставщика параметров
  • класс поставщика параметров может иметь столько параметров, предоставляющих методы, сколько вы хотите, чтобы вы могли группировать разные случаи
  • у вас может быть тестовый метод, который предоставляет параметры (больше никаких внешних классов или статики)
  • вы можете видеть фактические значения параметров в своей среде IDE (в JUnit Parametrised это только последовательные числа параметров)
person falsarella    schedule 20.05.2015

Если TestNG является вариантом, вы можете использовать параметры с DataProviders.

Результат каждого теста отдельного файла будет отображаться в текстовом отчете или пользовательском интерфейсе плагина Eclipse TestNG. При общем количестве выполненных тестов будет учитываться каждый из ваших файлов индивидуально.

Это поведение отличается от теорий JUnit, в которых все результаты объединены в одну "теорию". "и засчитываются только как 1 тест. Если вам нужен отдельный отчет о результатах в JUnit, вы можете попробовать параметризованные тесты.

Тест и входы

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
===============================================
person Ben Hutchison    schedule 17.07.2014
comment
Я не знаю о теориях, но параметризованные тесты в JUnit показаны отдельно в eclipse, а не вместе. - person Hans-Peter Störr; 18.07.2014

У меня была аналогичная проблема, и в итоге я написал простой бегун JUnit 4, который позволяет med динамически генерировать тесты.

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

person Kimble    schedule 08.04.2016