微服务下产品集成和集成测试框架流程(200818)
今天谈下微服务架构下的应用集成和集成测试方面的内容。在微服务架构下,由于传统的的单体应用以及拆分为多个微服务,那么原来单个系统内部的API接口调用以及变成了微服务间的外部接口调用,而且还可能已经由不同的开发团队在开发不同的微服务模块。
在这种情况下如果不能很好的进行产品应用集成和后续集成测试,那么会经常出现类似单元测试问题遗留到集成测试,端到端流程无法测试通过,测试用例和数据反复制作,集成过程中出现问题故障排查困难等诸多问题。
也正是这个原因,今天准备讲下产品集成和集成测试方面的内容,可以看到微服务下的产品集成和集成测试实际和传统组件化开发下的组件集成思路基本是一致的。当然在CMMI三级的时候我们有一个PI的过程域,该过程域也给出了产品集成的核心指导思路。
产品集成概述
大型软件产品开发一次可能开发多个新的业务系统,同时一个业务系统本身又包含多个业务模块和组件。只要在前期产品规划中存在子系统和模块的分解,那么后续就一定存在产品集成的动作。
在微服务架构设计下可以看到,我们通过传统单体应用的大拆小,形成了多个松耦合的微服务组件模块。一方面是通过分而治之降低大系统复杂度;另外一方面则是通过分解和接口定义后各模块可以并行开发。
只要架构阶段存在微服务模块拆分动作,那么最终在各模块开发完成后一定存在集成动作。
架构做出一个假设,只要在分解的时候各组件模块按预定的接口契约进行实现,那么后续各个组件一定可以进行集成和组装形成一个完整的产品。所以架构不能仅仅只关心解耦,还必须关心集成和装配。解耦后的东西无法集成,那么分解过程仍然是失败的。
在新的平台+应用,微服务+容器云平台下应用集成可以看到比常规的产品集成更加复杂,对于一个业务应用或组件首先是要考虑和平台层类似消息,缓存等技术服务能力的集成,其次才是考虑组件之间的进一步横向集成。
在这种场景下本身对应用集成的方案,策略和执行等都提出了更高的要求。
应用集成的内容
对于应用集成的内容主要分为三个方面的内容。
其一:单个微服务模块和平台层能力的持续集成和发布
对于单个微服务模块的持续集成,首先是编写好自动化编译脚本代码,如使用ant工具完成,然后设置定时作业和任务,开发人员按时check in相关代码。使用CI持续集成工具根据定时任务点在构建环境自动获取最新代码,自动运行ant自动化编译脚本对代码进行编译,编译完成后自动化部署到某个环境。部署完成后运行单元测试自动化脚本对代码进行自动化测试,输出自动化测试结果和报告;如果通过的话测试人员通过QTP进行进一步自动化测试或手工执行一遍冒烟测试脚本,完成本次持续集成。
在持续集成模式下,一方面是可以尽可能早的发现问题,一方面对测试人员随时都可以有一个可进行详细功能性测试的可用环境;其次如果对于多环境,涉及到开发环境测试通过后自动部署集成测试环境,集成测试环境测试通过后自动部署到验收环境等一系列动作。对此我们叫部署流水线模式,实现跨环境的持续集成管理。
其二:微服务两两之间上下游通过API接口服务间的服务集成
对于微服务两两间的横向集成主要是通过微服务提供的API接口服务集成,因此一方面是微服务需要和自身需要消费的提供业务服务能力的上游微服务组件集成获取输入信息和输出;一方面微服务本身也提供相应的API接口服务,需要配合下游的微服务组件进行服务集成和联调。
对于该步骤的集成重点是保证组件上下游之间能够集成通过,业务和数据能够正常流转,其集成的主要依据是组件概要设计中的服务接口设计进行。
其三:基于端到端业务场景的跨多个微服务之间的集成
在微服务两两集成通过后,接着的关键步骤就是根据端到端的业务场景进行跨多个业务组件的应用集成。确保端到端的业务流程能够在多个微服务模块协同下顺利完成。在这个阶段首先是需要保证组件两两集成通过,然后是依据相应的业务流程和业务架构文档,总体应用架构设计文档分析相应的业务场景,准备相应的业务数据进行。
在整个应用集成过程中,微服务间的集成顺序和集成场景是需要重点考虑的问题。
应用集成顺序
应用集成顺序分为两种模式:
一种是自顶向下的模式进行集成
对于自顶向下方式的集成,首先集成最外层或流程最末端的业务模块,业务模块前置依赖用模拟器(桩)实现。然后继续在每一层按宽度或深度优先,用完全实现模块代替模拟器,并建立下层。以这种方式继续直到所有被测系统中的桩已经实现和测试。在这种模式下可以看到整个集成过程完全是顶层需求驱动进行,集成工作可以较早的开始进行,如果产品集成图是正金字塔结构较容易,模拟器开发较少;反之同理。
一种是自底向上的方式进行集成
对于自底向上集成,首先集成最底层的业务模块,只在底层模块未实现前使用模拟器(桩)。然后继续在实现并测试对上一级模块,这些构件使用已经测试的下级模块。整个系统使用根一级模块测试。对于这种模式模拟器开发较少,同时上次各模块基本可以开始并行测试。这种集成方式最大的风险是如果上次需求变化可能直接影响到最底层。
应用集成的场景
集成场景分析目的是为后续的集成测试用例设计提供依据,集成测试用例要覆盖所有场景。对于场景分析输入主要包括跨模块协同业务流程图、系统需求规格说明书、概要设计说明书等。
对于集成场景分析可以从静态和动态两个层面进行分析:对于静态分析主要分析模块依赖关系,分析某一个服务接口影响到的业务模块具体功能点,可以模块-》模块的矩阵分析方法进行;对于动态分析主要是根据跨系统或模块流程入手,分析跨模块的流程协同,流程协同中所涉及到的所有接口服务。
集成场景的分析将为集成测试用例的设计提供核心输入,要明白,集成测试不是简单的接口测试,接口反映的是跨系统或模块的交互流程,需要通过交互流程的贯通来检验接口本身的正确性。
产品集成和持续集成的关系
产品集成强调是的是把左右的组件最终能够组装和集成起来,形成一个完整的系统。
Martin Fowler对持续集成是一种软件开发实践,即团队开发成员经常集成它们的工作,通常每个成员每天至少集成一次,也就意味着每天可能会发生多次集成。每次集成都通过自动化的构建(包括编译、发布、自动化测试)来验证,从而尽快地发现集成错误。
许多团队发现这个过程可以大大减少集成的问题,让团队能够更快的开发内聚的软件。可见持续集成只能算做产品集成的一个子实践。
要明白持续集成只是产品集成的一种方式,不论是开发过程是瀑布模式、增量模式还是迭代模式,都可以采用持续集成的思路。要明白持续集成的一个核心是将整个开发过程透明化,同时将集成工作提前化。尽可能早的暴露问题和风险,同时纠正在前期系统分析和架构设计中的不足。
对于持续集成我们往往会强调每日构建、冒烟测试、自动化测试等内容。
强调开发、测试和生产环境的部署流水线作业。但是要明白对于大型产品集成仍然会包括模块内测试和集成、模块间测试和集成、跨系统间的测试和集成工作。对于单个模块内可以采用每日构建和持续集成策略,但是对于模块间和跨系统我们可以采取分迭代式的集成方式进行集成。
集成测试流程
集成测试是将模块按照设计要求组装起来同时进行测试,主要目标是发现与接口有关的问题。如数据穿过接口时可能丢失;一个模块与另一个模块可能有由于疏忽的问题而造成有害影响;把子功能组合起来可能不产生预期的主功能;个别看起来是可以接受的误差可能积累到不能接受的程度;全程数据结构可能有错误等。
对于集成测试阶段的流程可以参考上图,在验收测试阶段流程和该图类似不再说明。
从该图中可以看到作为集成测试的负责方在进行集成测试执行前需要制定集成测试计划,集成测试方案和策略并联同甲方信息化管理部门和开发厂商共同进行计划和方案的评审。在方案评审通过后再开始单个业务组件的集成测试用例的设计,业务组件间的接口和服务测试用例的设计工作。
开发厂商在开发验证环境自身的单元测试通过后将形成一个稳定的可用于集成测试的版本,在这个时候可以提交集成测试申请;而对于配置管理方来说则根据提交的集成测试申请进行待测试版本的提取,并将测试版本部署到集成测试环境,成功部署完成后通知集成测试负责方进行集成测试工作。
集成测试方根据设计好的功能测试用例和接口服务测试用例开始进行业务组件的功能测试和上下游的接口服务测试工作,确保单个业务组件功能正确,和上下游业务组件之间的衔接正确。在这里重点还是集成方案中的集成顺序分析。在集成测试执行完成后输出相应的集成测试结果,如果存在相应的缺陷则打回到开发商,开发商在进行缺陷修复和自测通过后再提交第二轮的集成测试。
在多轮集成测试缺陷全部关闭后,需要在集成测试环境再进行一次回归测试。当回归测试仍然通过后可以开始输出相应的集成测试评估报告并提交评审。在集成测试评估报告和开发商,验收测试商一起评审通过后该业务组件可以开始提交验收测试,并进入详细的验收测试流程。
集成方案和策略
可以以多种方式进行集成测试,而下面是三种常用的类别:
第一种方法是由上而下的集成测试方法
首先测试和集成最高级别的模块。这使高级别的逻辑和数据流可以在过程的早期阶段测试,有助于最大限度地减少对驱动程序的需求。但是,对存根 (stub) 的需求使测试管理变得复杂,低级别的实用工具在开发周期中相对较晚的阶段测试。由上而下的集成测试的另一个缺点是不能很好地支持有限功能的早期发布。
第二种方法是由下而上的方法要求
首先测试和集成最低级别的单元。这些单元常被称为实用工具模块。通过使用这种方法,使用工具模块在开发过程的早期阶段测试,最大限度地减少了对存根 (stub) 的需求。但是,不利的方面是对驱动程序的需求使测试管理变得复杂,高级别的逻辑和数据流在晚期测试。与由上而下的方法一样,由下而上的方法也不能很好地支持有限功能的早期发布。
第三种方法(有时也称为伞形方法)测试沿功能性数据和控制流路径进行
首先,函数的输入以上面讨论的由下而上的模式集成。然后,每个函数的输出以由上而下的方式集成。这种方法的主要优点是对有限功能的早期发布的支持程度。它也有助于最大限度地减少对存根 (stub) 和驱动程序的需求。但是,这种方法的潜在缺点非常明显,因为它的系统性可能比其他两种方法低,会导致对回归测试的更大需求。
由于自顶向下的测试方式需要建立大量的技术服务和业务服务模拟器,而且底层的需求变化会对上层的业务组件模块造成较大的影响。因此对于私有云PaaS平台中应用的集成测试最好的方式还是以自底向上的模式进行,在这个过程中为了保证测试工作的尽早开始和并行,可以对少量涉及到技术服务集成的场景采用自顶向下的方式进行集成。
在整个集成测试方案策略中重点是集成依赖关系和集成顺序的分析,具体如下:
在此图中可以看到,首先需要分析业务组件模块之间的相互依赖关系,每个模块涉及到的前置依赖模块,以及和依赖模块之间需要交互的业务服务接口。基于初步的模块依赖关系分析可以开始考虑业务模块的组装和集成顺序,在集成顺序的分析中可以根据依赖关系按正向和逆向两种方式进行集成测试顺序的分析和梳理。
对于正向分析来说则是当前业务模块测试完成后可以测试哪些下游的业务模块;而对于逆向分析来说则是当前模块的前置依赖模块是哪些;如果需要测试当前模块需要首先测试哪些上游的业务组件模块等。通过这两种方式的梳理基本可以形成一个大框架的组件集成流程图。但是由于业务模块集成本身的复杂性,以上的初步集成方案和策略分析还不足够,最好的方法还是需要进一步结合业务场景尽快跨模块的业务协同分析,具体如下:
结合该图,在集成场景分析中首先是选择需要集成的业务流程,分析该业务流程中的各个业务活动以及这些业务模块之间的交互和协同点。对于这些交互点需要详细的分析业务功能以及该业务功能涉及到的业务服务接口,将这些业务服务接口全部识别出来并进行测试设计和测试数据准备。
基于以上步骤后可以有针对性的对识别出来的业务流程进行跨模块的端到端测试,在这种测试模式下虽然无法保证所有业务模块间的接口全部测试覆盖到,但是可以保证关键的业务流程实现跨模块的业务协同和贯通。
集成测试执行和评估
对于集成测试执行设计到冒烟测试、业务组件模块的功能测试、业务组件间接口服务测试、性能测试、易用性测试等多方面的内容,具体可以参考业界标准的测试方法规范体系。对于在测试执行阶段可以简要描述如下:
在集成测试执行过程中需要有相应的缺陷管理工具和平台对缺陷进行统一的管理和跟踪。如果从更加全面的工程变更角度来说,则需要有完善的需求变更、缺陷管理、版本管理、测试流程管理、发布管理等一系列的研发过程管理工具平台提供支撑。
对于测试评估则是根据需求设计文档(系统需求,产品集成方案、集成设计文档等),描述经过测试后,哪些组件接口已经实现,哪些组件接口没有实现或存在什么问题,产品对应系统需求是否通过测试,测试执行是否覆盖到所有集成测试用例。同时需要对集成测试执行结果以及因测试不充分而引起的风险进行评估,说明对系统测试的影响。集成测试评估的主要输出包括了:
- 集成测试清单和测试结果;
- 集成测试覆盖率分析:接口覆盖率,功能覆盖率;
- 测试结果统计分析:Bug分析,集成次数和成功率,遗留Bug分析;
- 测试结果评估;
- 测试结论和后续改进建议。
集成测试的其它关键点说明
通过DevOps实施来实现整个持续集成过程的自动化
持续集成和集成测试还是有很大区别,持续集成强调的是自动化的编译构建,部署,自动化的冒烟测试,保证开发过程的产出随时都可以构建一个冒烟测试通过的可用版本。而集成测试则涉及到严格的测试策略,测试方案,集成测试顺序,各个集成功能点的覆盖,详细的功能性测试等。集成测试不仅仅是接口测试,更重要的是以接口质量为前提的跨组件功能性测试。
而对于DevOps最佳实践本身就包括了持续集成的过程。
持续集成不仅仅是实现了自动化的编译,打包和部署,自动化的单元测试。更加重要的是实现了环境之间的自动化迁移。
这个能力在我们整个产品集成中相当重要。
可视化的版本部署看板实现可追溯
在产品集成整体策略下,一个核心就是对于后续类似验收测试,生产环境等都是做环境迁移,而部署重新进行版本构建。只有这样才能够保证最终测试人员测试版本的一致性。
同时根据部署流水线方式,需要建立版本部署情况追溯表。比如上图,我们可以很清楚的看到当前在每一个环境各个微服务模块处于什么版本。
集成测试执行顺序
集成测试是整个测试里面的一个完整阶段,不仅仅是包括接口集成测试,而应该是包括了功能冒烟测试,接口测试,功能性测试,非功能性测试等完整内容,具体如下:
我一直认为这是集成测试中非常关键的一个内容,集成顺序的确定涉及到前期大量的组件间依赖关系分析,业务功能点和接口对应关系分析等。特别是发展到现在,我们发现很多时候组件间不再是以前单纯的单向依赖关系,由于接口服务注册在总线上,导致多个组件间可以相互依赖,所以前面简单的组件依赖分析已经不适用,替代的方法是基于跨组件的流程协同分析,以核心流程驱动组件间的组装顺序。
同时,对于传统的自顶向下集成和自底向上集成方法往往都不能完全覆盖。很多时候采用的都会是混合集成的策略。一个是为了及早的看到集成的效果我们期望从上向下,但是却需要大量的模拟器和stub桩模块。另外一个是为了减少模拟器,我们从最底层向上集成,但是往往却将风险延迟到最后发现。