当前位置: 首页 > 科技观察

如何编写有效的接口测试?

时间:2023-03-14 20:50:57 科技观察

在所有的开发测试中,接口测试是必不可少的项目。有效而完整的接口测试不仅可以保证新功能的开发质量,还可以让开发在修改功能逻辑时有返回的能力,也是优雅重构的前提。编写接口测试应该遵循哪些原则?测试代码的结构应该是怎样的?接口测试有哪些实用技巧?本文分享作者对接口测试的实战总结。一线开发的同学可能或多或少有过导致线上bug甚至失败的经历;他们也会遇到这样的场景,一个同学在开发某个功能的时候重构了代码,导致线上bug或者失败;到了某个功能,发现需要修改公共逻辑,怕影响其他功能,所以把代码抄得很不好看,重写了一个单独的逻辑来支持。以上情况都包含一个关键问题,无论是功能开发还是逻辑重构,如何保证代码开发的质量。保证的手段,众所周知,就是检测。首先是新功能测试,确保新功能逻辑正确;二是回归测试,保证原有业务功能逻辑正确。测试的方式一般有两种,手动测试和自动化测试。随着测试技术和工具的不断发展,人工测试的比例逐渐降低,逐渐被自动化测试所取代。自动化测试是可持续和可重复的,甚至支持人工智能。Atestlayered测试也是分层的,如下图所示:在一个系统中,自动化测试一般分为单元测试、模块测试和接口测试。单元测试目前我的应用代码基本都是基于spring框架的面向接口的编程模型,单元测试被弱化了。单元测试的需求基本上是对单个类的单个方法的测试。我们现在的模式,写的成本太高了。当然,如果是一个工具或者一个比较内聚复杂的逻辑(比如算法逻辑),还是要通过单元测试来保证逻辑的正确性。模块测试当系统比较大,模块较多时,可以建立一个模块测试层,保证各个模块功能的正确性。但是现在的系统发展趋势是微服务架构,所以模块测试层不是很有必要,可以被接口测试层覆盖。接口测试个人认为准确的说应该叫入口测试。这一层是从系统入口开始的集成测试。应用入口通常是HSF(一种分布式RPC服务框架)服务、消息、定时任务。作为一个开发,测试方法有上万种,接口测试是少不了的。当我们应用的接口测试有效,覆盖完成后,不仅可以保证我们新功能的开发质量,还可以让我们在修改功能逻辑时具备返回的能力。同时,这也是我们进行代码重构的前提。同时,可测试性也是代码结构是否合理的一个指标。如果发现一段代码难以编写测试脚本或无法测试,则说明当前代码结构不合理,需要重构。接下来主要说一下接口测试的有效性。测试原则的两个基本原则:自动化:接口测试是非交互式的,自动执行,无需人工参与。独立性:接口测试不应相互依赖。可重复:接口测试可以重复进行,不受环境影响。接口测试遵循BCDE原则,保证接口交付质量。边界:边界测试。正确:正确的输入,正确的预期输出。设计:根据需求和设计文档编写测试逻辑。错误:错误的输入,预期的输出。数据准备:数据准备是通过系统服务进行的,而不是直接插入db。可测试性:不可测试的代码需要重组为合理的结构。覆盖:接口测试需要覆盖所有的UC。同时,代码覆盖率和分支覆盖率要达到一定的标准,必须覆盖新的代码。连续性:如果代码修改导致现有接口测试失败,则必须修复代码问题或测试代码逻辑。时间要求:接口测试应在项目发布前完成,项目发布后不得再添加。以上基本原则应该适用于所有层次的自动化测试用例。在编写接口测试时,除了上述原则外,还需要遵循其他原则。先看一张图:从系统的角度来分析入口调用,以HSF服务为例:一个外围系统调用了我们系统提供的一个服务。系统执行一堆代码逻辑,其中包括分支逻辑。系统执行过程中,依赖外部HSF服务,进行调用,获取返回值。系统执行过程中,依赖DB查询或登陆数据,依赖缓存查询或登陆数据。在系统执行期间向外部发送消息。将HSF执行结果返回给上游系统。有效接口测试的关键原则是覆盖所有入口,mock所有依赖,验证执行过程中留下的痕迹。总结如下:入口覆盖:接口测试用例必须覆盖HSF服务入口、消息入口、定时任务入口。依赖mock:基本原则中有可重复性原则,即接口测试不能依赖环境,需要mock外部依赖。但是,对于数据库依赖,不建议完全模拟它们。一方面mocking成本高,另一方面SQL和表约束逻辑可能覆盖不了。完整验证:有效的接口测试应该有完整的验证,没有验证的接口测试是没有意义的。只要执行过程中留下的痕迹对业务有影响,就必须进行完整的验证,以保证接口测试的有效性。HSF接口返回值校验:根据场景和接口约定进行HSF返回参数校验。DB验证:验证登陆数据的正确性。缓存验证:验证缓存中存储的数据的正确性。HSF依赖入参校验:通过mock工具获取依赖HSF调用的入参,进行入参校验。消息校验:通过mock工具获取发送的消息对象,进行消息体校验。三测试代码结构在编写测试代码时,还应该像编写业务代码一样,考虑代码的可读性、可扩展性和可重用性。同时,可以根据系统的业务特点,在测试框架的基础上,封装适合当前系统的测试组件,提高测试代码编写效率,规范测试代码结构。一个接口的测试代码一般结构如下:1.测试准备依赖数据准备很多时候,我们的测试依赖数据,可能是配置数据,也可能是业务数据(比如退款需要依赖支付数据)).配置数据:可以通过定义配置文件来初始化配置。业务数据:这类数据不应该是直接插入数据生成的,而应该是调用业务服务生成的。Dependencymock对于外部依赖,需要对依赖的服务进行mock,避免真正的调用。准备接口测试的输入参数准备接口的输入参数。2测试执行调用接口方法执行业务逻辑。3测试验证返回参数验证:验证接口的返回参数。DB:校验DB的登陆数据。缓存数据验证:验证登陆缓存的数据。消息校验:校验对外发送的消息对象。外部HSF调用验证:验证外部HSF调用的输入参数。四大实用技巧1执行效率对于接口测试来说,执行效率是一个不得不关注的点。如果一个接口测试执行超过3分钟才能看到结果,会大大降低开发者编写接口测试的积极性。为了提高测试执行效率,推荐的解决方案是:最小化启动测试上下文,比如应用springboot,启动spring。使用内存数据库,例如h2。mock掉中间件依赖2.测试框架选择测试框架推荐选择基于testng的,它可以通过配置文件提供数据准备的测试框架。如果找不到合适的,可以基于testng自己打包。3接口测试覆盖场景的完整性影响测试用例的覆盖率。一方面,开发者需要根据业务场景的输入和测试经验,枚举正常和异常的情况。另一方面,接口方法也有一些固定点需要测试,如幂等测试、边界值测试、参数不正确测试等。同时使用覆盖工具查看接口未覆盖的代码或分支逻辑,进行有针对性的场景覆盖测试。以我的经验,完整的分支覆盖非常重要,尤其是不寻常的分支。五、小结为保证系统稳定在线运行,质量保证手段必不可少。虽然自动化保障手段很多,但接口测试仍然是最基本也是最重要的保障手段之一。如果能够持续保证接口测试的覆盖率和有效性,线上BUG的发生将大大减少,开发人员重构代码的动力也会更大。