接口并发性能测试开发之:从测试方案设计、测试策略、指标分析到代码编写,这一篇全搞定。

2023-11-18

1. 引言

这篇是我3月份在公司内部做的技术分享内容,
由于我在公司内部分享的内容较多,以及一些特殊性,
我摘取了接口并发测试从设计思路整理→测试方案设计→设计分析→代码编写这套流程。

我不会承认我把40多页PPT的内容都放在这篇博文里

因为我不管是在内部技术分享,还是对个人的培训中,都发现:很多人并不清楚接口并发测试的整体流程,或者说,并没有参与过整个流程。
所以,我把这部分内容摘取出来,分享出来,就是为了能让大家在测试开发的道路上,越走越远!

接下来,就跟着小鱼一起,开始今天的分享,来看看接口并发性能测试的是怎样的分析流程。

听说,看到最后的大佬,技术能力都是最强的
据说,最后的彩蛋,会让你不知所措

2. 并发测试定义

目的:
是以并发为手段进行接口测试行为,通过测试行为发现接口在并发场景下导致的功能问题。

类型:
点层面上同一时间做某件事
例:早上7:30 ,所有的学生都升国旗
线层面上一个时间做不同的事,但同时对服务器产生压力
例:一个时间点,有的学生跳皮筋,有的玩足球

敲黑板:

并发与性能:并发测试不等同于性能测试,性能测试也只是并发测试的一个小类。

3. 并发测试分类

  • 1、功能并发测试
    解析:要先进行测试单业务功能场景的并发测试,在进行混合业务功能场景的并发测试。
    目的:为验证系统功能是否符合需求规格说明书的要求;

  • 2、性能并发测试
    解析:同时满足某些系统性能指标的前提下,让被测对象承担不同的工作量,以评估被测对象的最大处理能力及是否存在缺陷。
    目的:为验证系统性能指标是否符合需求规格说明书的要求;

  • 3、稳定性并发测试:
    解析:判断测试系统的长期稳定运行的能力。
    目的:为验证系统稳定性是否符合需求规格说明书的要求;

  • 4、异常性并发测试:
    解析:模拟系统在较差、异常资源配置下运行,以评估被测对象在资源不足的情况下的工作状态。
    目的:为验证系统的异常响应机制是否满足需求规格说明书的要求。

4. 设计思路整理

  • 1、需求分析
    首先找到并发测试对象,了解需求测试的功能有哪些,可以按照业务功能整理,不必深入细节。
    其次描述测试对象的重要性,如要求严格质量的核心功能、高频使用功能、占用系统资源较多的功能等。
    最后进行测试对象拆分,比如购买商品可以拆分成:搜索商品、锁定库存、提交订单、发送支付指令、接受处理支付结果、业务流水、短信及站内信通知、VX推送结果等。

  • 2、环境需求分析
    明确重点测试对象,预先设置基础数据及大量历史数据、模拟真实环境。

  • 3、性能指标需求分析
    分析性能指标是否合理。

    可以从历史数据的这几个方面考虑:TPS、页面访问量、并发请求数等,从而来判断需求指标是否合理,安排优先级。

5. 测试方案设计

1、测试策略

  • 并发测试的准备工作
    请求顺序、请求之间互相调用关系、数据流向、有没有调用外部系统等后,需要明确重点测试对象,
    预先设置基础数据及大量历史数据,模拟真实环境等。

  • 测试策略执行,一般涉及以下4个阶段

    ①对于功能并发测试:要先进行测试单业务功能场景的并发测试,在进行混合业务功能场景的并发测试
    ②对于性能并发测试:同时满足某些系统性能指标的前提下,让被测对象承担不同的工作量,以评估被测对象的最大处理能力及是否存在缺陷。
    ③对于稳定性并发测试:判断测试系统的长期稳定运行的能力。该策略强度较小,一般趋向于客户现场日常状态下的压力强度。
    ④对于异常性并发测试:模拟系统在较差、异常资源配置下运行,如人为降低系统工作环境所需要的的资源,网络带宽、系统内存、数据帧等,以评估在资源不足情况下的工作状态。

  • 总结
    不同的测试阶段,测试人员关注的测试目的也是不同。所以对测试人员来说,测试思想才是最重要,有了测试思想,才会有好的测试方案。

