测试即是文档
文档需要全面,实时更新,并且易懂。我说的全面是指除了介绍程序的功能外还应该覆盖到代码中一些重要的地方。对很多人来说文档的重要性不言而喻,但很难保持它的及时性和准确性。糟糕的文档的后果通常会浪费更多的资源和时间。往往都是出于一些错误的原因而编写的文档。
要求文档的一些原因
有很多原因导致我们需要编写文档。团队经常会由于一些制度上的要求而编写文档,或者就是纯粹出于无知。下面是一些编写文档的错误的理由:
- 有人认为文档和项目的成败息息相关。
- 文档能够证明某些人的存在。
- 需求方除了文档也不知道要什么好
- 要你提供文档的人也就是求个安心,知道事情都 OK 了
- 工作流程提示说,你该创建文档了
文档都是过时的
软件文档的一个主要的问题就是它通常都不是最新的。代码的某个部分可能发生了改动,但是文档却体现不出这个情况。这句话适用于几乎所有的文档,影响最大的其实还是需求和测试用例。不管你多努力,文档的过期无可避免。
文档对谁有用?
取决于不同的受众,文档的类型和格式也会相应地有所不同。开发人员,测试人员,客户,主管,最终用户都是文档的最大的潜在用户。
开发人员
开发人员不应该依赖于文档,因为它们通常都是过时的。除此之外,没有什么文档能比代码本身更能提供详细以及最新的信息了。如果你想知道某个方法做了些什么,看下这个方法吧。不确定某个类是干嘛的?看一眼它。通常只有代码写的太差了才需要给它添加文档。
使用代码本身作为文档,这并不代表不需要其它的文档了。关键是要避免冗余。如果看一下代码就能获取到系统的详细信息,那么还可以有一些其它的文 档来提供快速导读以及更高层面的一个概述的功能。代码本身的文档是回答不了这个系统是干嘛的或者这个系统用到了什么技术啊这种类型的问题。大多数情况下, 对于开发人员而言,一个简单的 README.md 就足够他快速入门的了。像项目描述,环境配置,安装,构建及打包指令这些东西对项目的新成员来说非常有用。但那之后,代码就是你的圣经。产品代码提供了所 有需要的详细信息,而测试代码则是作为产品代码的内在意图的一个描述。测试用例就是可执行的文档,而 TDD(测试驱动开发)就是实现它的最常见的方式。
假设你用了某种持续集成的方式,如果测试-文档(这里测试就是文档,文档也是测试)中有一部分不对了,这个用例会执行失败,它将会很快得到修 复。持续集成解决了测试-文档不正确的问题,不过它不能保证所有功能都是有文档的。由于这个原因(当然也有其它原因)测试-文档应当用 TDD 的方式来创建。如果在代码开发前,所有的功能都定义成测试用例,那么测试用例就能作为开发人员的一个完备的最新的文档了。
那团队的其它成员怎么办?测试人员,客户,主管,还有其它非码农呢,他们可能无法从产品和测试的代码中获取到所需要的信息。
测试人员
最常见的两种测试就是黑盒测试和白盒测试。这个区分很重要,因为它将测试人员也分成了两类,一拨是知道怎么写代码的,至少是能读懂代码的(白盒 测试),另一拨是不懂代码的(黑盒测试)。有的时候测试人员也两样都干。不过一般而言,测试都是不懂代码的,因此对开发人员有用的文档对他们来说是没意义 的。如果说要从代码中剥离出文档的话,单元测试可不是什么合适的东西。这就是 BDD(行为驱动开发,Behavior Driven Development)存在的价值了。它能为非开发人员提供所需的文档,但同时还兼备 TDD 和自动化的优点。
客户
客户需要能够给系统增加新的功能,同时他们也需要获取到关于当前系统的重要信息。给他们的文档可不能太技术了(代码当然不行),同时也得是最新 的。行为驱动开发(BDD,Behavior Driven Development)的故事和场景应该是提供这类文档的最佳方式了。它能够作为验收标准(在代码开发前),还可以反复的执行,同时还能用自然语言编 写,这使得 BDD 不仅仅能够保证文档是最新的,同时它对那些不想看代码的人来说也非常有用。
可执行的文档
文档是软件不可或缺的一部分。正如软件的其它部分一样,它也得经常进行测试,这样才能保证它是准确的并且是最新的。实现这个最有效的方法就是将 这个可执行的文档能够集成到你的持续集成系统里面。TDD 是这个方向的不二选择。从较低层面来看的话,单元测试就非常适合作为这个文档。另一方面来说的话,在功能层面来说 BDD 是一个很好的方式,它可以使用自然语言来进行描述,这保证了文档的可读性。