我的问题假设人们已经相信某种单元测试是值得的,并且实际上将它们写在他们当前的项目中。让我们还假设代码的某些部分的单元测试不值得编写,因为它们正在测试微不足道的功能。示例是 getter/setter,和/或编译器/解释器将立即捕获的东西。相反的假设是“有趣”的代码值得测试。
9 回答
代码区域的覆盖级别应该与更改的可能性和依赖它的功能量的组合成正比。
例如,我们在基本控制类的核心有一些相当复杂的解析逻辑。我们对它进行了单元测试,因为它必须处理来自我们影响之外的系统的输入(改变的可能性很大)+我们所有的 UI 控件都依赖于它来保持稳定。基础中最轻微的调整会通过继承和依赖层产生涟漪并放大。
验证在层之间传递的数据的单元测试通常会增加最大的价值
UI <----> 业务 <---> 数据
我发现回报最多的测试是那些测试以前发现的错误的测试。在我看来,如果一个团队在修复错误时只添加回归测试,那么他们将比几乎任何其他测试策略获得更多的收益。
通过测试已损坏的内容(并彻底测试),您知道您正在测试容易损坏的区域。
这当然假设您正在测试在开发过程中中断的东西,而不仅仅是在部署或类似的东西之后等待 QA 报告滴入。
当问题被问到时,我毫不怀疑像 selenium 测试这样的功能测试提供了最大的商业价值。selenium (web) 测试点击应用程序并断言预期的行为,如用户故事/用例所定义。这些测试断言您的软件试图与客户沟通的主要“事物”是好的。
如果这些事情不起作用,您的客户将对您生产可信软件的能力失去信心,从而带走相当多的商业价值。
现在,这些测试可能没有涵盖相当多的细节,但我真的相信它们对于建立信任至关重要,尤其是在与大众市场交谈时。
为了解决我自己的问题,以下是我发现值得测试的模块:
a) 任何业务规则。在我当前的应用程序中,业务规则是从业务对象外部化的。
b) 业务对象上的任何虚拟属性。这些虚拟属性通常涉及算法。
c) 主要组件,我们可以在其中说明给定消耗的输入的预期生产输出。这通常会渗透到集成测试中。
d) 我们的开发过程要求我们检查单元测试中的新功能和错误修复。对于错误修复,我们尝试准确复制导致错误的原因,并显示一旦代码修复被签入,单元测试就可以通过。
e) 我们从一种数据表示类型转换为另一种数据表示类型的任何转换层,例如 POJO-XML
在SO Podcast 41中讨论- 这部分目前不在成绩单中。博客中的回复包含对单元测试覆盖率值的进一步讨论。
- Joel 担心过度的 TDD(例如,从 90% 到 100% 的测试覆盖率)会缩短其他可能使软件产品受益的活动的时间,例如更好的可用性或用户要求的附加功能。
- 单元测试作为“吃你自己的狗粮”的一种形式,并记录系统的行为是绝对有用的。即使您完全无视测试的实际结果,它们作为文档仍然很有价值,并为您提供了对代码库的全新外部视角。
- Joel 指出了测试 UI(Web 或可执行文件)与测试 UI 背后的代码相比的难度。执行此操作的经典方法可能记录在 The Art of UNIX Programming 中,您从一个命令行应用程序开始,该应用程序接收和输出文本。GUI 只是您粘贴在命令行应用程序之上的一个层,它可以带来完美的可测试性——但从长远来看,可能不是那么出色的应用程序。哪个更重要?
所有合理的单元测试都是有价值的,但根据我的经验,那些倾向于节省最多时间,从而产生最佳投资回报率的单元测试是错误修复的单元测试。主要是因为错误修正适用于代码中最困难/最脆弱的部分。
可以在许多地方重用的测试。我当前项目的示例:
- 配置文件的语法检查
- 检查 RTF 模板中引用的模型属性是否确实存在于模型类中(人们更改类并且通常忘记调整模板)
- 检查一些经常被忽视的样式指南规则(每个 UI 掩码必须有标题栏文本,每个按钮必须有唯一的助记符等)
即使是对单元测试持怀疑态度的程序员也喜欢这些,因为他们可以用最少的工作量使用它们——在某些情况下,它会引导他们编写自己的单元测试。
TDD 可以帮助您更快地编写代码,因此只有更快的 TDD 才能提供更多的业务价值。;)