Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/334.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
重试Visual Studio C#TestMethod_C#_Visual Studio_Unit Testing - Fatal编程技术网

重试Visual Studio C#TestMethod

重试Visual Studio C#TestMethod,c#,visual-studio,unit-testing,C#,Visual Studio,Unit Testing,我很想知道Visual Studio 2008 C#单元测试框架中是否有任何内置的机制来重试测试。 举个例子,我有一个C#单元测试,它看起来像: [TestMethod] public void MyMethod() { DoSomething(); Assert.Something(); } ... do { Initialization(); DoSomething(); } while (PerformedOK() == false); Assert.So

我很想知道Visual Studio 2008 C#单元测试框架中是否有任何内置的机制来重试测试。 举个例子,我有一个C#单元测试,它看起来像:

[TestMethod]
public void MyMethod() {
    DoSomething();
    Assert.Something();
}
...
do {
    Initialization();
    DoSomething();
} while (PerformedOK() == false);
Assert.Something();
...
DoSomething();
if (PerformedOK() == false) Retry();
else Assert.Something();
现在,偶尔
DoSomething()
会表现不佳;在这种情况下,我希望在到达断言之前重新运行
DoSomething()
方法。很明显,我可以做如下事情:

[TestMethod]
public void MyMethod() {
    DoSomething();
    Assert.Something();
}
...
do {
    Initialization();
    DoSomething();
} while (PerformedOK() == false);
Assert.Something();
...
DoSomething();
if (PerformedOK() == false) Retry();
else Assert.Something();
尽管这有点麻烦,因为添加了循环并重复测试初始化,否则将完全由其他方法/类构造函数处理

我的问题是,是否有一种更方便的机制来重试测试,比如:

[TestMethod]
public void MyMethod() {
    DoSomething();
    Assert.Something();
}
...
do {
    Initialization();
    DoSomething();
} while (PerformedOK() == false);
Assert.Something();
...
DoSomething();
if (PerformedOK() == false) Retry();
else Assert.Something();
它将自动重试测试,而不会将其注册为失败,同时像往常一样执行所有常规初始化代码。

严重

DoSomething()偶尔执行 糟透了

每次测试都应该是绿色的。如果被测试的代码有时表现“糟糕”,那么您需要修复代码,隔离不同的行为。您应该有两个测试,一个是当DoSomething失败(并且应该失败)时断言正确,另一个是当DoSomething正常(并且应该正常)时断言正确

在测试中使用重试逻辑是错误的。您应该始终对预期结果进行断言,并且您应该能够隔离和插入代码以返回预期结果

[编辑-添加了一些可用于重试循环的代码]

您可以创建一个循环包装器,它接受中的任何方法并调用它X次,或者直到成功为止。您还可以让循环函数调用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;
    }
}

您的第二个示例几乎是相同的代码行和相同的复杂性。有很多种方法可以对它进行蒙皮,你不能说我提倡使用递归

[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.
    }

}
但关键是这是一个单元测试。如果有什么原因导致测试出错,您需要找到一种隔离测试的方法,以便它处于受控环境中


除非你们有要求,否则测试最终应该通过。您应该使用的最佳重试逻辑是在失败之后。单击测试,然后再次点击运行。

我理解您的意见并感谢您的建议,但有时还有其他考虑。@Oak:您依赖第三方系统的考虑因素?如果是一个集成测试,重试逻辑可以是好的,但我仍然认为它应该在您的代码库中,而不是在您的测试中。如果“其他考虑”确实是第三方,考虑使用模拟和/或存根。不要想出更好的方法来做错误的事情。@lotsoffreetime:“做错误事情的更好方法”,我可以引用你的话吗?@oak:它告诉你重试循环应该在DoSomething内部,或者在处理触发重试的异常的包装库代码中,而不是在测试中,因为你希望它在你重试时工作。您在生产中如何处理它?为什么它有时表现不好?@Lasse:在这种情况下,与其说它“表现不好”,不如说它只是失去了与另一个组件的同步,而使它失去同步的方面与此特定测试用例无关。在任何情况下,我的问题都比较笼统,并不真正关心为什么需要重试。当测试实际失败时会发生什么?您是否需要“重试10次,然后停止”?如果另一个组件处于必须重试11次的状态,该怎么办?让我重新表述我的问题。如果完全删除测试,会发生什么?脆性测试是单元测试的祸根“哦,那个测试,是的,我们知道,它总是失败,只要忽略它,它就会消失。”@Lasse“测试失败时会发生什么”-我希望有一个重试机制,如果存在的话,允许我指定什么时候应该重试,什么时候不应该重试。。。就像上面的伪语法一样。如果可能的话,我强烈建议只在特定的已知异常上重试。这样,您的测试方法不会永远运行或每次都通过——它至少会在某些bug上失败。