版权声明:此文章转载自极客头条
如需转载请联系听云College团队成员小尹 邮箱:yinhy#tingyun.com
在过去几年中,微服务悄然却坚定地在拥挤的软件架构市场上占据了一席之地。与传统单一整体式架构有所不同,微服务架构并不是将应用作为单体来构建的。虽然单一整体式架构本来是很可靠的,但相关的问题越来越多,特别是在更多应用采用云端部署的方式之后。微服务架构属于模块化的结构,它并非是由拼插在一起的组件堆成,而是将软件分解打散为不同的服务,从而形成组件化结构。因此在微服务架构中,整个应用就像一套彼此独立、可部署、可伸缩的服务,甚至为使用不同语言编写不同服务提供了灵活性。此外,这种方式也有助于跨团队间的并行开发。
很明显,随着业界转向微服务架构,适用于单一整体式架构的测试方案也需要转变。考虑到以微服务构建的应用在功能和性能上都更出众,微服务测试也必须覆盖各个层面以及层面间服务,同时还要保持轻量级。然而,由于微服务开发本质上是分布式的,相关测试也经常会有很大挑战,下面列出了其中一些:
如果测试团队倾向使用Web API测试工具——这类工具常在SOA测试中使用,在微服务测试中就会产生问题。由于在微服务架构中,各个服务由不同团队开发,想要在测试时及时提供所有服务会颇具挑战性;
在测试生命周期的各个点上,确定恰当的测试量也是一种挑战;
测试与数据验证中的提取日志十分复杂;
考虑到开发的敏捷与非集成性,提供专门的测试环境也是一种挑战。
Mike Cohn的测试金字塔(Testing Pyramid)在测试方案制定时非常有用,可以协助确定所需的测试量。根据这个金字塔,在测试时采用自下而上的方法,并将各个阶段所需的自动化工作量纳入考量,会有助于解决上面提到的那些挑战。
单元测试的范围局限在服务内部,它是围绕着一组相关联的案例编写的。由于单元测试的数量较多,理论上应当是以自动化方式执行的。在微服务中执行单元测试时,必须将协作型单元测试(Sociable unit testing)与孤立型单元测试(Solitary unit testing)相结合,通过观察其状态变化来检查模块行为,并查看对象以及其依赖项之间的交互情况。然而,测试者需要确保在单元测试中,当单元“行为”受限时,“实现”不会受到测试的限制——可以通过不断将单元测试的价值与维护成本/实现受限的成本相对比来做到这一点。
尽管单独测试模块非常重要,但测试各个模块能否正确交互,并测试其作为子系统的交互性以查看接口的缺陷也同样重要,这项工作可以通过集成测试来完成。集成测试的目的在于:通过集成模块检查路径畅通与否,来确认模块与外部组件的交互情况。执行“网关集成测试”与“持续集成测试”能确保在找到外部组件间的逻辑回归与断裂之处时迅速获得反馈,从而有助于评估各个单独模块中所含逻辑的正确性。
微服务中的组件测试要求:使用测试替代与内部API端点,通过替换外部协作的组件,独立对各个组件执行测试。组件测试提供给测试者一个受控的测试环境,并帮助他们从消费者角度引导测试,允许综合测试,提高测试的执行次数,并通过尽量减少可移动部件而降低整体构件的复杂性。组件测试也能确认微服务的网络配置是否正确,以及是否能够对网络请求进行处理。
上述三种测试对模块提供了高测试覆盖率,但并未测试到外部依赖是否支持端对端的业务流。而契约测试会测试外部服务的边界,以查看服务调用的输入/输出,并测试该服务能否符合契约预期。将所有的消费者契约测试结果集合起来,有助于维护者在需要时对服务作出变更(不影响消费者),并十分有助于在定义新服务提供支持。
除了测试服务之外,测试者还需要确保无论使用何种架构构建,应用都必须达到业务目标,同时我们还要测试集成系统运行的完整性。因此在微服务测试方案中,端对端测试占据了重要的角色。除此之外,考虑到在微服务架构中有一些执行相同行为的可移动部件,端对端测试时需要找出覆盖缺口,并确保在架构重构时业务功能不会受到影响。
微服务中的测试必须在颗粒度上更加细致,同时避免因过于敏感而浪费时间。要想制定强大的测试方案,测试者需要恰当定义服务、明确指定界限。考虑到软件行业正在向微服务倾斜,这些应用的测试者可能得在服务级别上对流程与测试的实施方式直接进行修改。这样一来,他们不仅能够正确地测试各个组件,也能在集成应用与交付优质产品时有更多时间集中精力执行端对端测试。