在过去的两年里,我在一些项目中使用TDD作为开发风格,但我总是陷入同样的困境:如何测试程序各个部分的集成?
我目前正在做的是为每个类编写一个测试用例(这是我的经验法则:"单元"是一个类,每个类都有一个或多个测试用例).我尝试通过使用模拟和存根来解决依赖关系,这非常有效,因为每个类都可以独立测试.经过一些编码后,所有重要的类都会进行测试 然后我使用IoC容器将它们"连接"在一起.在这里,我陷入困境:如何测试布线是否成功,对象是否按照我想要的方式进行交互?
一个例子:想想一个Web应用程序.有一个控制器类,它接受一组id,使用存储库根据这些ID获取记录,然后迭代记录并将它们作为字符串写入outfile.
为简单起见,将有三类:Controller,Repository,OutfileWriter.他们每个人都是孤立地进行测试.
我将做什么来测试"真正的"应用程序:使用数据库中的一些ID发出http请求(手动或自动),然后查看文件系统是否写入文件.当然,这个过程可以自动化,但仍然是:它不会复制测试逻辑吗?这是所谓的"集成测试"吗?在我最近阅读的关于单元测试的一本书中,在我看来,集成测试更像是一种反模式?
您所描述的确实是集成测试(或多或少)。不,它不是反模式,而是软件开发生命周期的必要组成部分。
任何相当复杂的程序都大于其各个部分的总和。因此,无论你对它进行单元测试得多么好,你仍然不太清楚整个系统是否会按预期工作。
之所以会这样,有几个方面:
*我刚刚从 Luke Hohmann 的《超越软件架构》一书中读到的一个例子:在一个应用程序中,通过创建和维护实际机器中硬件组件 ID 的“快照”来应用强大的反盗版防御,开发人员很好地覆盖了代码单元测试。然后,QA 通过在没有网卡的机器上进行尝试,在 10 分钟内成功使该应用程序崩溃。事实证明,由于开发人员在Mac上工作,他们理所当然地认为机器有一个网卡,其MAC地址可以合并到快照中......