2、测试方案
以两轮测试为例

  • 第一轮测试,以接口文档驱动测试,测试步骤及要点如下。
    编写接口测试代码:核对每个接口传入参数控制:长度限制、格式、必填项限制、正常值范围限制等。同时,确认报错提示信息是否准确、到位;
    异常数据测试:如渠道值设置负数、属性设置不存在、网络断开、数据库锁表等情况,检查数据是否出现异常;
    逐个接口进行并发事务测试:检查账户金额,用户流水、对账流水数据。核对数据的与用例调用结果是否一致;
    复合接口并发测试:将各种充值、交易类型的接口按照一定的顺序进行并发,校验账户收支金额、流水是否与用例调用结果是否一致;

  • 第二轮测试,以业务场景驱动测试,测试步骤及要点如下。
    统一动作并发:相同订单并发支付,并发退款;
    混合交易场景:秒杀抢购,集中退货、到货确认;
    绕过页面操作:通过抓包,抛送异常值进行交易测试。

6. 指标分析

1、整理并发需求

  • 需求内容
    中午和晚上是订餐的高峰期,所以会有很大的并发订单量。为了保证订单成功率、响应速度等因素,我们要进队高峰期的订单量进行并发性能测试。

  • 性能指标需求
    ① 打开速度<3s,订单提交成功<5s;
    ②订单成功率达到99.5%以上;
    ③在100个并发用户的高峰期,订单处理能力至少达到900TPS。

2、提取性能指标
以100个外卖订单为例,需要提取的并发指标:

①并发订单数
②成功订单数
③成功订单响应时间
④订单成功率
⑤成功订单的总响应时间
⑥成功订单的平均响应时间
⑦Tps

3、性能指标分析

①并发订单数:即自定义的并发数,把并发100次,设置为10个线程,每个循环10次;

②成功订单数:就是获取响应值为成功的请求,先定义一个success_count ,初始值为0,如果成功的话执行+1;

③订单成功率:成功订单数/总的订单数成功;

④订单总响应时间:每个成功订单的响应时间之和,所以我们定义一个sum_time,初始值为0.00,然后把每次成功的响应时间加起来成功;

⑤订单平均响应时间:成功订单总响应时间/成功订单数;

⑥TPS:成功并发数/成功订单平均响应时间;

⑦订单响应时间:在请求之前,获取一次时间,在断言成功之后,再次获取一次时间,这样二者之差,就是订单的响应时间。

7. 代码实战

咱们还是老规矩,直接上代码,在代码中做分析

# -*- coding: utf-8 -*-
"""
@ auth : carl_DJ
@ time : 2021-3-6
"""

import hashlib
import threading
from time import *
from datetime import datetime,timedelta
import requests
import json


'''初始化全局变量'''

#自定义全局变量需要的线程数,10
thread_num = 10
#自定义全局变量每个线程需要循环的数量,10
one_worker_num = 10
#设定最开始的总时间
sum_time = 0.00
#设定最开始的成功连接数
success_count = 0

''' 后台登录常规操作'''

username = 'carldj'
password = hashlib.md5(b'123456').hexdigest()  #设置密码,且是md5加密方式
url = "http://www.xxx.com/energy/user/login/"
form_data = {"username":username,"password":password}
login_response = requests.post(url,data=form_data)
c = login_response.cookies

 '''订单发送请求'''

