怎么开展性能测试
什么时候开始性能测试
1.先确定需不需要做
- 客户有明确的性能需求
- 当没有明确需求时
- 如果市场用户访问量不大,时间允许就做一个基准测试,时间不允许就不做
- 市场用户量比较大,需要先跟产品,需求人员确定好性能需求,再去做对应的性能测试
2.什么时候开始做
- 未上线的新产品
- 都是在功能,接口测试完成之后。系统趋于稳定在做性能测试
- 已经上线的产品
- 系统更新(新增功能,改善功能)
- 系统扩容(扩大用户访问量,提高业务处理能力)
- 系统优化(随着时间推移,用户量增多,系统处理变慢)
- 系统修复(系统上线出现问题,功能缺陷,性能缺陷)
- 什么时候介入
- 都是在功能,接口测试完成之后。系统趋于稳定在做性能测试
- 一般测那些
- 先跑一遍基准测试 看脚本是否能通然后再去做 负载测试 压力测试 并发测试 (其他测试根据情况在做补充)
1.3.2 性能测试关注点
性能测试本身不是目的,任何一种测试类型,其核心目的都是为了发现系统存在的问题并及时修复以确保系统能够稳定运行,能够正常处理业务,能够提供给用户一个更好的使用体验,能够让客户对系统产生信心,能够成功交付运行。所以,通常情况下,我们为系统进行性能测试,主要目的是评估以下一些关注点是否满足要求
- 客户端响应时间是否满足要求?
- 服务器资源使用情况是否合理?
- 应用服务器和数据库资源使用是否合理?
- 最大访问数,最大业务处理量是多少?
- 系统可能存在的瓶颈在哪里?
- 能否支持7*24小时的业务访问?
- 架构和数据库设计是否合理?
- 内存和线程资源是否能被正常回收?
- 代码或者SQL语句是否存在性能问题?
- 如果系统出现不稳定情况,其可恢复性如何?
1.3.3 性能测试流程
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ecU97yqa-1670222852673)(https://woniumd.oss-cn-hangzhou.aliyuncs.com/test/zhangjing/20210127103934.png)]
-
分析
-
性能测试需求分析
说明:需求分析就是把真正需求搞清楚; 分析点: 响应时间 TPS 并发用户数 事务成功率 资源利用率 例如: 1). 那些功能需要进行性能测试; 2). 系统用户登录响应时间小于3秒钟; 3). 系统支持500用户并发访问; 4). 系统的日PV能达到5000个以上。 5). 对已经上线的系统,进行性能优化
-
-
设计
-
性能测试方案/计划
说明: 1). 性能测试计划是对性能测试的重要过程。 2). 在对需求文档经过认真分析后,作为性能测试管理人员,需要编写的第一份文档就是性能测试计划; 3). 性能测试计划中,需要阐述产品、项目的背景,将前期的需要测试性能需求明确,并落实到文档中。 例如: 1). 交代项目背景 2). 测试目的 3). 测试范围 4). 测试设计 5). 测试方法 6). 测试标准 7). 测试环境 8). 风险分析 9). 测试结果 10). 测试输出
-
-
实现
-
构建测试数据
说明:在进行性能测试之前,我们应该先构造假数据,尽可能的模拟真实场景 提示:自动化构建数据,获取线上用户数据,数据脱敏处理
-
设计性能测试用例
说明:性能测试需求最终要体现在性能测试用例设计中,性能测试用例应结合用户应用系统的场景,设计出相应的性能测试用例,用例应能覆盖到测试需求 提示: 1). 明确那些业务功能使用频繁; 2). 明确系统预期的用户规模、并发用户数、在线用户数; 3). 明确系统业务的处理能力要求,如:TPS、响应时间、系统资源利用率等;TPS :(Transaction per second)事务数/秒
-
设计性能测试场景
说明:测试场景的设计一个重要的原则就是依据测试用例,把测试用例设计的场景展现出来。 提示: 1). 虚拟用户数量及启动虚拟用户方式 2). 场景的相关设置(如:集合点) 3). 脚本是否存在依赖关系(登录与注册) 4). 思考时间 请求数 请求大小 是否缓存 带宽 5). 拱形(负载测试) 门型(压力测试) 复杂(模拟真实服务器访问情况,不停的在Ramp Up,Duration,Ramp Down之间切换,场景运行图象类似于高低起伏不同的波浪线。这类场景的运用较少,因为需要大量的历史数据作为支撑,通常不适用于对未上线的系统进行设计) 混合(利用上述各类场景,进而更好的模拟真实情况,比较理想的一种模型,实用价值不大。)
-
设计性能测试脚本
说明:性能测试用例编写完成以后,接下来就需要结合用例的需要,进行测试脚本的编写工作。 提示: 1). 工具选型、代码实现 2). 脚本保证其正确性,去除冗余代码; 3). 注重编码的规范和代码的编写质量;
-
-
执行
-
搭建测试环境
说明: 偷梁换柱法,指标换算法,云平台租赁
-
执行测试脚本
说明:执行测试脚本是关系到测试结果是否准确的一个重要过程。 注意事项: 1). 负载的测试机不能够运行设定的虚拟用户数; 2). 没有“预热”过程; 3). 没有模拟用户的真实环境; 4). 性能用例运行次数过少。
-
监控收集性能指标
说明:可以在场景运行时决定要监控那些数据,便于后期分析性能测试结果。 提示: 1). 应用性能测试工具的重要目的就是可以提取到本次测试关心的数据指标内容; 2). 性能测试工具利用应用服务器取得在负载过程中相关计数器的性能指标。 (计数器:计算、统计性能指标的工具) 注意: 1). 负载机的时钟要一致,保证在监控过程中的数据是同步的; 2). 尽量搜集与系统测试目标相关信息,无关内容不必进行监控; 3). 要以管理员的身份登录后
-
-
分析
-
分析性能测试数据 找到性能瓶颈
说明:性能测试执行过程中,性能测试工具搜集相关性能测试数据,待执行完成后,这些数据会存储到数据表或者其他文件中,为了定位系统性能问题,我们需要系统分析这些性能测试结果。 提示: 1). 一般使用“拐点分析”方法,利用性能计数器曲线图上的拐点进行分析的方法。(基本思想就是性能产生瓶颈的主要原因就是因为某个资源的使用达到了极限,此时表现为随着压力的增大,系统性能却出现急剧下降,就产生了“拐点”现象。)
-
性能优化回归测试
说明:性能测试分析人员经过对结果的分析以后,有可能提出系统存在性能瓶颈。 提示: 1). 调优人员(开发人员、数据库管理员、系统管理员、网络管理员、性能测试分析人员)相关人员对系统进行调整; 2). 验证-性能测试人员继续进行第二轮、第三轮……的测试,与以前的测试结果进行对比,从而确定经过调整以后系统的性能是否有提升。 注意: 系统调优由易到难的先后顺序如下: 1. 硬件问题; 2. 网络问题; 3. 应用服务器、数据库等配置问题; 4. 源代码、数据库脚本问题; 5. 系统架构问题。
-
设计测试报告
- 项目背景
- 测试目的
- 测试方法
- 测试环境
- 测试目标
- 测试数据
- 测试结论
- 测试分析
- 性能优化
- 测试时间
-
-
提交测试产物
- 测试方案
- 测试用例
- 测试脚本
- 测试报告
7. 性能测试项目实战
7.1 测试流程
7.2 woniuboss项目部署
被测系统:Woniuboss4.0;java程序
基础环境:Java运行环境,Tomcat服务器,MySQL服务器
1、部署Java运行环境【Windows/Linux系统-1.8及以上】
2、部署MySQL数据库服务器【Windows/Linux系统-5.6】
3、部署Tomcat服务器【Windows/Linux系统-8.0及以上版本】
4、Woniuboss4.0放置在Tomcat服务器的容器内webapps目录下,数据库连接配置文件配置正确,重启服务,访问浏览器页面成功即可。
5、数据库数据每次更新变动 记得文件备份!!
7.3 woniuboss项目需求分析
-
业务分析:
- 面向公司内部使用
- 用户数:公司内部员工数量 WoniuBoss 500
- 响应时间:2-5-8
- 硬件使用率 80%
- 面向互联网
- 用户数:提前预估。根据日志记录或者数据查看 用户访问量,UV ip,注册用户数
- 并发数:使用二八原则 用总PV 计算(可以根据具体应用场景得出使用时间)
- 响应时间:2-5-8
- 硬件使用率:80%
- 面向公司内部使用
-
指标提取
- CPU
- 内存
- 磁盘
- 网络
- RT
- ERROR
- TPS
-
性能测试计划及方案编写
- 交代背景
- 测试目的
- 测试范围(测得业务模块 对象)
- 测试环境(服务器 数据库 数据)
- 测试方法(工具 业务建模 )
- 测试输出(输出的内容 形式)
- 测试计划(人员安排 分工)
- 测试风险分析(预期可能存在的时间风险 性能风险 脚本制作风险 及其他 以及对应解决方案)
-
案例分享
-
https://baijiahao.baidu.com/s?id=1665290298711964701&wfr=spider&for=pc--银行容量测试 https://max.book118.com/html/2019/0625/7142125163002034.shtm金融行业性能测试 https://www.jianshu.com/p/c2119fa675e9电商行业性能测试
-
7.4 数据提前预埋
1. 直接使用生产环境的数据(简单但需要脱敏)
2. 自己写脚本生成
"""
@author: ZJ
@email: 1576094876@qq.com
@File : adddata.py
@desc: 添加woniuboss的测试数据
@Created on: 2021/6/24 14:09
"""
### 使用request去模拟发送请求 生成数据
import random
import requests
from faker import Faker
url = "http://192.168.1.105:8080/WoniuBoss4.0/employee/addEmp" # 新增员工接口地址
#
fake=Faker("zh-CN") # 实例化中文对象 使用该对象产生中文数据
# # print(dir(fake)) # 可以查看 faker都能生成哪些规则的数据
header={"Content-Type":"application/x-www-form-urlencoded; charset=UTF-8",
"Cookie":"JSESSIONID=3af6bac4-c97f-4100-a136-797fc9341697; rememberMe=CtezVFzOfV6ZqwXS1L5wdFfV+EXTKP/K5GQax82SICaBzbc3UFKGa0m4TGCaQx0x/fDCaNcf5vWmUC0ZNGLITCV1O/du7Q6+dxFoOSS0lc0hUU8I4H7G/bjXukRZd9tP7gO9tHK1eBiiBwb9lzthB1eBG1Z86MAVB6kagh2+3UnBqQdaEh9jMa3TDNva7J8q+W5QHTewFixsZEJRvjRBcIVTCPPgt4LFBcf6Cb6arHHZFUVXXXD0pDyhTCQ4soPQUhfQyb6mO93lTe5Im1H6748ihCvGs/y5vv4v8lu8mrFULtKHwD3xW/+RFibteztVZM96GhvsDExVjD0UZPe/550AkEp8reKNhGYPK3Zvu4Y9pmkUPFv5G4ZvWOCNRv2XEwS/hzc8sG9ehOwIo8RCd+UCOKl210rQixL2hoddvQ6h27pUG4NTBT/DMDn7k5ntogVl9jDV68/N0enKvstfVyp1J0HcfJFDlVnOPz6ZODXjcRmy/lqqZgR9gKW6UnKr; _jfinal_captcha=b8948910934b4988a961b0981948d33e"
}
"""
300个员工
员工占比 教学部:咨询部:就业部:其他 14:5:2:1
员工实际人数 教学部:咨询部:就业部:其他 190:60:30:20
"""
for i in range(1,301):
if i <=2:
department_id = 1
position="管理专员"
elif i<=32:
department_id = 2
position="就业专员"
elif i<=34:
department_id = 4
position="电销专员"
elif i<=37:
department_id = 5
position="渠道专员"
elif i<=40:
department_id = 6
position="市场专员"
elif i<=45:
department_id = 8
position="研发"
elif i<=50:
department_id = 9
position="财务"
elif i<=110:
department_id = 3
position="咨询专员"
elif i<=300:
department_id = 7
position="讲师"
employee_name = "WNCD"+"{:0>3d}".format(i)
tel =fake.phone_number()
ssn = fake.ssn()
data ={
'emp.region_id': 1, # 获取区域id
'emp.department_id': department_id, # 按照权重随机分配一个部门
'emp.position': position, # 职位默认为不填
'emp.employee_name': employee_name,
'emp.sex': random.choice(["男","女"]),
'emp.entry_time': str(fake.date_between(start_date="-6y")), # 生成随机的入职日期
'emp.tel': tel , # # 生成随机的手机号
'emp.email': tel+"@qq.com",
'emp.qq': tel,
'emp.education': random.choice(['01','02','03']),
'emp.university':"",
"emp.major": "fake.job()",
'emp.address': "成都",
'emp.source': fake.address(),
'emp.cardnum':fake.credit_card_number(),# 生成随机信用卡号
'emp.identity': ssn, # 身份证号
'emp.birthday': ssn[6:10]+"-"+ssn[10:12]+"-"+ssn[12:14],
'emp.birthday_type': '01',
'emp.emergency_contact':'',
'emp.emergency_tel':'',
'emp.emegency_relation':'',
'emp.work_id': employee_name
}
print(data)
# 插入数据
requests.post(url,headers=header,data=data)
3. 直接执行sql
sql可以查看源码得出 也可以查看日志得出 更推荐直接让开发去写
###使用pymysql 连接数据库 直接执行sql语句生成数据
from interface.Common.db import DB
db = DB("woniuboss",host="192.168.1.105" )
# #
for i in range(241,301): # 设置咨询师的权限
sql = f"delete from system_user_role where user_id= {i}"
db.writeDB(sql)
sql = f"insert into system_user_role (user_id,role_id) values ({i},13),({i},17),({i},24)"
print(sql)
res = db.writeDB(sql)
print(res)
#
for i in range(301,491): # 设置老师的权限
sql = f"delete from system_user_role where user_id= {i}"
db.writeDB(sql)
sql = f"insert into system_user_role (user_id,role_id) values({i},14),({i},17)"
print(sql)
res = db.writeDB(sql)
print(res)
# 针对 咨询主管及教学主管这种比较特殊的 可以自己在页面单独设置
import datetime
#
now_time = datetime.datetime(2021, 1, 10, 16, 12, 51, 252814) # 设置第一个班级的开班时间
for i in range(1, 61): # 添加班级
# class_headmaster_id 班主任id 对应的班主任在员工表的id
str_time = now_time.strftime("%Y-%m-%d")
class_no = "WNCDT" + "{:0>3d}".format(i)
class_headmaster_id = 51 + i # 咨询师在员工表对应的id
sql = f"insert into `class`(`orientation`, `class_headmaster_id`, `create_time`, `opening_time`, `region_id`, `class_no`, `opening_status`) " \
f"values('测试',{class_headmaster_id}, '{str_time}', '{str_time}', 1, '{class_no}', '02')"
res = db.writeDB(sql)
print(res)
now_time += datetime.timedelta(days=+15) # 每隔多少天开班
4. 使用工具生成
咨询师场景(使用jmeter模拟请求新建学生数据)
系统 50个咨询师 持续操作100次 新增50个学生信息 每次新增学生信息 有三分之一的概率将学生报名 并随机分配到任一班级 (流程 新增资源—->跟踪资源 状态设为已报名)
7.5 场景设计
场景设计原则
1、主业务流程
2、操作比较频繁的功能
3、使用用户比较多的功能
4、数据量比较大的功能
5、有需求的,按需求来做
6、负载测试模型—拱型场景;压力测试—检测系统的稳定性(压力下系统是否会error)—门型场景
WoniuBoss脚本功能实现
- 每个业务场景登陆仅登陆一次
- 咨询部 (咨询师登陆后 会按照概率随机触发某个事件)
- 10%概率点击报表中心(报表中心中的每个报表概率一致)
- 40%概率点击资源管理 ,新增简历资源,30%概率会将该资源转化为报名状态并随机分班
- 20%概率点击学员管理下的学员信息
- 10%概率点击 首页(main)
要求:请加上述操作用jmeter脚本实现 并且每个操作用事务表示
基于上述脚本 修改 模拟负载测试 并分析图形指标
预计启动共50个用户数。初始构建5个咨询师用户进行操作120秒 然后在构建5个 在持续进行操作120秒 直到线程数变为50 持续运行180s后退出脚本
7.6 性能测试脚本开发
7.7 执行性能测试并收集数据
性能监控的实现原理:
在服务器搭建收集器 进行指标收集 然后通过工具进行绘图 (数据采集——>数据渲染)
- 实时监控
- ServerAgent
- 离线传输
- 监控平台
- 现在基本云平台都实现了监控平台
- 监控平台本质比上述操作多了个 数据收集过程
- 优点:准确性高 时效性好 可视化高 会有历史记录 警告通知
我们在 做性能指标监控时 每次的数据都要收集好保存截图 后期需要贴在报告中
7.8 性能测试结果分析
负载测试:随着时间的变化,虚拟用户数逐渐增加时,响应时间开始趋于平稳;遇到瓶颈时响应时间有明显增加的趋势;TPS,throughput,开始趋势上升;遇到瓶颈时有明显下滑趋势;资源利用率,开始趋于上升;遇到瓶颈趋于资源饱和(90%)
压力测试:最大用户数,长时间运行,何时出现瓶颈,表现出来何种症状-
资源利用率高负荷;响应时间巨长;数据库连接数太多;有没有错误率;内存溢出;
补充:
top -Hp pid 可以查看该进程下各个线程的cpu使用情况
通过top命令定位到cpu占用率较高的线程之后,继续使用jstack pid命令可以查看当前java进程的堆栈状态 找dead_locked (线程死锁)
https://www.cnblogs.com/wuchanming/p/7766994.html
监控日志:outoffmemory(内存溢出)
监控内存(内存超过100%):outoffmemory(内存溢出)
mysql有无索引 是否慢查询
后端代码是否优化 返回值内容大小是否优化
前端是否优化
应用软件配置是否优化:
tomcat配置优化:jvm参数配置,tomcat线程数配置
数据库配置优化:数据库查询缓存
是否分布式
tomcat分布式配置:增加nginx代理
mysql分布式 读写分离 主从同步 分库分表 表结构是否冗余
服务拆分
前后端分离 动静分离,静态文件部署到nginx,tomcat只管动态
微服务:把一个大的功能很多的应用拆分成很多个小的功能单一的应用
使用其他中间件
redis:缓存,缓存读写速度远高于硬盘读写速度
mq:消息队列,削峰填谷
7.9 性能测试报告编写
意义:
性能测试报告是一个性能测试完成的里程碑,是整个性能测试环节的总结性工作。也是给甲方给老板给同事的一份交付
性能测试报告与功能测试报告的本质一样,记录测试过程(测试环境,数据准备,场景设计,各项性能指标的结果分析,性能测试结论—并非简单意义上的通过与不通过,而是一种评估结果反馈。),目的是为了作为性能测试依据的参考,是否需要调优还是修复性能缺陷?
负载测试:确定系统的最大和最佳用户数,TPS,吞吐量,资源利用率?逐个分析不同负载情况下的性能状况
压力测试:高负载下,系统的性能表现,是否会出现ERROR。是否做出何种预案?
报告中需要交代
- 测试背景
- 测试目标
- 测试目的
- 环境介绍(服务器的硬件和软件,测试工具,网络环境,测试人员 很重要必须要有)
- 测试方法(用了什么工具,场景的设计,业务建模)
- 测试脚本
- 测试数据(虚拟用户数,tps,响应时间,cpu和内存等截图)
- 测试分析(哪个请求慢,可能的原因是什么,优化的方案)
- 性能优化
- 回归记录(数据对比)
7.9 性能测试报告编写
意义:
性能测试报告是一个性能测试完成的里程碑,是整个性能测试环节的总结性工作。也是给甲方给老板给同事的一份交付
性能测试报告与功能测试报告的本质一样,记录测试过程(测试环境,数据准备,场景设计,各项性能指标的结果分析,性能测试结论—并非简单意义上的通过与不通过,而是一种评估结果反馈。),目的是为了作为性能测试依据的参考,是否需要调优还是修复性能缺陷?
负载测试:确定系统的最大和最佳用户数,TPS,吞吐量,资源利用率?逐个分析不同负载情况下的性能状况
压力测试:高负载下,系统的性能表现,是否会出现ERROR。是否做出何种预案?
报告中需要交代
- 测试背景
- 测试目标
- 测试目的
- 环境介绍(服务器的硬件和软件,测试工具,网络环境,测试人员 很重要必须要有)
- 测试方法(用了什么工具,场景的设计,业务建模)
- 测试脚本
- 测试数据(虚拟用户数,tps,响应时间,cpu和内存等截图)
- 测试分析(哪个请求慢,可能的原因是什么,优化的方案)
- 性能优化
- 回归记录(数据对比)
- 测试结论(建议环境 可能存在的瓶颈)