参数化测试:有选择地仅运行一个数据点

时间:2014-12-06 14:08:42

标签: java junit junit4

我有一个Parameterized测试,例如,用文件输入:

@RunWith(Parameterized.class)
public class FileTest {
...
public static Collection<Object[]> data() {
     return IteratorUtils.toList( FileUtils.iterateFiles(testFilesDir
                                                        , TrueFileFilter.INSTANCE
                                                        , (IOFileFilter) null) );
 }

文件系统中的文件,表格或URL中的行是否真的没有区别。只需进行Parameterized测试即可获得大量数据点,并需要时间来结束。

现在我正在运行测试,说10,000个文件,我检测到文件#9,203的问题。我修复了这个bug 验证我想要重新运行测试的修复程序,但仅针对此特定文件(因为我不能等待2个小时)。后续的重新运行(在确认修复之后)当然应该包含整个数据集。

有没有办法做到这一点,例如通过在JUnit的控制台调用中提供一些运行时参数,以便只使用一个特定的数据点?

1 个答案:

答案 0 :(得分:2)

好的,所以最后我找到了实现这个目标的方法。为参数化测试类使用构造函数,该构造函数也采用可以从命令行轻松传递的友好名称。例如。类似的东西:

private final File   testFile;
private final String friendlyTestName;

public FileTest(File testFile, String friendlyTestName) {
    this.testFile = testFile;
    this.friendlyTestName = friendlyTestName;
}

当然,您必须在提供数据点的方法中生成适当的元组。例如。在下面的示例中,友好名称只是测试文件的文件名(没有路径;我们假设它们是唯一的):

@Parameters(name= "{index}: {1}")
public static Collection<Object[]> data() {
    Collection<File> _rv = IteratorUtils.toList( FileUtils.iterateFiles(testFilesDir, TrueFileFilter.INSTANCE, (IOFileFilter) null) );
    Collection<Object[]> rv = new ArrayList<>();
    for (File f : _rv)
        rv.add(new Object[]{f, f.getName()});
    return rv;
}

然后,从命令行调用Ant时会传递target-friendly-name参数:

ant -Dtarget-friendly-name=a-005 test

...并确保将其一直传达到junit Ant任务。例如。在build.xml文件中,您应该有类似的内容:

<junit printsummary="${junit.summary}" showoutput="${junit.output}">
    <sysproperty key="target-friendly-name" value="${target-friendly-name}"/>
    ...
</junit>            

最后,在测试方法本身使用assumeTrue要求数据点的友好名称等于目标友好名称(如果存在;否则运行所有测试)。

@Test
public void testFile() {
    assumeTrue( (targetFriendlyName==null)||(targetFriendlyName.equals(friendlyTestName)) );
    ...
}

我一直在寻找一种方法来直接使用Parameters注释的{index}属性,这样就不需要定义一个单独的friendlyName但是还没有找到方法这样做;因此,此解决方案需要在测试类中不自然地添加友好名称字段。