在Java中从循环创建多个单元测试
我正在为我的(小型)程序编写单元测试,测试用例在大约30个不同的文件中指定。在Java中从循环创建多个单元测试,java,unit-testing,junit,junit4,Java,Unit Testing,Junit,Junit4,我正在为我的(小型)程序编写单元测试,测试用例在大约30个不同的文件中指定。 为了测试它,我只需要一个循环,它遍历所有文件,解析它们,并执行所需的操作 问题是,在这种情况下,我的所有测试都将被视为一个测试,因为它与@Test符号在同一个函数中。 是否可以以某种方式拆分它,而不必为每个测试文件使用单独的函数 所有测试都作为一个测试用例的问题是,我看不出哪个测试用例没有通过这个过程;如果一个失败了,其余的都失败了(我会得到一个测试失败,而不是5/30失败) 我目前正在使用JUnit(4.12),但我
为了测试它,我只需要一个循环,它遍历所有文件,解析它们,并执行所需的操作 问题是,在这种情况下,我的所有测试都将被视为一个测试,因为它与
@Test
符号在同一个函数中。是否可以以某种方式拆分它,而不必为每个测试文件使用单独的函数 所有测试都作为一个测试用例的问题是,我看不出哪个测试用例没有通过这个过程;如果一个失败了,其余的都失败了(我会得到一个测试失败,而不是5/30失败) 我目前正在使用JUnit(4.12),但我没有义务继续使用它,所以如果有更好的解决方案,我可以切换框架 谢谢 例如:
public class MyTests {
@Test
public void testFromFiles {
// loop through all the files
}
}
output: 1 test run successfully
更新:选择的答案对我来说非常有用,我用JUnit 5(而不是4)添加了另一个解决方案,以防它对某人有所帮助。尝试以下方法:
@RunWith(Parameterized.class)
public class EdiTest {
@SuppressWarnings("WeakerAccess")
@Parameterized.Parameter(value = 0)
public String model;
@SuppressWarnings("WeakerAccess")
@Parameterized.Parameter(value = 1)
public String filename;
@Parameterized.Parameters(name = "{index}: testEDI({0}, {1})")
public static Collection<Object[]> data() {
return Arrays.asList(new Object[][]{
{"753", "edi753_A.edi"},
{"753", "edi753_B.edi"},
{"754", "edi754.edi"},
{"810", "edi810-withTax.edi"},
{"810", "edi810-withoutTax.edi"},
});
}
@Before
public void setUpContext() throws Exception {
TestContextManager testContextManager = new TestContextManager(getClass());
testContextManager.prepareTestInstance(this);
}
@Test
public void testEDI() throws IOException {
String edi = IOUtils.toString(ClassLoader.getSystemResource(filename));
EdiConverter driver = ediConverterProvider.getConverter(model);
// your test code here
}
}
@RunWith(参数化的.class)
公共类编辑测试{
@抑制警告(“弱化访问”)
@参数化。参数(值=0)
公共字符串模型;
@抑制警告(“弱化访问”)
@参数化。参数(值=1)
公共字符串文件名;
@Parameterized.Parameters(name=“{index}:testEDI({0},{1})”)
公共静态收集数据(){
返回Arrays.asList(新对象[][]{
{“753”,“edi753_A.edi”},
{“753”,“edi753_B.edi”},
{“754”,“edi754.edi”},
{“810”,“edi810 with tax.edi”},
{“810”,“edi810不含税。edi”},
});
}
@以前
public void setUpContext()引发异常{
TestContextManager TestContextManager=新的TestContextManager(getClass());
testContextManager.prepareTestInstance(此);
}
@试验
public void testEDI()引发IOException{
字符串edi=IOUtils.toString(ClassLoader.getSystemResource(filename));
EdiConverter驱动程序=ediConverterProvider.getConverter(型号);
//您的测试代码在这里
}
}
尝试以下方法:
@RunWith(Parameterized.class)
public class EdiTest {
@SuppressWarnings("WeakerAccess")
@Parameterized.Parameter(value = 0)
public String model;
@SuppressWarnings("WeakerAccess")
@Parameterized.Parameter(value = 1)
public String filename;
@Parameterized.Parameters(name = "{index}: testEDI({0}, {1})")
public static Collection<Object[]> data() {
return Arrays.asList(new Object[][]{
{"753", "edi753_A.edi"},
{"753", "edi753_B.edi"},
{"754", "edi754.edi"},
{"810", "edi810-withTax.edi"},
{"810", "edi810-withoutTax.edi"},
});
}
@Before
public void setUpContext() throws Exception {
TestContextManager testContextManager = new TestContextManager(getClass());
testContextManager.prepareTestInstance(this);
}
@Test
public void testEDI() throws IOException {
String edi = IOUtils.toString(ClassLoader.getSystemResource(filename));
EdiConverter driver = ediConverterProvider.getConverter(model);
// your test code here
}
}
@RunWith(参数化的.class)
公共类编辑测试{
@抑制警告(“弱化访问”)
@参数化。参数(值=0)
公共字符串模型;
@抑制警告(“弱化访问”)
@参数化。参数(值=1)
公共字符串文件名;
@Parameterized.Parameters(name=“{index}:testEDI({0},{1})”)
公共静态收集数据(){
返回Arrays.asList(新对象[][]{
{“753”,“edi753_A.edi”},
{“753”,“edi753_B.edi”},
{“754”,“edi754.edi”},
{“810”,“edi810 with tax.edi”},
{“810”,“edi810不含税。edi”},
});
}
@以前
public void setUpContext()引发异常{
TestContextManager TestContextManager=新的TestContextManager(getClass());
testContextManager.prepareTestInstance(此);
}
@试验
public void testEDI()引发IOException{
字符串edi=IOUtils.toString(ClassLoader.getSystemResource(filename));
EdiConverter驱动程序=ediConverterProvider.getConverter(型号);
//您的测试代码在这里
}
}
使用JUnit 5和:
- :
类动态测试{ @试验工厂 列出createSomeTests(){ 返回数组.asList( DynamicTest.DynamicTest(“第一个动态创建的测试”, ()->资产真(真)), DynamicTest.DynamicTest(“第二个动态创建的测试”, ()->资产真实(真实)) ); } }
- 获取和筛选所有测试文件的示例:
class MyTestsClass { @TestFactory List<DynamicTest> runAllTestFiles() { List<DynamicTest> list = new ArrayList<DynamicTest>(); try (Stream<Path> paths = Files.walk(Paths.get("tests_dir"))) { List<Path> files = paths .filter(path -> path.getFileName().toString().endsWith(".mytests")) .collect(Collectors.toList()); files.forEach(file -> list.add( DynamicTest.dynamicTest( file.getFileName().toString(), () -> testFileWithSomeAsserts(file)) )); } catch (IOException e) { e.printStackTrace(); } return list; } }
类MyTestsClass{ @试验工厂 列出runAllTestFiles(){ 列表=新的ArrayList(); try(Stream path=Files.walk(path.get(“tests\u dir”)){ 列出文件=路径 .filter(path->path.getFileName().toString().endsWith(“.mytests”)) .collect(Collectors.toList()); files.forEach(文件->列表.add( 动态测试,动态测试( file.getFileName().toString(), ()->testFileWithSomeAsserts(文件)) )); }捕获(IOE异常){ e、 printStackTrace(); } 退货清单; } }
@TestFactory
的工作原理与常规测试不同,在这种情况下,不能使用每个测试之前的/@之后的:
动态测试生命周期
动态测试的执行生命周期与标准@test
案例的执行生命周期截然不同。具体来说,没有针对单个动态测试的生命周期回调。这意味着对@TestFactory
方法执行@beforeach
和@AfterEach
方法及其相应的扩展回调,但不对每个动态测试执行。换句话说,如果您访问lambda表达式中用于动态测试的测试实例中的字段,那么在执行同一@TestFactory
方法生成的各个动态测试之间,回调方法或扩展不会重置这些字段
与JUnit 5和:
- :
类动态测试{
@试验工厂
列出createSomeTests(){
返回数组.asList(
DynamicTest.DynamicTest(“第一个动态创建的测试”,
()->资产真(真)),
DynamicTest.DynamicTest(“第二个动态创建的测试”,
()->资产真实(真实))
);
}
}
- 获取和筛选所有测试文件的示例:
class MyTestsClass {
@TestFactory
List<DynamicTest> runAllTestFiles() {
List<DynamicTest> list = new ArrayList<DynamicTest>();
try (Stream<Path> paths = Files.walk(Paths.get("tests_dir"))) {
List<Path> files = paths
.filter(path -> path.getFileName().toString().endsWith(".mytests"))
.collect(Collectors.toList());
files.forEach(file -> list.add(
DynamicTest.dynamicTest(
file.getFileName().toString(),
() -> testFileWithSomeAsserts(file))
));
} catch (IOException e) {
e.printStackTrace();
}
return list;
}
}
类MyTestsClass{
@试验工厂
列出runAllTestFiles(){
列表=新的ArrayList();
try(Stream path=Files.walk(path.get(“tests\u dir”)){
列出文件=路径
.filter(路径