摒弃无意义的单元测试 (2)

对于数据库服务来说,在集成测试中,往往会引入H2内存数据库来模拟真实环境中的数据库服务。一般不是太特殊的SQL,都可以在H2内存数据库中运行。

对于Web Service,我暂时还没有很好的解决方案。之前有过CXF的项目经历,在测试环境中,魔改了client,从测试文件中读取XML响应体。但这么做也无法确保我们应用的对外调用参数是否输入正确。

无法保证AOP功能的正确性;

在集成测试中,整个应用服务都已经运行起来,所有AOP都是正常工作的,通过调整请求中的参数和头信息,就可以触发AOP的拦截,进而检查AOP逻辑的正确性。

重构难度大,不适合敏捷实践;

在集成测试中,所有的测试用例只在应用服务的外部检查,并不依赖内部的实现,所以如果重构时,对外的接口没有变化,无需修改测试用例,只需要完成实现的重构即可。

缺乏大局观,存在过度设计的可能;

如果我们的测试用例完整的覆盖了业务需求,那么运行过这些测试用例后,还存在着没有行覆盖到的代码,那么这些代码就是过度设计的代码,可以考虑删除或者检查测试用例是否存在缺失。

带来的挑战

集成测试可以解决很多单元测试无法解决的问题,但也会带来新的挑战:

对于卡片,要拆分为前端卡与后端卡甚至更多的有着更多技术细节的子卡。在这些子卡中,BA需要清楚地认识到,想要达成业务需求,接口的格式应该是怎样,接口调用前后的数据变化。这些技术细节可以依赖团队里的TL或Sr Dev。

这样的实践,有些传统开发中概要设计的味道。虽然很多情况下,我们不会将卡片拆至如此细的粒度,但是这么做,可以更早的意识到这张卡的依赖项,同时也可以方便QA,针对这个接口设计测试用例。

由于集成测试中的测试用例可以完全来自QA,如果这些测试用例完全来自QA,可能需要QA摸索出一条新的工作节奏。如果这些测试用例完全来自开发,QA再独立写一套,那么可能会存在重复工作的现象。如果测试用例由开发编写,再由QA审核,这可能是个好实践,但我还没有尝试过。

在后端技术栈中,我们会使用数据库版本管理工具来管理数据库版本。在Java的技术栈中,通常我们会使用Flyway。但Flyway的一个局限性是就是过度依赖SQL,这使得一些DDL可以运行在真实环境中数据库,但却无法运行在H2数据库。所以在这里,我推荐Liquibase,这个框架会对数据库的更新做出自己的抽象,可以做到一个脚本运行在多种厂商的数据库,更适合集成测试的场景。

由于集成测试要启动一个真实的容器,所以自动测试时间也会更长,构建时间也会更长,不过还是在可以接受的范围内。

重申下适用范围

尽管我这篇博客的主题是呼吁大家摒弃无意义的单元测试,但这是建立在我们所经历的大部分工作,都是针对接口的开发。在这样的工作中,单元测试有着很大的局限性,而集成测试有着更好的匹配度。

但如果你在开发一个类库,或者在DDD建模的早期,在这些场景中,单元测试才是更好的选择。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zyfygf.html