2012-06-28 120 views
4

我在阅读Code Complete。在那本书中,史蒂夫麦康奈尔警告说:“开发者测试往往是'干净的测试'。开发人员倾向于测试代码是否工作(干净测试),而不是测试代码中断的所有方式(脏测试)。“如何编写“脏”单元测试?

如何为代码破解的方式编写测试?我的意思是,我可以为不良输入编写测试,并确保它被正确阻止。但除此之外,我应该考虑什么样的事情?麦康奈尔在这里的含义是什么?我很喜欢基本的单元测试,但是试图掌握它。

+0

如果您不这样做:传递以null结尾的字符串'“\ 0”'作为方法参数。也许看看像[PEX](http://research.microsoft.com/en-us/projects/pex/)这样的工具,它们在自动测试边缘案例方面做得很好。 – Filburt

回答

6

我认为你在这里正确的道路上。测试证明代码的工作原理将调用一个合理,有意义和预期输入的方法,程序处于正常状态。虽然测试打破代码尝试认为“开箱即用”关于这段代码,因此使用任何无意义或意想不到的输入。

恕我直言重要的是什么虽然是了解这两个思维过程是非常不同的。当开发人员以TDD方式编写代码时,他倾向于专注于在代码中实现的各种功能部分,并且测试证明此功能或用例的某些功能或指定功能可以正常工作。以这种方式创建的测试是McConnell所说的“干净测试”。

思考一段代码如何被破坏需要一个非常不同的思维过程和不同的体验。它需要从不同的角度来看你的方法和API,例如暂时搁置你所知道的目标的这些方法和参数,并且只关注在技术上可行的与他们做的。还要考虑所有这些 - 通常是隐含的 - 前提条件或依赖关系,这种方法才能正常工作。它取决于从DB读取的配置参数吗?它是否写入文件系统?它是否调用另一个组件,期望它事先被正确初始化?它使用大量的内存吗?它是否在GUI上显示消息?......如果其中一个或多个不成立,该怎么办?

所有这些导致重要的问题:你的方法应该如何处理这种脏案件?它应该崩溃吗?抛出异常?继续尽可能好?返回错误代码?记录错误报告?......所有这些小或更大的决定对于正确和一致地定义方法或API的合同非常重要。

肯特贝克谈到在同一种意义上佩戴“开发人员帽子”和“测试人员帽子”之间的切换。流畅地切换观点和思维过程需要练习和经验。

1

作者最有可能意味着什么清洁测试是仅验证方法执行的happy path的测试。

测试开心路径通常是最简单的,人们可能会认为起作用,他们的写作测试工作已经完成。情况很少如此。试想一下:

public void SaveLog(string entry) 
{ 
    var outputFile = this.outputFileProvider.GetLogFile(); 
    var isValid = this.logValidator.IsValid(outputFile); 
    if (isValid) 
    { 
     this.logWriter.Write(outputFile, entry); 
    } 
} 

快乐路径测试将简单地假定所有的依赖关系(outputFileProviderlogValidatorlogWriter)工作,写确实正在发生。但是,有很大的可能性可能会沿途破坏,而那些路径也应该被测试。像:

  • outputFileProvider无法获取输出文件
  • outputFile被证明是无效的
  • logValidator失败,自己的异常
  • logWriter无法写入

只是仅举几例!单元测试比单纯检查快乐路径还多,但不幸的是情况往往如此。

1

Elisabeth Hendrickson,Test Obsessed,有一个Test Heuristics Cheat Sheet,其中她列出了各种的测试方法。该文件广泛地涉及测试,但名为“数据类型攻击”的部分有很多具体的例子,“不愉快的路径”单元测试可以看。

例如,这里有她对方法测试的路径和文件的想法:在名称

长名称(> 255个字符)
特殊字符(空格*/\ | <>,(?。 )[] {};:'“ @#$%^ &)
不存在的
已经存在
没有空间
最小的空间
写保护
不可用
锁定
在损坏

远程计算机