dubbo接口自动化用例性能优化

前言

去年换了一个新部门,看了下当前的自动化用例的情况,发现存在三类性能问题:

  • 本地调试运行时等待时间较长,就算是一个简单的case,执行时间都需要1分钟以上
  • 单用例执行时间比较长,部分用例执行时间超过2分钟
  • 集成到CI中运行时,执行时间较长

对于上述三个问题花时间进行了一定程度的优化,总结如下

优化本地调试时间

通过调试可以发现,一个需要执行660ms的case,在执行前的初始化工作就需要消耗约1分半钟,那么就需要思考下能否减少这部分初始化时间了。

公司用的自动化框架是基于AbstractTestNGSpringContextTests的框架。AbstractTestNGSpringContextTests是一个spring集成testNg的工具,可以通过ApplicationContext加载bean。ApplicationContext实现的默认行为就是在启动服务器时将所有bean提前进行实例化。提前实例化意味着作为初始化过程的一部分,applicationContext实例会创建并配置所有的bean。

如果是作为一个spring服务,在启动时将bean提前进行实例化,然后可以处理所有的请求,这样的做法是很合理的。但是作为本地调试,更关注是自己case运行时所需要的bean是否实例化,而不需要将所有bean进行实例化。

查阅了下spring相关文档,发现可以引入lazy-init来告诉ApplicationContext按需加载bean。
配置方式有两种:

  1. default-lazy-init参数,其配置形式如下:
    <beans?default-lazy-init="true" >?</beans>
  2. lazy-init参数,其配置形式如下:
    <bean id="stu"?lazy-init=“true”></bean>

配置完成后,运行了一下,发现并没有速度上的提升,原因是因为将大部分的bean的初始化放在了测试用例里的基类里面,导致启动时认为这些bean都需要初始化。

这说明要让lazy-init生效,提高单用例的启动速度,那就要尽可能少的使用不需要的bean,需要做一定改造:

  1. 将service/DAO初始化挪到测试用例里面。
  2. 去除不需要的多余的service/DAO。

按照上面的思路对用例进行了优化,可以将用例的初始化时间精简到30秒左右。

单用例执行时间的优化

为什么会出现很多的用例执行时间超过2分钟呢?做了一些分析和调试后,主要有几个原因:

  • 业务决定了服务之间很多是通过消息的方式进行传递,存在异步调用,所以需要等待再进行后续执行,为了用例的稳定性往往设置了过大的sleep time。
  • 一些数据准备和初始化操作不合理,无谓的耗时。

下面来看几个案例:

  1. 在beforeclass里面都会有一段初始化数据的操作,先调接口查询数据是否存在,不存在则进行初始化,导致每运行一个测试用例类都需要做一次对应操作。

    实际上这些数据初始化完后可以一直被使用,不需要多次检查,可以优化的地方是用个静态变量判断数据已初始化的话就不检查,或者将该操作设置为跑一次用例集只运行一次。
  2. 大量使用了sleep做等待,如果操作需要等待1s左右才生效,那么用sleep往往需要sleep2秒,所以sleep一般会造成50%左右的性能浪费。
    引入异步校验工具Awaitility对原有代码进行改写。

Awaitility的基本的语法为:

  • pollInterval:执行间隔
  • pollDelay:等待多久开始执行
  • atMoast:执行的超时时间
  • until()-> 执行其中的语句直到返回true或超时

这样的写法比较优雅简介,如果判断执行完成可以提前结束等待,避免时间浪费。

提高并发

当优化了单用例的运行时间后虽然对总体自动化集成测试的运行速度有一定帮助,但当用例越来越多的时候,时间也会变得无法忍受,能想到的一个办法是增加用例的并发。

用例能够并发执行的前提是用例之间具有隔离性,一个用例的执行不会影响另一个用例的执行,比如我在店铺A下单和在店铺B下单这两个用例就不会有干扰,又比如我在店铺A创建商品和我在店铺A下单也不会有影响。所以考虑用例并发的时候,需要先针对自己的业务特性进行一定程度的分组隔离。

