在我们的项目中我有几个 联合单元 测试例如从目录中取出每个文件并对其运行测试。如果我实施一个 testEveryFileInDirectory 方法中的 TestCase 这显示为只有一项可能失败或成功的测试。但我对每个单独文件的结果感兴趣。我怎样才能写一个 TestCase / TestSuite 这样每个文件都显示为单独的测试,例如在 Eclipse 的图形化 TestRunner 中?(为每个文件编写显式测试方法不是一种选择。)

也比较一下问题 在 Eclipse Testrunner 中使用名称的 ParameterizedTest.

有帮助吗?

解决方案

取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;
    }
}

同时检查此例如

其他提示

<强> 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 参数化测试

J单元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 动态测试

J单元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

应该通过从TestSuite继承和重写tests()方法列出文件和每个在JUnit 3中可能返回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 参数化运行器的主要区别:

  • 更明确 - 参数位于测试方法参数中,而不是类字段中
  • 更少的代码 - 你不需要构造函数来设置参数
  • 您可以在一个类中混合使用参数化方法和非参数化方法
  • params 可以作为 CSV 字符串或从参数提供程序类传递
  • 参数提供者类可以有任意数量的参数提供方法,以便您可以对不同的情况进行分组
  • 您可以有一个提供参数的测试方法(不再有外部类或静态变量)
  • 您可以在 IDE 中看到实际的参数值(在 JUnit 的 Parametrised 中,它只是连续的参数数量)

如果TestNG的是一个选项,你可以使用参数用的dataProvider

每个单个文件的测试将在基于文本的报告或Eclipse的TestNG插件UI示出其结果。运行将单独计算每个文件的总测试的次数。

此行为从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
===============================================

我有类似的问题,并最终编写一个简单的JUnit 4转轮,允许MED动态地生成的测试。

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top