在 Java 中生成数据驱动的单元测试
Generate Data-Driven Unit-Tests in Java
假设我有一个 junit 方法
public class BusinessClassTest {
private BusinessClass fixture;
@Test
public void test1() {
//the following two paths reside in the man/test/resources folder
String inputPath = "/fixtures/1/input";
String expectedPath = "/fixtures/1/expected";
validatedFixture(inputPath, expectedPath);
}
private void valiateFixture(String inputPath, String expectedPath) {
//inputData = load the input data
//feed it to a fixture
//actual = fixture.process(inputData)
//expectedData = loadExpectedData
//validate(expectedData, actualData);
}
}
现在假设我在 fixtures 下有 20 个文件夹。我如何遍历文件夹并为每个文件夹生成一个类似于
的方法
@Test
public void test{test_number}() {
//the following two paths reside in the man/test/resources folder
String inputPath = "/fixtures/{test_number}/input";
String expectedPath = "/fixtures/{test_number}/expected";
validatedFixture(inputPath, expectedPath);
}
空闲时我想将此 class 构建为 maven 的一部分。
更新
我正在使用 velocity 来生成 class 但是,不确定如何从 maven 进行代码生成...
你真的需要动态构建测试类吗?另一种方法是遍历 fixtures
基本路径的所有子目录,然后直接为每个路径调用 validatedFixture
。在下面的 Java8 中查找示例:
@Test
public void bigTest {
File file = new File("/fixtures/");
String[] dirs = file.list((current, name) ->
new File(current, name).isDirectory());
for (String testNumber : dirs) {
String inputPath = "/fixtures/" + dirs + "/input";
String expectedPath = "/fixtures/" + dirs + "/expected";
// omit the test method and call validation directly
validatedFixture(inputPath, expectedPath);
}
}
使用 Matt 列出的文件系统遍历,您可以使用参数化测试来执行您的数字验证。
此方法将根据@Parameters(name) 注释的参数为您提供命名良好的测试。
import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import org.junit.Assert;
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 BusinessClassTest{
@Parameters(name="{0}:{1}")
public static Collection<Object[]> getTestPaths() {
Collection<Object[]> allTests = new ArrayList<>();
File file = new File("/fixtures/");
String[] dirs = file.list((current, name) ->
new File(current, name).isDirectory());
for (String testNumber : dirs) {
String inputPath = "/fixtures/" + dirs + "/input";
String expectedPath = "/fixtures/" + dirs + "/expected";
allTests.add(asConstructorArguments(inputPath, expectedPath));
}
return allTests;
}
private static Object[] asConstructorArguments(String inputPath, String expectedPath) {
return new Object[]{inputPath, expectedPath};
}
private final String inputData;
private final String expectedData;
private final Fixture fakedFixture;
public BusinessClassTest(String input, final String expected) {
this.inputData = input;
this.expectedData = expected;
fakedFixture = new Fixture() {
@Override
public String process(String path) {
return expected;
}
};
}
@Test
public void validateFixture() {
//feed it to a fixture
String actualData = fakedFixture.process(inputData);
Assert.assertEquals(expectedData, actualData);
}
//Interface to emulate your API
public interface Fixture {
String process(String path);
}
}
假设我有一个 junit 方法
public class BusinessClassTest {
private BusinessClass fixture;
@Test
public void test1() {
//the following two paths reside in the man/test/resources folder
String inputPath = "/fixtures/1/input";
String expectedPath = "/fixtures/1/expected";
validatedFixture(inputPath, expectedPath);
}
private void valiateFixture(String inputPath, String expectedPath) {
//inputData = load the input data
//feed it to a fixture
//actual = fixture.process(inputData)
//expectedData = loadExpectedData
//validate(expectedData, actualData);
}
}
现在假设我在 fixtures 下有 20 个文件夹。我如何遍历文件夹并为每个文件夹生成一个类似于
的方法 @Test
public void test{test_number}() {
//the following two paths reside in the man/test/resources folder
String inputPath = "/fixtures/{test_number}/input";
String expectedPath = "/fixtures/{test_number}/expected";
validatedFixture(inputPath, expectedPath);
}
空闲时我想将此 class 构建为 maven 的一部分。
更新
我正在使用 velocity 来生成 class 但是,不确定如何从 maven 进行代码生成...
你真的需要动态构建测试类吗?另一种方法是遍历 fixtures
基本路径的所有子目录,然后直接为每个路径调用 validatedFixture
。在下面的 Java8 中查找示例:
@Test
public void bigTest {
File file = new File("/fixtures/");
String[] dirs = file.list((current, name) ->
new File(current, name).isDirectory());
for (String testNumber : dirs) {
String inputPath = "/fixtures/" + dirs + "/input";
String expectedPath = "/fixtures/" + dirs + "/expected";
// omit the test method and call validation directly
validatedFixture(inputPath, expectedPath);
}
}
使用 Matt 列出的文件系统遍历,您可以使用参数化测试来执行您的数字验证。
此方法将根据@Parameters(name) 注释的参数为您提供命名良好的测试。
import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import org.junit.Assert;
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 BusinessClassTest{
@Parameters(name="{0}:{1}")
public static Collection<Object[]> getTestPaths() {
Collection<Object[]> allTests = new ArrayList<>();
File file = new File("/fixtures/");
String[] dirs = file.list((current, name) ->
new File(current, name).isDirectory());
for (String testNumber : dirs) {
String inputPath = "/fixtures/" + dirs + "/input";
String expectedPath = "/fixtures/" + dirs + "/expected";
allTests.add(asConstructorArguments(inputPath, expectedPath));
}
return allTests;
}
private static Object[] asConstructorArguments(String inputPath, String expectedPath) {
return new Object[]{inputPath, expectedPath};
}
private final String inputData;
private final String expectedData;
private final Fixture fakedFixture;
public BusinessClassTest(String input, final String expected) {
this.inputData = input;
this.expectedData = expected;
fakedFixture = new Fixture() {
@Override
public String process(String path) {
return expected;
}
};
}
@Test
public void validateFixture() {
//feed it to a fixture
String actualData = fakedFixture.process(inputData);
Assert.assertEquals(expectedData, actualData);
}
//Interface to emulate your API
public interface Fixture {
String process(String path);
}
}