微细服务体系结构的软件测试
近几年来,微服务悄然而又坚定地在拥挤的软件架构市场中占有一席之地。微服务体系结构不同于传统的单一整体体系结构,微服务体系结构并不以单体形式构建。尽管单一整体体系结构是可靠的,但其相关的问题也日益增多,尤其是当越来越多的应用采用云部署的方式时。微型服务体系结构是一种模块化结构,它不是由组件拼装而成的,而是将软件分解分散到不同的服务中,形成组件化结构。所以在微服务体系结构中,整个应用就像是一组相互独立、可部署、可扩展的服务,甚至可以灵活地编写不同的服务。另外,这种方法还可以帮助团队间并行开发。
显然,随着行业向微服务体系结构过渡,适用于单一整体架构的测试方案也需要改变。基于微服务构建的应用在功能和性能上都更加出色,微服务测试也必须覆盖所有级别以及跨级别的服务,同时还必须保持轻量级。但是,由于微服务开发在本质上是分布式的,因此相关的测试常常具有巨大的挑战,其中包括如下:
· 假如一个测试团队倾向于使用WebAPI测试工具——这种工具经常用于SOA测试,那么在微服务测试中就会产生问题。因为在微服务体系结构中,服务是由不同的团队开发的,因此要在测试时及时提供所有服务是相当困难的;
· 对于测试生命周期的不同阶段,如何确定合适的测试数量也是一个挑战;
· 在测试和数据验证中提取日志非常复杂;
· 为了实现敏捷和非集成的开发,提供专门的测试环境也是一个挑战。
MikeCohn的测试金字塔(TestingPyramid)对于测试方案开发非常有用,并且能够帮助确定需要的测试数量。基于此金字塔,在测试时采用自底向上的方法,并且考虑了各个阶段所需要的自动化工作,这将帮助解决上述问题。
单元测试:
一个单元测试的范围仅限于服务内部,它围绕一系列相关的案例进行编写。因为单元测试的数量很大,所以理论上应该以自动化的方式进行。当单元测试在一个微服务中执行时,您必须结合合作型单元测试(Sociableunittesting)和孤立型单元测试(Solitaryunittesting),它通过观察它的状态变化来检查模块的行为,并看到对象和它们的依赖之间的相互作用。但是,测试人员需要确保在单元测试中,当单元“行为”受到限制时,“实现”不受测试的限制——通过持续地将单元测试的价值与维护成本/实现受限成本进行比较,就可以做到这一点。
综合测试:
虽然独立测试模块非常重要,但是同样重要的是测试模块是否能够正确交互,并测试它们作为子系统的交互作用,看界面的缺陷,这一工作可以通过集成测试来完成。综合测试的目的是:通过综合测试模块,检验各模块是否通畅,确认模块与外部组件的交互。实施“网关集成测试”和“持续集成测试”可以确保,当发现外部组件之间的逻辑回归和缺陷时,能够迅速得到反馈,从而帮助评估个别模块所包含的逻辑是否正确。
元件测试:
微型服务中的组件测试需求:使用测试覆盖和内部API端点,通过替换外部协作组件,独立地对单个组件执行测试。组合式测试为测试人员提供了一个可控的测试环境,帮助他们从消费者的角度来引导测试,允许综合测试,增加测试的执行次数,最大限度地减少可移动部分,从而降低整体构件的复杂性。构件测试还可以确认微服务的网络配置是否正确,并且能够处理网络请求。
合同测试:
以上三个测试提供了一个高测试覆盖率,但是没有测试一个外部依赖性是否支持端对端业务流。合同测试测试了外部服务的边界,以查看服务调用的输入/输出,并测试服务是否符合合同预期。收集所有消费者契约测试结果,帮助维护者在需要时对服务做出改变(不影响消费者),并且非常有助于为新服务的定义提供支持。
两端式测试:
除测试服务外,测试人员还需要确保应用必须满足业务目标,而不论构建模式是什么,同时还要测试集成系统运行的完整性。所以,端到端测试在微服务测试方案中起着重要作用。此外,考虑到在微服务体系结构中有可移动的部分具有相同的行为,端对端测试需要确定覆盖范围,并确保在进行架构重构时业务功能不受影响。
总结:
微细粒测试必须更仔细地考虑微粒,同时避免因为过于敏感而浪费时间。为了开发一个强有力的测试方案,测试人员需要正确地定义服务,明确规定范围。鉴于软件业正倾向于微服务,测试人员可能必须在服务级别直接修改过程和测试的执行方式。通过这种方式,他们不仅能够正确地测试各个组件,还可以有更多的时间来集成应用,并提供更多的时间来进行端对端测试。