Test JUnit z dynamiczną liczbą testów
W naszym projekcie mam kilka testów JUnit , które np. pobierają każdy plik z katalogu i uruchamiają na nim test. Jeśli zaimplementuję metodę testEveryFileInDirectory
w TestCase
to pokazuje się jako tylko jeden test, który może się nie powieść lub odnieść sukces. Ale jestem zainteresowany wynikami KAŻDEGO pliku. Jak mogę napisać TestCase
/ TestSuite
taki, że każdy plik pojawia się jako osobny test np. w graficznym teście Eclipse? (Kodowanie jawnej metody testowania dla każdego pliku nie jest opcją.)
Porównaj również pytanie Parametryzowało test z nazwą w Eclipse Testrunner .
7 answers
Spójrz na sparametryzowane testy W JUnit 4.
Właściwie to zrobiłem to kilka dni temu. Postaram się wyjaśnić ...Najpierw Zbuduj swoją klasę testową normalnie, jak w przypadku testów z jednym plikiem wejściowym. Udekoruj swoją klasę:
@RunWith(Parameterized.class)
Zbuduj jeden konstruktor, który pobiera dane wejściowe, które zmienią się w każdym wywołaniu testowym (w tym przypadku może to być sam plik)
Następnie zbuduj statyczną metodę, która zwróci Collection
tablic. Każda tablica w zbiorze będzie zawierać argumenty wejściowe dla konstruktora klasy, np. plik. Udekoruj tą metodą:
@Parameters
Oto przykładowe zajęcia.
@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;
}
}
Sprawdź również ten przykład
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-09-14 09:24:22
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());
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-12-11 11:04:15
Junit 5 Testy Parametryzowane
JUnit 5 sparametryzowane testy wspierają to, umożliwiając użycie metody jako źródła danych :
@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 wspiera to również poprzez pojęcie DynamicTest
, które ma być generowane w @TestFactory
, za pomocÄ… metody statycznej 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 */ }));
}
Testy uruchamiane w Twoim IDE (IntelliJ tutaj) będą wyświetlane w następujący sposób:
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-08 17:26:10
Powinno być możliwe w JUnit 3 poprzez dziedziczenie z TestSuite
i nadpisywanie metody tests()
do listy plików i dla każdego zwracania instancji podklasy TestCase
, która przyjmuje nazwę pliku jako parametr konstruktora i ma metodę testową, która testuje plik podany w konstruktorze.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-12-11 10:16:57
Możesz rozważyć użycie JUnitParams library , więc będziesz miał jeszcze kilka (czystszych) opcji:
@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);
}
}
Możesz zobaczyć więcej próbek użycia tutaj .
Dodatkowo o JUnitParams, dlaczego pisanie parametryzowanych testów z nim jest łatwiejsze i czytelniejsze:
Projekt JUnitParams dodaje nowego biegacza do JUnit i zapewnia wiele Å‚atwiejsze i czytelne parametryzowane testy dla JUnit > = 4.6.
Główne różnice w stosunku do standard JUnit Parametryzowany biegacz:
- bardziej jednoznaczne-params sÄ… w metodzie testowej params, Nie pola klasy
- mniej kodu - nie potrzebujesz konstruktora, aby ustawić parametry
- możesz mieszać parametryzowane z nieparametryzowanymi metodami w jednej klasie
W przeciwieństwie do innych formatów, nie można ich używać.]}- parameters provider class może mieć tyle parametrów dostarczających metody, ile chcesz, dzięki czemu możesz grupować różne przypadki
- możesz mieć metodę testową, która dostarcza parametrów (nie ma już zewnętrznych klas ani statyki)
- możesz zobaczyć rzeczywiste wartości parametrów w IDE (w Parametryzowanym JUnit jest to tylko kolejne liczby parametrów)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-20 21:09:28
Jeśli TestNG jest opcją, możesz użyć parametrów z Dataproviderami .
Test KAŻDEGO pliku będzie miał swój wynik pokazany w raporcie tekstowym lub interfejsie wtyczki TestNG Eclipse. Liczba wszystkich przeprowadzonych testów będzie liczyć każdy z plików osobno.
To zachowanie różni się od teorii JUnit , w której wszystkie wyniki są sumowane pod jednym wpisem "teorii" i liczone tylko jako 1 test. Jeśli chcesz mieć oddzielne raportowanie wyników w JUnit, możesz spróbować Testy Parametryzowane .
Test i wejścia
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
}
}
Przykładowe wyjście
PASSED: testFile(file1)
PASSED: testFile(file2)
===============================================
Default test
Tests run: 2, Failures: 0, Skips: 0
===============================================
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-18 20:07:12
Miałem podobny problem i skończyło się na napisaniu prostego JUnit 4 runner, który pozwala med dynamicznie generować testy.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-08 19:04:29