def order():
    #引用全局变量
    global c
    global sum_time
    global success_count
    #获取执行发送订单请求前时间
    t1 = time()
    #设定url、form_data进行创建订单
    url1 = "http://www.xxx.com/energy/create_order/"
    from_data1 = {"restaurant_id":1136,
                  "menu_item_total":'12.00',
                  "menu_item_data": [{'id':2667868,'p':22,'q':3}]
                  }
    make_responst = requests.post(url1,data=from_data1,cookies = c)
    #获取请求结果
    res = make_responst.text
    #结果转换成字典赋值给变量id
    id = json.loads(res)['order_id']
    #断言判断是否提交成功
    assert  id != " "
    su_time =datetime.now()+ timedelta(hours=1)
    
    #设定url、form_data进行生成订单
    url2 = "http://www.xxx.com/energy/place_order/"
    from_data2 = {"restaurant_id": id,
                  "customer_name": 'carl_dj',
                  "mobile_number":username,
                  "delivery_address":"address message",
                  "pay_type":'cash',
                  "preorder":su_time
                  }
    place_responst = requests.post(url2, data=from_data2, cookies=c)
    res = place_responst.text
    #追加断言,判断结果是否有"success",有的话,说明订餐成功
    assert res == " success"
    print("订餐成功")
    #订单成功后,再次获取一下时间
    t2 = time()
    #获取订单的响应时间
    res_time = t2-t1
    #把响应时间写入txt文件
    result = open("E:\Private Folder\res.txt","a")  #路径直接写死,也可用os.path 来写路径
    result.write("成功订单响应时间:" + str(res_time)+ '\n')
    result.close()

    #也可以使用with打开文件,好处是不用关心文件是否关闭
    # with open ("E:\Private Folder\res.txt","a") as result1:
        # print(result1.read())

    #把每次成功订单数累加到全局变量sum_time中
    sum_time  = sum_time + res_time
    #把每次获取的成功订单数做累加,添加到全局变量success_count中
    success_count = success_count +1

'''嵌套指定循环次数的order()函数'''

def working()
    global one_worker_num
    for i in range(0,one_worker_num):
        order()

 '''自定义main()函数,来执行多线程'''
def main():
    global thread_num
    #自定义一个空的数组,用来存放线程组
    threads = []
    #设置循环次数
    for i in range(thread_num):
        #将working()函数存放到线程中
        t = threading.Thread(target=working,name="T"+ str(i))
        #设定守护线程
        t.setDaemon(True)
        threads.append(t)
    #启动循环执行
    for t in threads:
        t.start()
    ##设置阻塞线程
    for t in threads:
        t.join()

if __name__ == "__main__":
    main()
    total_order = thread_num*one_worker_num
    avg_time = sum_time/success_count
    '''执行完之后,需要把数据写入到txt文件中'''
    #订单并发总数
    result.write("并发订单数:"+ str(total_order)+ "\n")
    #成功并发数
    result.write("成功并发数:"+ str(success_count) + "\n")
    #订单成功率
    result.write("订单成功率:"+ str(success_count/total_order*100)+ "%" + "\n")
    #成功订单响应时间
    result.write("成功订单总响应时间:"+ str(sum_time)+"\n")
    #成功订单平均响应时间
    result.write("成功平均响应时间:"+str(sum_time/success_count)+"\n")
    #TPS事务数/秒
    result.write("TPS:"+str(success_count/avg_time) + "\n")  #tps = 并发成功数/平均响应时间
    result.close()


8. 总结

关于并发测试,性能测试,小鱼的博文,确实不少,在这里,小鱼再重新罗列一下,
毕竟小鱼喜欢做助人为乐的事情,

我不会承认,我只看妹子的颜值

性能篇
《看过这篇《性能分析流程》后,和面试官聊天都有底气了!!!》
《性能调优怎么做,看过这一篇,菜鸟变大佬!》
《MySQL性能监控(sql命令语句 & MONyog工具)全掌握,这一篇足以!》
《深聊性能测试,从入门到放弃之:初识性能测试》
《深聊性能测试,从入门到放弃之:如何对IO进行性能调优》

性能篇之Locust

