我很想知道在Visual Studio 2008单元测试框架中是否有针对C#的重试测试的内置机制。 例如,我有一个C#单元测试,看起来像:
[TestMethod]
public void MyMethod() {
DoSomething();
Assert.Something();
}
现在偶尔DoSomething()
表现不佳;在这种情况下,我想在达到断言之前重新运行DoSomething()
方法。显然我可以做类似的事情:
...
do {
Initialization();
DoSomething();
} while (PerformedOK() == false);
Assert.Something();
...
虽然这有点麻烦,因为添加了循环并重复测试初始化,否则将由其他方法/类构造函数完全处理。
我的问题是是否有更方便的机制来重试测试,例如:
DoSomething();
if (PerformedOK() == false) Retry();
else Assert.Something();
将自动重试测试而不将其注册为失败,同时像往常一样执行所有常规初始化代码。
答案 0 :(得分:8)
说真的......
偶尔DoSomething()会执行 严重
每次测试都应该是绿色的。如果测试代码有时执行“严重”,那么您需要修复代码,隔离不同的行为。你应该有两个测试,一个是当DoSomething失败时断言正确(并且应该失败),另一个是DoSomething正常时断言正确(并且应该没问题)。
在测试中使用重试逻辑是错误的。您应始终断言预期结果,并且您应该能够隔离并检测代码以返回您期望的结果。
[编辑 - 添加了一些可用于重试循环的代码]
你可以创建一个循环包装器,它接受任何方法并将其调用X次,或直到它成功。您也可以使用Loop函数调用init,或将其作为单独的参数传递。如果成功,该方法也可以返回bool。更改签名以满足您的需求。
[TestMethod]
public void something()
{
Loop.LoopMe(TestMethod,3);
Assert.Something();
}
class Loop
{
public static void LoopMe(Action action, int maxRetry)
{
Exception lastException = null;
while (maxRetry > 0)
{
try
{
action();
return;
}
catch (Exception e)
{
lastException = e;
maxRetry--;
}
}
throw lastException;
}
}
答案 1 :(得分:1)
您的第二个示例几乎是相同的代码行和相同的复杂性。有很多方法可以剥皮,你可以而不是我主张使用递归。
[TestMethod]
public void MyMethod() {
bool success = DoSomething();
Assert.IsTrue(success);
}
public boolean DoSomething(){
//Do whatever
if(performedOk){
return true;
}else{
//find a way to stop it.
}
}
但关键是它是一个单元测试。如果某些事情导致它出错,您需要找到一种方法来隔离您的测试,以便它处于受控环境中。
除非你有要求,否则测试最终应该通过。您应该使用的最佳重试逻辑是在失败之后。单击测试并再次点击运行。