NUnit 中的 [Retry] 和 [Repeat] 属性如何交互
How do the [Retry] and [Repeat] attributes interact, in NUnit
那么...如果附加两个 属性,预期的行为是什么?
哪个属性在里面,哪个属性在外面?
如果 [Retry]
在外面,那么你断言:
- “这一般要非常稳定,但偶尔的闪烁是可以的。”
- 例如
[Repeat(50), Retry(3)]
表示“您必须能够连续取得 50 次成功,但您有 3 次尝试这样做。”
如果 [Repeat]
在外面,那么你断言:
- “这通常不会一直失败。如果您尝试几次,它就会一直有效。”
- 例如
[Repeat(50), Retry(4)]
说“在几乎每组 4 中,至少 一个 的执行会成功。”
据我所知,我能看到的文档没有给出任何指示。 :(
早期版本没有处理这个问题,结果是不确定的。 2018 年的一个 PR 引入了代码,导致任何具有多个重复属性(如重复和重试)的测试总是失败。
事实上,代码库中甚至有一个测试来验证此行为:https://github.com/nunit/nunit/blob/aa74dcd07da92e6b3a1182c760b6ca3e72455379/src/NUnitFramework/tests/Attributes/RepeatableTestsWithTimeoutAttributesTests.cs#L128
很遗憾,答案是您不能在当前版本的 NUnit 中对同一个测试使用这两个属性。
解决方法...
使用您希望“在外部”的属性,并在您的测试代码本身中实现与其他属性等效的属性。
如果您想测试“连续三次正确获得 50 次的机会”,请使用 [Retry(3)] 并在您的测试中添加代码以尝试该操作 50 次,失败后立即失败。
for (int i = 0; i < 50; i++)
{
// Try your operation
Assert.That(.... // whatever you are asserting
}
如果你想测试“运行 50 次,每次重试 4 次,”使用 [Repeat(50)] 和 包括一个实现重试的循环。这个比较棘手,因为您必须防止任何断言过早地终止测试。以下至少是您可能需要做的事情的开始。
Exception ex = null;
for (int i = 0; i < 4; i++)
{
ex = Assert.Catch(() => // try your operation );
if (ex == null) Assert.Pass();
}
Assert.Fail(ex.Message);
重要提示: 不要 使用 c# try
和 catch
而不是 Assert.Catch
。在最新版本的 NUnit 中,在抛出任何异常之前会报告失败。 NUnit 异常不打算被测试代码看到。