《深聊性能测试,从入门到放弃之:Locust性能自动化(一)初识Locust》
《深聊性能测试,从入门到放弃之:Locust性能自动化(二)代码实战》
《深聊性能测试,从入门到放弃之:Locust性能自动化(三)如何提高Locust性能》
《深聊性能测试,从入门到放弃之:Locust性能自动化(四)自定义客户端测试》
《深聊性能测试,从入门到放弃之:Locust性能自动化(五)API汇总整理(上)》
《深聊性能测试,从入门到放弃之:Locust性能自动化(五)API汇总整理(下)》
《深聊性能测试,从入门到放弃之:Locust性能自动化(六)自定义生成负载图形形状》
《深聊性能测试,从入门到放弃之:Locust性能自动化(七)HAR-files→locustfiles自动转换 :Transformer的使用》

并发篇
《我这样回答多线程并发,面试官非要跟我做朋友!》
《常见的并发问题有哪些都不知道,还怎么说自己是大佬!!》
《接口测试开发之:Python3,接口并发测试框架(多线程)》
《接口测试开发之:Python3,订单并发性能实战》
《接口测试开发之:一篇搞懂 Cache、Cookie及Session的爱恨情仇》

自动化篇
Web UI自动化篇(从入门到实战),清点这里
App自动化篇(从入门到实战),清点这里

爬虫篇
爬虫实战及代码讲解,请点击这里

Python开发篇
Python3 开发实战 及代码讲解,请点击这里

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

接口并发性能测试开发之:从测试方案设计、测试策略、指标分析到代码编写,这一篇全搞定。 的相关文章

