《微服务设计》,Building Microservices,作者Sam Newman,译者崔力强、张骏,人民邮电出版社,2016年。
笔记中有些内容直接引用原书。
================================================================
第七章测试
1.测试类型
面向技术的测试:单元测试、非功能性测试(响应时间、可扩展性、性能测试、安全测试)。面向业务的测试:验收测试、探索性测试(可用性测试、我如何破坏系统功能)。对于微服务,要尽可能扩大自动化测试范围。
2.测试范围
Mike Cohn的《Scrum敏捷软件开发》提出了测试金字塔,底层是单元测试,中间是服务测试,上层是用户界面测试(这里称为端到端测试)。
单元测试。通常只测试一个函数和方法调用,面向技术而不是业务,能快速反馈功能是否正常,对代码重构非常重要。
服务测试。绕开用户界面,直接对服务进行测试。需要给所有外部合作者打桩。
端到端测试。模仿用户使用的测试。
权衡。三种测试在测试范围、运行时间、反馈周期、定位范围都不同,要为不同目的选择不同测试来覆盖。
比例。好的经验:下面一层的测试的数量要比上面一层的多一个数量级。
3.实现服务测试
mock还是打桩。打桩,是指为被测服务的请求创建一些有着预设响应的打桩服务。mock,与打桩相比,mock还会进一步验证请求本身是否被正确调用,需要创建更智能的合作者。但过度使用mock会让测试变得脆弱。关于二者的权衡,可以参考弗里曼和普雷斯的书《测试驱动的面向对象软件开发》。
智能的打桩服务。Mountebank是一个打桩/mock服务器,可以避免很多重复工作。
4.端到端测试
让多个流水线扇入到一个独立的端到端测试的阶段。也就是各个服务有自己的构建、单元测试和服务测试,但没有自己的端到端测试,所有服务都共享最后的端到端测试。
5.端到端测试的缺点。有很多缺点(详见下面章节)。
6.脆弱的测试
端到端测试由于依赖太多的因素,比如其它服务、网络等等,很可能出现失败时并不是由被测的那个服务所导致的。这就导致测试变得脆弱。Martin Fowler建议当出现脆弱测试时,如果不能立即修复,就将其从测试套件中移除。另外,还可以尝试用小范围测试替代脆弱测试。
谁来写这些测试。测试由所有人来写,会导致测试用例爆炸,测试失败后,都认为是别人的问题。由专门的团队来写,开发人员远离测试代码,周期变长,并且难以理解和修复测试中的问题。好的平衡在于共享端到端测试套件的代码权,对测试套件联合负责。
测试多长时间。很多端到端测试时间很长,有的要一天,有的甚至六个星期。并行测试工具如Selenium Grid可以缓解该问题。但重要的在于权衡哪些测试需要哪些可以抛弃。这很困难。
大量的堆积。测试周期长导致部署等待时间长,部署次数少,代码变更就会不断累积。因此要尽可能频繁地发布小范围的修改。
元版本。不要追求一起部署服务,以及使用相同的版本号,这会导致失去服务单独部署的能力,并且导致服务之间的耦合。
7.测试场景,而不是故事
针对少量的核心场景进行端到端测试,避免针对庞大规模服务的端到端测试。但更好的方法可能是下面的CDC测试。
8.拯救消费者驱动的测试
CDC(Consumer-Driven Contract)消费者驱动的契约,可以不需要使用真正的消费者也能确保新的部署不会破坏给消费者的服务。CDC测试的层次与服务测试的层次一样,都在金字塔中间,但其更侧重消费者如何使用服务。
Pact。Pact是一个开源的消费者驱动的测试工具,Ruby语言开发,支持JVM和.NET版本。Pacto是另外一个工具,名字很相近。
关于沟通。CDC需要消费者和生产服务之间有良好的沟通。
9.还应该使用端到端测试吗
CDC可以替代端到端测试,但在语义监控进行生产系统监控时,还是会用到端到端测试。端到端测试可以在你需要的时候使用,比如尚未构建好CDC测试,完成后可以减少。
10.部署后再测试
区分部署和上线。部署在生产环境,在真正负载之前进行测试,有助于发现特定环境的问题。还可以使用蓝/绿部署,部署两份软件,但只有一个接受真正的请求。蓝/绿部署需要能够切换生产流量到不同的主机,需要提供足够多的主机支持两个版本部署。蓝/绿部署甚至可以做到零宕机部署。
金丝雀发布。金丝雀发布是指通过将部分生产流量引流到新部署的系统,来验证系统执行情况。与蓝/绿发布不同的是,新旧版本共存的时间更长,而且经常会调整流量。
平均修复时间(MTTR)胜过平均故障间隔时间(MTBF)。要好好考虑如何监控以及从故障中恢复过来,而不仅仅是考虑充分的测试。
11.跨功能的测试
跨功能需求(Cross-Functional Requirement, CFR)比非功能需求更好地涵盖了一个事实:这些系统行为仅仅是许多横切工作融合的结果。跨功能需求包括数据的持久性、服务的可用性、吞吐量和服务可接受的延迟等方面。CFR测试也是金字塔分层的。建议尽早去看CFR,并定期审查。
性能测试。微服务使得跨网络边界的次数增多,因此追踪延迟的根源很重要。需要一个类似生产的数据量,更多的机器。性能测试运行时间长,每次构建的时候运行性能测试并不可行。可以每天运行一个子集,每周运行一个更大的集合。还是要尽可能频繁。
12.小结
使用不同类型测试,反馈要迅速;尽量使用CDC测试来替代端到端测试;使用CDC测试提供团队之间的对话要点;在努力测试与更快地在生产环境中发现并修复问题之间找到平衡。