在我们的案例中,考虑对店铺进行分组,用例并发用到的并发基本机制是testNG parallel=“tests“/class thread-count=“N"
在实际执行中,分组的实施也会有两种模式,按case的纬度还是按照类的纬度:
1.使用店铺id分组进行并发,使用group=店铺id 维度
优点:任意维度扩展
缺点:每个case需要加@group
2.把不同测试类按店铺id分组,使用package/class维度
优点:改动简单
缺点:需要每个测试类只使用一个店铺id,缺乏扩展性,需要频繁改动配置文件

最后选择了按case纬度,因为现存的用例并未很好的按店铺id进行组织,比较散乱,使用类的纬度改动较大。

使用了两个并发以后,性能提升明显。

最后

解决了一部分性能问题后,尤其是提高了用例并发以后,对用例稳定性也更高了。和开发写代码需要考虑异常和容错处理一样,测试人员在自动化设计、实施等各阶段都需要考虑用例的稳定性问题:

  • 减少外部依赖。如果执行过程需要依赖其他系统的接口的话,那么其他系统发生了变更或故障就会影响自身用例的进行。可以考虑通过预先生成的数据来替代调用外部接口生成数据在用例中使用。第三方接口的调用可以考虑mock?。
  • 预置数据代替创建过程。由于操作越多稳定性越低,使用预置数据而不是实时生成它,速度更快,稳定性更高。?
  • 使用不同维度进行隔离。通过隔离,用例执行失败的脏数据就不会影响其他用例。?
  • 调优:超时、等待时间。线上超时时间设置的比较短,测试环境的机器配置不如线上,需要适时调大超时和等待时间来保证接口调用不会超时。?
  • 防御式编程。编写测试代码时不能假设数据已存在或者没有脏数据残留,所以预先的判断和清理很重要,比如检查到数据缺失就实时修复、用例运行之前考虑清除临时数据。?
  • 定位并解决不稳定的问题。有时候偶现用例失败,可以考虑给被测应用增加日志,同时持续多次运行用例多次(如 testNg 里增加threadPoolSize=1,?invocationCount=50)来复现问题,最终解决问题。

原文地址:https://www.cnblogs.com/opama/p/12235519.html

时间: 2024-10-04 06:46:15

dubbo接口自动化用例性能优化的相关文章

接口自动化用例设计

返回结果是[{},{},{}]这种格式的,用assertNotEqual和assertIn进行判断,前提要先str一下,cases里的用例执行顺序是从上到下获取的 接口属性有两种,一种是get型的,一种是写入型的,get型的主要是获取信息,写入型的就是对数据库进行写入,修改的接口,所有项目都包含get型的和写入型的接口,get型的接口只要关注返回结果是否正常就可以,写入型的不要关注返回结果而是调用接口后去相关的数据库里取相关的字段值和你的预期结果进行校验 原文地址:https://www.cnb

robot+selenium编写web UI自动化用例

通常我们可以用robot framework写接口自动化用例,但是有些站点如果未做前后端分离,迭代过程中又有大量的重复测试工作量,没有接口可调用验证,也有自动化测试需求,怎么办?这时候,那个深坑频现的web UI自动化就势在必行了.robot只是自动化框架,好在他稳定而且扩展性极好,要想驱动web浏览器自动干活,只需要安装另外一个神器selenium,下文将提纲携领介绍web UI如何入门,一旦你入了门,其余的就是baidu和看官网帮助的工作量了,建议用到了在查,不然也没卵用. 用例编写前提:

Android UI自动化用例设计技巧