随机推荐

  • nRF24L01单芯片2.4GHz收发模块射频信道频率

    框架图 管脚图 操作模式配置 射频信道频率 RF通道频率决定了 nRF24L01 使用的通道中心 该通道在 1Mbps 时占用 1MHz 带宽 在 2Mbps 时占用 2MHz 带宽 nRF24L01 可以在 2 400GHz 到 2 52
  • poll()函数详解

    poll提供的功能与select类似 不过在处理流设备时 它能够提供额外的信息 include
  • 测试流程简述

    测试流程 整体流程如下 需求评审 功能需求 性能需求 接口需求 测试计划 测试用例 用例评审 测试环境搭建 平台 架构 web服务器 数据库 执行用例 缺陷记录 缺陷跟踪和回归测试 测试报告 测试计划 测试计划 描述了要进行的测试活动的范围
  • 第八站:JavaScript的数据类型、运算符、流程控制语句

    第八站 JavaScript的数据类型 运算符 流程控制语句 欢迎来到第八站 JavaScript的数据类型 运算符 流程控制语句 在这一站 我们将深入探索JavaScript中的核心概念 为你揭示这个语言的奇妙之处 准备好继续冒险了吗 让
  • linux安装datax

    1 创建文件夹 存放安装包 cd opt mkdir datax cd datax 2 下载安装包 wget http datax opensource oss cn hangzhou aliyuncs com datax tar gz 3
  • 流程引擎是什么?有什么作用?

    编者按 本文详细论述了流程引擎的概念 流程引擎的作用以及选型的要旨 并介绍了自主研发具有中国特色的流程引擎 关键词 流程引擎 集成性 数据分析 BPMN2 0规范 中国特色 流程审批 自主研发 流程引擎是什么 流程引擎 用来驱动业务按照设定
  • Python基础语法(函数式编程)

    目录 实例1 温度转换 实例2 蟒蛇绘制 模块1 turtle库 基本图形绘制 基本数据类型 1 整数 浮点数 复数 1 整数 2 浮点数 3 复数 4 数值运算操作符 实例3 天天向上的力量 2 字符串 模块2 time库 时间的基本处理
  • SpringCloud文件上传

    2 实现图片上传 刚才的新增实现中 我们并没有上传图片 接下来我们一起完成图片上传逻辑 文件的上传并不只是在品牌管理中有需求 以后的其它服务也可能需要 因此我们创建一个独立的微服务 专门处理各种上传 2 1 搭建项目 2 1 1 创建Spr
  • Android:播放UDP流例如udp://@239.0.0.3:8218

    成功实现播放udp github下载 求大佬们给个star GitHub YangWenlong71 udpplayer 基于ijk重新编译 未做删减几乎全能的安卓视频播放器 支持播放UDP https http 等 分割线 研究思路及结果
  • Django(17):Cookie 和 Session

    目录 Cookie 什么是Cookie Django使用Cookie Cookie使用示例 session 什么是session Django使用session Session使用示例 小结 HTTP协议本身是 无状态 的 在一次请求和下一
  • Flutter——头像上传功能,实现照片选择及裁剪

    使用两个开发库 image picker和image crop 前者用来拍照或者从相册选择照片 后者用来裁剪 结果均为File类型 裁剪完成后可以直接上传文件 先写到这儿 有时间上代码 更新 实现的功能是点击头像图片 弹出选择框 选择拍照或
  • C# 流程图完整功能,矩形,菱形圆,三角形,直线,折线,放大,滚动条,保存等等功能(附下载链接)

    C 流程图完整功能 矩形 菱形圆 三角形 直线 折线 放大 滚动条 保存等等功能 点我下载项目源码 流程图具体功能如下 连接时图形有线帽 部分动漫展示 public virtual void Draw Graphics gr canvas
  • 51虚拟安卓系统v1.1.0.6-安卓端的虚拟机(支持root,xposed框架)

    应用名称 51虚拟安卓系统 应用包名 com f1player 应用版本 1 1 0 6 应用大小 266 87M 下载地址 链接 https pan baidu com s 1N9YWIafoI575GfKvtHkd3A 提取码 qnr2
  • Ubuntu系统中如何进行屏幕截图

    前言 我的环境是双系统 ubuntu20 04 但应该无论是什么版本的ubuntu都可以实现 方法 1 快捷键截图 在设置里找到键盘快捷键 找到截图目录 就可以看到有关截图的快捷键 可以自己手动更改 单击选项即可 一般使用shift pri
  • 【C++编程技巧】根据字符串中的指定字符作为分界将字符串拆分

    在C 中可以用split 函数方便的实现字符串的拆分 在C 中没有类似的函数 用strtok函数进行完成字符串分割 原型 char strtok char str const char delim 功能 分解字符串为一组字符串 参数说明 s
  • JAVA中的JeeSite框架基本简介

    JAVA的主流框架是很多的 每一个框架都有它的适用项目和条件 所有JAVA程序员都熟悉的肯定是常用的四大框架 而JeeSite这个框架使用的人却不是很多 但是这个框架却有它的独到之处 稳定 高效 调用方便 这里对JeeSite做一个简单的介
  • kill掉僵尸进程的方法(kill -9 <PPID>)

    ps A ostat ppid pid cmd grep e Zz 先用以上bash命令找到僵尸进程 Z右边第一列为PPID 第二列为PID kill 9 PPID 即PID对应的父进程即可 kill 9
  • 从TP、FP、TN、FN到ROC曲线、miss rate、行人检测评估

    从TP FP TN FN到ROC曲线 miss rate 行人检测评估 update 2018年1月31日22 21 56 最初版本是基于行人检测Piotr Dollar大佬的论文和代码胡乱写的 难免有错 严谨的paper请参考 The R
  • “不完全类型”指在C++中有声明但又没有定义的类型。

    用delete删除一个只有声明但无定义的类型的指针 是危险的 这通常导致无法调用析构函数 包括对象本身的析构函数 成员 基类的析构函数 从而泄露资源 示例代码 引用 class C 在另一个cpp文件中定义 C createC 在另一个cp
  • 接口并发性能测试开发之:从测试方案设计、测试策略、指标分析到代码编写,这一篇全搞定。

    并发接口性能设计思路与代码编写 1 引言 2 并发测试定义 3 并发测试分类 4 设计思路整理 5 测试方案设计 6 指标分析 7 代码实战 8 总结 1 引言 这篇是我3月份在公司内部做的技术分享内容 由于我在公司内部分享的内容较多 以及