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

Mat*_*att 3 c# vb.net tdd unit-testing code-coverage

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

例1:

下面是一个示例方法(这也恰好是另一个SO问题中的示例,该问题涉及如何最好地测试它,如果我们要测试它).这种方法做得不多.它System.ServiceProcess.ServiceController是停止服务功能的外观.目前这段代码不是使用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
Run Code Online (Sandbox Code Playgroud)

例2:

如果有人认为代码仍然有一些逻辑,因此在进行TDD时需要进行测试,那么下面的代码没有逻辑:

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
Run Code Online (Sandbox Code Playgroud)

Car*_*ter 11

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

我们大多数人都没有专门测试简单的getter和setter作为TDD过程的一部分.但是,在我们需要它之前,我们不会创建需要getter和setter的字段 - 其中"need"被定义为失败测试.因此,getter和setter将作为理所当然的测试,因为它们是根据我们测试驾驶的方法创建的.

你的两个例子都有足够的逻辑值得测试; 我会测试它们两个.

  • @Matt - 关键是如果明天有人改变了上面的代码,使其不再有效,你是否能够在没有重大调试时间的情况下找出原因?为了对方法进行单元测试,我将创建几个测试用例.验证该方法在指定有效服务名称时返回正确的过程对象(检查属性).验证服务不存在时是否引发异常. - 要说GetProcess没有逻辑是不正确的,只是逻辑被包含在被调用的方法中. (2认同)

Cri*_*ole 5

为了充分披露:我不是TDD的专家(我实际上并没有使用它,也从来没有),但我想我可以在这种情况下对TDD倡导者的无知进行辩论.

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

假设从现在起六个月后你意识到你需要扩展Process一些额外的东西.您委派所有正确的方法并覆盖GetProcessById.您现在正式必须测试这种"零逻辑"方法.那就是麻烦.多态性和编程语言的许多其他特性(甚至不是严格面向对象的特性)导致代码不能完全按照您的想象去做.

所以,话虽如此,如果您遵循严格的TDD方法,并且您正在努力实现100%的测试覆盖率,那么您将需要测试"零逻辑"方法,就像这两种方法一样.

我能想象的唯一例外是.NET特有的,它是自动实现的属性,测试Getter和Setter没有任何意义,因为即使它们没有,你也无能为力.测试包含在属性中的对象,而不是属性本身.

TDD人员,这样做总结得很好吗?