我有以下问题(使用_junit 4.11_):
<strong i="6">@ClassRule</strong>
public static TemporaryFolder tmp = new TemporaryFolder();
...
<strong i="7">@Parameters</strong>
public static Collection<Object[]> data() throws Exception {
return java.util.Arrays.asList(new Object[][] {
{0, tmp.getRoot().getPath()}
});
}
这会导致初始化错误
java.lang.IllegalStateException: the temporary folder has not yet been created
at org.junit.rules.TemporaryFolder.getRoot(TemporaryFolder.java:127)
所以似乎_@Parameters_方法是在 _ClassRule_ 初始化阶段之前执行的,这使得上面的场景有点复杂。
当前解决方法:
protected static TemporaryFolder initStaticTemp() {
try {
return new TemporaryFolder() { { before(); } };
} catch (Throwable t) {
throw new RuntimeException(t);
}
}
public static TemporaryFolder tmp = initStaticTemp();
<strong i="6">@AfterClass</strong>
public static cleanup() throws Exception {
tmp.delete();
}
它可以工作,但需要手动清理......
+1
想一想,我想实现这一点的一个好方法是为此引入一个注释:
<strong i="7">@Parameters</strong>
<strong i="8">@AfterClassRules</strong>
public Object[][] generateParameters() {
// do stuff
}
这将确保两种变体仍然可用,并且现有代码不会被破坏。 如果维护人员可以接受这种设计,我将开始为此提出拉取请求。
我正在写一条附加评论,因为我不确定评论的更新是否会触发通知。
我之前评论中提出的设计会被维护者接受吗? 如果是这样,我将开始处理拉取请求。
这里有一个相当困难的架构问题:JUnit 向 Eclipse 之类的运行器承诺,它可以在运行任何测试之前枚举有多少测试,但还希望最大限度地减少在此规划阶段消耗的任何资源。 所以我们真的很想知道在我们之前会有多少参数,例如,创建任何临时文件夹,或者执行 ClassRules 中出现的更激烈的事情,比如启动服务器。
也许我最喜欢的答案是在 Theories 中启用@DataPoints 之类的东西:可以有以@ParameterSet为前缀的静态字段或静态方法,它们结合在一起构成完整的参数集。 所以你的例子是:
@ClassRule public static TemporaryFolder tmp = new TemporaryFolder();
@ParameterSet public static Object[] first = new Object[] { 0 };
@ParameterSet public static Object[] second() {
return new Object[] { tmp.getRoot().getPath(); }
}
这里的重点是我们可以在不实际执行的情况下计算方法“秒”。
你怎么看?
嗯,我想现在我想起来了,这个问题实际上更多的是我的测试代码中的气味。 我正在连接到远程服务并根据其配置方式运行测试。 相反,我可能应该在我的测试中修复预期的配置。
这是我最初遇到问题的测试: CryptoAppExecReturnCodeTest.java
@dsaff我会考虑一下您的建议。 最初的印象是:将对拆分为单独的数组需要特别注意元素的位置(容易出错)。 所以我最终可能会用一些虚拟的东西填充_first_(只是保持元素的数量); 并在_second_中-我想将pair元素彼此相邻:
{ 0, tmp...getPath() },
{ 1, ... }
除了测试次数之外,跑步者还需要什么? (例如 - 也许是测试名称?)
@javornikolov ,我刚刚意识到我误读了您的初始帖子,因此我的回复可能令人困惑。 我将您的测试视为使用一个参数构造的测试类的两个不同实例; 现在我再次阅读它,它实际上是一个由两个参数构造的测试类的实例。 然后调整我的建议,建议的代码是:
<strong i="7">@ClassRule</strong> public static TemporaryFolder tmp = new TemporaryFolder();
<strong i="8">@ParameterSet</strong> public static Object[] only() {
return new Object[] { 0, tmp.getRoot().getPath(); }
}
我希望这能让我的意图更清楚; 对不起我最初的困惑。
(通过一些旧的错误)
也许我们应该将此问题重命名为“在理论中启用@DataPoints 之类的东西”?
(通过一些旧的错误)
也许我们应该将此问题重命名为“在理论中启用@DataPoints 之类的东西”?
我会说问题是能够在参数化测试的参数列表中使用Rule
资源。 @dsaff提出的@ParameterSet
方法对我来说似乎是可行的(假设评估以解决原始问题的顺序进行)。
但是,如果“类似@DataPoints 的东西”足够清晰,并且没有在不涵盖原始场景的方向上出现分歧的风险:对我来说还可以。
我更喜欢参数化测试而不是理论(使用数据点)的原因是后者的结果不会为每组参数独立报告,并且第一次失败会中止后续参数的执行。
最有用的评论
当前解决方法:
它可以工作,但需要手动清理......