我们编写测试来验证程序行为的正确性。
通过使用眼睛检查输出语句的内容来验证程序行为的正确性是手册,或者更具体地说,是视觉 过程。
你可以这么说
目视检查工作,我检查代码是否符合预期
做,对于这些情况,一旦我看到它是正确的,我们就可以
去吧。
现在首先,很高兴您对代码是否正常工作感兴趣。这是好事。你走在了曲线的前面!遗憾的是,这种方法存在问题。
目视检查的第一个问题是,如果您永远无法再次检查代码的正确性,那么您就是一个严重的焊接事故。
第二个问题是,使用的那双眼睛与眼睛主人的大脑紧密耦合。如果代码的作者还拥有视觉检查过程中使用的眼睛,那么验证正确性的过程依赖于视觉检查员大脑中内化的程序知识。
仅仅因为他们没有与原始编码人员的大脑合作,就很难有一双新的眼睛进来并验证代码的正确性。第二双眼睛的所有者必须与代码的原作者交谈才能完全理解相关代码。众所周知,对话作为一种分享知识的方式是不可靠的。如果原始编码器对新的眼睛不可用,则这一点没有实际意义。在那种情况下,新的眼睛必须阅读原始代码。
阅读其他人的单元测试未涵盖的代码比阅读具有相关单元测试的代码更难。最好的情况是阅读其他人的代码是一项棘手的工作,最坏的情况是这是软件工程中最艰巨的任务。雇主在宣传职位空缺时强调项目是新建项目(或全新项目)是有原因的。从头开始编写代码比修改现有代码更容易,从而使招聘的职位对潜在员工更具吸引力。
通过单元测试,我们将代码分成其组成部分。然后,对于每个组件,我们设置了我们的摊位,说明程序应该如何表现。每个单元测试都讲述了程序的该部分应如何在特定场景中运行的故事。每个单元测试就像合同中的一个条款,从客户端代码的角度描述应该发生的事情。
这意味着一双新的眼睛拥有两个关于相关代码的实时准确文档。
首先他们有代码本身,实现,代码是如何完成的;其次,他们拥有原始编码人员在一组正式陈述中描述的所有知识,这些陈述讲述了这段代码应该如何表现的故事。
单元测试捕获并正式描述了原作者在实现类时所拥有的知识。它们描述了该类在客户端使用时的行为方式。
您对这样做的有用性提出质疑是正确的,因为可能会编写无用的单元测试,不涵盖所有有问题的代码,变得陈旧或过时等等。我们如何确保单元测试不仅模仿而且改进了知识渊博、尽职尽责的作者在运行时直观地检查其代码的输出语句的过程?首先编写单元测试,然后编写代码以使该测试通过。完成后,让计算机运行测试,它们速度很快,它们擅长做重复性任务,它们非常适合这项工作。
每次触发他们测试的代码并为每个构建运行测试时,都要对其进行审查,从而确保测试质量。如果测试失败,请立即修复。
我们将运行测试的过程自动化,以便每次构建项目时都会运行它们。我们还自动生成代码覆盖率报告,详细说明测试覆盖和执行的代码百分比。我们争取高比例。如果一些公司没有编写足够的单元测试来描述代码行为的任何变化,他们会阻止将代码更改签入源代码控制。通常,第二双眼睛会与更改的作者一起审查代码更改。审阅者将检查更改,以确保更改可以理解并被测试充分覆盖。所以审查过程是手动的,但是当测试(单元和集成测试以及可能的用户验收测试)通过这个手动审查过程时,就成为自动构建过程的一部分。每次签入更改时都会运行它们。continuous-integration 服务器在构建过程中执行此任务。
自动运行的测试,维护代码行为的完整性,并有助于防止未来对代码库的更改破坏代码。
最后,提供测试可以让您积极地re-factor code,因为您可以安全地进行重大代码改进,因为您知道您的更改不会破坏现有测试。
Test Driven Development 有一个警告,那就是您编写代码时必须着眼于使其可测试。这涉及对接口进行编码并使用依赖注入等技术来实例化协作对象。查看Kent Beck 的工作,他很好地描述了 TDD。查找coding to interfaces并学习design-patterns