Joyine 2019-07-01
由于工作的原因,最近一直在研究API接口测试问题,因为前后端开发经常遇到进度不一致、信息不对称的情况,最近正在找寻能完美解决这个问题的方案。尝试寻找了一下,发现这其实是一个契约测试问题,在找到之前的一些文章,看完觉得对我理解契约测试有很大帮助,转过来记录一下。现在我已经有一些思路了,后续会专门写一篇文章来记录这部分的内容。
测试是软件流程中非常重要,不可或缺的一个环节。一般的测试分为单元测试,集成测试,端到端的手工测试,这也是构成测试金字塔的三个层级。我们今天将要讨论的话题是契约测试,它是处于单元测试和集成测试中间的一个环节。这三个层级分别测试的场景如下:
契约测试最开始的概念由Martin Fowler 提出,请参见这篇文章, 它又被称之为:消费者驱动的契约测试(Consumer Driven Contracts)。这里的契约是指软件系统中各个服务间交互的数据标准格式,更多的指消费端(client)和提供端(server)之间交互的数据接口的格式。
系统工程中存在这样的理论:线性系统(即复杂性随规模线性增长的系统)的可靠性等于组成它的各个组件的可靠性之乘积。这容易理解,因为整个系统正常工作的条件是必须每个组件都同时正常工作。
如上图所述,三个组件共同支撑的系统,如果每个组件的可靠性是90%,那么整个系统的可靠性就是 90%×90%×90%=72.9%,我们可以看到系统整体的可靠度是低于任一组件的可靠性的。如果一个系统由100个组件组成,每个组件即使能达到99%的可靠性,那么整个系统的可靠性也会降到36.6%左右。
我们常说复杂性是软件工程的最重要的特性,一个完善的软件系统必然是靠很多的子系统,组件共同撑起来的。根据上面的理论,如果是一个复杂的软件系统那么每一个组件的可靠性都对系统整体的可靠性有着非常重要的影响,排除组件本身的可靠性的因素,各个组件之间的相互依赖和调用关系也将会对系统的稳定性有着决定性的影响。随着业务的复杂度越来越高,整个系统也变得越来越庞大和错综复杂,在今天的软件工程开发中微服务已经不是一个新名词,在微服务的架构下通常一个client会与多个service相互交互,可以想象一下如果某一个服务的接口发生变化将会影响整个系统的运行。如下图展示的传统的大服务与微服务的区别。
那么在微服务模式下如果保证各个服务端与消费端之间以及服务与服务之间能够可靠的交互呢?这就回到了到我们要聊的契约测试的话题。
如下图,在服务端接口发生变化的情况下通过契约测试可以很容易的测试出契约不匹配,可以在集成测试之前就能发现问题,尽早解决。
单元测试:
集成测试:
端到端测试:
契约测试:
一般契约测试是在单元测试之后,集成测试之前要进行的,首先在保证各自功能正确的前提下测试消费者和提供者的契约是否相匹配,然后再进一步的测试功能的完备性和整个业务流的正确性。
本文主要浅显的介绍了契约测试是什么以及它的重要性,后续将会继续介绍契约测试的框架以及相关实践。