Java IntelliJ:使用previos run重新运行间歇性失败的随机测试';s数据

Java IntelliJ:使用previos run重新运行间歇性失败的随机测试';s数据,java,unit-testing,intellij-idea,junit,intermittent,Java,Unit Testing,Intellij Idea,Junit,Intermittent,我有一个JUnit测试类,包含许多测试。为了增加场景覆盖率,我们测试中的一些数据是随机的,这意味着它可能在单独的测试运行之间采用一系列值,例如: protected MonthlyAmountWithRemainder getMonetaryAmountMultipleOf(int multiplier) { BigDecimal monthly = randomBigDecimal(1000); BigDecimal multiply = new BigDecimal(mult

我有一个JUnit测试类,包含许多测试。为了增加场景覆盖率,我们测试中的一些数据是随机的,这意味着它可能在单独的测试运行之间采用一系列值,例如:

protected MonthlyAmountWithRemainder getMonetaryAmountMultipleOf(int multiplier) {
    BigDecimal monthly = randomBigDecimal(1000);
    BigDecimal multiply = new BigDecimal(multiplier);
    BigDecimal total = monthly.multiply(multiply);
    return new MonthlyAmountWithRemainder(total, monthly, ZERO);
}
你看到这个
randomBigDecimal(1000)
了吗?可以生成0到1000之间的任何值。我们还可以在测试中随机化日期和一些其他值

通常情况下,我们的测试运行得很好,但如果没有任何明显的原因,测试就会失败。正如您所想象的,这种罕见的故障使得调试测试用例以找出故障原因或修复故障变得不可能


因此,问题是:是否可以捕获失败测试运行中生成的数据,并使用完全相同的测试数据重新运行测试,以便调试失败场景?换句话说,我想重新体验我以前失败的测试运行。这可以实现吗?

简单:使用种子来为随机数生成器种子。该种子可以从随机数生成器本身创建(以便每次运行都获得不同的随机值)。核心点是记录所使用的种子

因为“fail repo”可以归结为不使用随机种子,而是使用导致测试失败的种子值

当然:要使事情“正确”需要付出努力——您需要确保使用不同的种子运行日常测试。但是,您还需要确保固定种子是微不足道的,并且会导致确定的结果

或者,每当随机数据出现时,您应该研究基于“快速检查”的测试方法(参见示例)。进入这种方法需要一些思考,但这通常是值得的。其思想是指定生产代码的某些属性,然后框架生成随机数据并试图篡改这些属性。真正好的部分是:一旦框架找到一种方法来破坏你的属性,它就会开始搜索导致问题的最小的示例。

谢谢@GhostCat。 以下是我们在项目中的处理方式:

测试类应扩展以下类:

import org.junit.rules.TestRule;
import org.junit.Rule;
public class RandomisedTest {
@Rule
public final TestRule randomisedRule = new RandomisedRule();
}
然后,当您有一个使用随机值的测试方法时,如:

@Test
public void shouldDoStuff() {
...
}
当它失败时,在失败异常跟踪中将有一个种子编号(长,如1516787460453)

要使用相同的测试数据重新运行测试,请将以下注释附加到测试方法标题:

@Test
@RandomisedRule.Randomised(1516787460453)
public void shouldDoStuff() {
...
}
重新运行时,测试将使用与上次运行中相同的测试数据

希望这对别人有帮助