Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vb.net/15.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
C# 当所需代码几乎没有逻辑时,是否仍使用TDD编写测试?为什么?_C#_Vb.net_Unit Testing_Tdd_Code Coverage - Fatal编程技术网

C# 当所需代码几乎没有逻辑时,是否仍使用TDD编写测试?为什么?

C# 当所需代码几乎没有逻辑时,是否仍使用TDD编写测试?为什么?,c#,vb.net,unit-testing,tdd,code-coverage,C#,Vb.net,Unit Testing,Tdd,Code Coverage,TDD应该有100%的代码覆盖率。这是否意味着应该为属性getter和setter以及其他不包含实际逻辑的方法(例如处理外部API功能)编写测试 例1: 下面是一个示例方法(如果我们要测试它,它恰好也是处理如何最好地测试它的示例)。这种方法没有多大用处。它是停止服务的System.ServiceProcess.ServiceController功能的外观。目前,这段代码并不是使用TDD编写的,但如果是,是否应该进行测试?这里没有什么逻辑。测试本身并没有那么大的帮助 供参考:如果您想回答如何最好地

TDD应该有100%的代码覆盖率。这是否意味着应该为属性getter和setter以及其他不包含实际逻辑的方法(例如处理外部API功能)编写测试

例1: 下面是一个示例方法(如果我们要测试它,它恰好也是处理如何最好地测试它的示例)。这种方法没有多大用处。它是停止服务的
System.ServiceProcess.ServiceController
功能的外观。目前,这段代码并不是使用TDD编写的,但如果是,是否应该进行测试?这里没有什么逻辑。测试本身并没有那么大的帮助

供参考:如果您想回答如何最好地测试它(IoC和适配器模式与绕行),请参阅


为了充分披露:我不是TDD方面的专家(我实际上没有使用过它,也从来没有使用过),但我认为我可以在这种情况下为TDD倡导者辩护

想象一下,您有一个简单的“零逻辑”属性/函数,如示例2所示。假设您实现了自己版本的
GetProcessById
,其功能略有不同,但可以与
Process
对象交换。您决定不为此函数编写测试,然后说“啊,我只是将它委托给经过良好测试的库,我不可能把它搞砸。”这是您的第一个错误。“我不可能把事情搞砸”是程序员经常对自己说的最糟糕的谎言

假设六个月后你意识到你需要用一些额外的东西来扩展
过程。您可以委托所有正确的方法并重写
GetProcessById
。您现在必须正式测试这种“零逻辑”方法。这就是问题所在。多态性和编程语言的许多其他特性(即使不是严格面向对象的)导致代码不能完全按照您想象的那样工作

因此,也就是说,如果您遵循严格的TDD方法,并且您正在努力实现100%的测试覆盖率,那么您将需要测试“零逻辑”方法,就像这两种方法一样

我能想象的唯一例外是特定于.NET的,这是自动实现的属性,在这里测试Getter和Setter是否正确工作没有意义,因为即使它们不正确,您也无能为力。测试包装在属性中的对象,而不是属性本身

TDD的朋友们,这总结得很好吗?

TDD不应该有100%的代码覆盖率。与其他方法相比,TDD往往具有非常高的代码覆盖率。如果你没有写一行没有失败测试的代码,如果你严格遵守,那么是的,你将得到100%的覆盖率。但我们大多数人并没有严格遵循这一点,完美的代码覆盖率并不是TDD的目标。高代码覆盖率是测试驱动开发的一个很好的副作用,但这不是重点

我们大多数人不会在TDD过程中测试简单的getter和setter。但是我们不会创建需要getter和setter的字段,除非我们需要它——其中“需要”被定义为失败的测试。所以getter和setter将作为一个理所当然的测试,因为它们是根据我们正在测试的方法的需要创建的

你的两个例子都有足够的逻辑,值得测试;我会把他们两个都试驾。

完全披露:我不使用正式的TDD,也从来没有使用过

您的代码示例封装了一个第三方复杂API来完成一些事情。虫子从哪里来

大多数错误都是由API的意外行为引起的,可能是未记录的行为。在任何情况下(Windows版本/区域设置/网络设置等),都很难让这些事情正常运行。记录人们在Win32 API中犯下的错误和误解,你实际上可以成为一名优秀的程序员

  • 最重要的测试是针对真实API的测试。您需要一些设置和拆卸代码来创建流程或服务
  • 嘲弄/IoC不是很有价值。您只是在证明您正在以特定的顺序进行特定的API调用。您需要证明您的代码在现实世界中遇到的所有情况下都实现了您想要的目标
  • 我真的认为您不能在这里针对mock进行测试优先开发。假设您在第三方API()中发现一个bug。你需要解决这个问题。您甚至可能需要完全改变您的方法,可能是PInvoke到Win32 API或某些COM对象。在这种情况下,模拟测试只是浪费时间。
  • 首先,您必须编写一个针对真实API的解决方案
  • 然后,您必须编辑模拟测试以匹配解决方案
  • 您不能首先编辑模拟测试,因为您必须尝试解决方法,以了解它是否真正起作用

我的是垂直市场的桌面软件。我们有一个像你一样的例程库,我们对它们进行了现实的测试。偶尔,我们会在特定的Windows版本/区域设置/任何地方发现一个bug。然后我们扩展测试以重现bug并验证修复,并确保在我们的测试环境集上重新运行它们。读者注意:如果您的代码,可能是您的,您将不需要这样做。

如果您正在编写代码,然后又想知道如何测试它,那么您就错过了TDD的要点。@Anon我没有试图通过先编写代码来实现TDD。我想知道如果我这样做了,TDD方法真的会对每个方法、属性等进行单元测试吗?不管从逻辑的角度看,是否有任何东西需要真正测试。至于如何测试,我会使用IoC和
Public Function StopService(ByVal serviceName As String, ByVal timeoutMilliseconds As Double) As Boolean Implements IWindowsServicesService.StopService

    Try
        Dim service As New ServiceController(serviceName)
        Dim timeout As TimeSpan = TimeSpan.FromMilliseconds(timeoutMilliseconds)

        service.[Stop]()

        If timeoutMilliseconds <= 0 Then
            service.WaitForStatus(ServiceControllerStatus.Stopped)
        Else
            service.WaitForStatus(ServiceControllerStatus.Stopped, timeout)
        End If

        Return service.Status = ServiceControllerStatus.Stopped

    Catch ex As Win32Exception
        Return False
    Catch ex As TimeoutException
        Return False
    End Try

End Function
Public Function GetProcess(ByVal serviceName As String) As Process
    Dim managementObject As New ManagementObject(String.Format("Win32_service.Name='{0}'", serviceName))
    Dim processID As Integer = CType(managementObject.GetPropertyValue("ProcessID"), Integer)
    Dim process As Process = process.GetProcessById(processID)
    Return process
End Function