一.封装方法 1.编程如何越来越快: 首先,需要经验丰富,知识面广. 其次,每一个熟练编程的人员,都会有自己的一个库,解决各种问题.各种通用的方法函数. 同理,自动化脚本也是编程,测试用例则为需求,UI自动化编写虽然容易,但是界面变化快.维护庞大.所以封装通用方法,是最快最容易的途径. 2.哪些方法需要封装: 公共的操作方法 经常使用的步骤:超过两次以上 经常使用的组件:输入框.文本框.列表 经常操作的布局:多个组件组成通用的布局 经常操作的页面:ui页面由一个一个单独Activity组成,就可

自动化用例设计原则

1.自动化用例分3步走 初始化,输入准备 执行(方法调用),结果验证(断言) 清理环境 2.用例独立 不同的执行顺序,相同的结果 用例间没有状态共享 用例执行前的环境状态与用例执行结束后的一致 3.单一职责 一个单测用例只负责一个场景/行为 一个用例中的多个断言仅验证一个场景 如:调用api返回结果需要验证error no是否为0,error msg是否为空 一个方法,N个场景需要写N个用例 一个场景,多个方法可以写一个用例 遵循的原则就是一个场景对应一个用例 4.自描述 变量名.方法名.类名等

命令行运行Android Robotium自动化用例或单元测试用例

本文目录 1.运行所有的测试用例 2.运行单个测试类或某个TestSuite 3.运行某个测试类里面的某个测试方法 4.运行两个不同的测试类或类中的方法 命令行运行Android Robotium自动化用例或单元测试用例 1.运行所有的测试用例 举个栗子:运行测试工程下的所有用例 1 adb shell am instrument -w com.taobao.taobao.test/android.test.InstrumentationTestRunner 2.运行单个测试类或某个TestSu

自动化用例设计

用例设计部分,无论是手工测试还是自动化测试,都必须要的环节,也是非常重要的环节.在做自动化的时候,用例需要考虑前置后置.步骤和对比,每一个部分都要有提供非常明确的测试数据,要考虑数据的重复使用是否会影响脚本的执行结果. 自动化用例设计原则 1.不是所有的手工用例都要转成自动化测试用例 2.考虑到脚本开发的成本,不要选择流程太复杂的测试用例,如果有必要,可以考虑把流程拆分成多个用例来实现脚本 3.选择的用例最好可以构建成场景.例如,一个功能模块,分多个用例,多个用例使用同一个场景 4.选择的用例可

jenkins执行自动化用例(详细、有用、mark 优先级高高高)

http://blog.sina.com.cn/s/blog_68f262210102vx8o.html 第七章 测试用例接入jenkins自动运行 ------Web自动化测试之Webdriver+TestNG--从零到熟练(系列) 自动化测试用例的最终目的就是无人值守的自动化回归测试,不管是用什么语言,什么框架编写的测试用例,如果想达到这个效果,都需要借助于Jenkins或是Hudson.根据业界的习惯,我们还是使用Jenkins.在本人的各个自动化测试教程中,已经多次介绍到了Jenkins

搭建python自动化用例框架--问题

根据https://blog.csdn.net/huilan_same/article/details/76572411搭建python自动化框架过程所遇问题: 一.缺少测试套:测试套编码如下,会运行E:\Software\sichuantest\test\case目录下所有与test_*.py匹配的用例 import unittest from utils.HTMLTestRunner import HTMLTestRunner import time #注意使用套件时,在单个py文件中下的多

PageObject设计模式进行自动化用例的设计方法

关于PageObject模式进行自动化代码的编写: PageObject简而言之理解就是:一个页面作为一个类,页面中所有的元素均作为类中的方法 当然PageObject也是一种分层思想. 以Python登录163邮箱举例: BrowserDriver作为打开浏览器驱动的一个方式 Page是所有的页面组成的一个包 Testcase就是实际的测试用例 1.Page中存在一个基本的page类,所有的页面类都需要继承的类:这样写的好处就是元素一旦修改,UI界面发生变化,我仅需修改我的page就行,不影响