黑羽压测 功能说明
登录
我们做性能测试的时候,模拟的用户使用场景经常需要登录,才能进行后续http请求。
这样的情况下用 黑羽压测 怎么模拟呢?
这个,要看被测系统的用户认证机制。
典型的有下面两种机制。
cookie session 机制
如果 被测系统 使用的是 传统的 session机制。 登录后,服务端会在响应消息的cookie中存入sessionid。客户端后续的请求必须在cookie头中携带sessionid。
这种机制 在 白月黑羽教程中有 详细解释 ,可以参考这里
黑羽压测 的客户端 会 自动保存
服务端返回 的所有cookie,并且会在后续请求中携带上。
所以,对于Cookie session 的登录认证机制,非常简单,不需要我们做任何特别的设置。
下面提供了一个示例:
# 创建客户端
client = HttpClient('127.0.0.1', # 目标地址:端口
timeout=10 # 超时时间,单位秒)
# 登录, 成功后的cookie会自动保存在client对象里
response = client.post(
"/api/mgr/signin",
data={
'username':'byhy',
'password':'88888888'
})
# 后续请求自动携带cookie里面的sessionid
response = client.get(
"/api/path1",
)
token机制
如果 被测系统 使用的是 token 机制。 登录后,服务端通常会在响应消息头 中存入token。客户端后续的请求必须在指定头中携带token。
黑羽压测 可以方便的从 响应消息中提取 内容, 并且在后续请求消息中存入。
下面提供了一个示例:
# 创建客户端
client = HttpClient('127.0.0.1', # 目标地址:端口
timeout=10 # 超时时间,单位秒
)
# 登录, 成功后,token通常在响应消息的消息头中
# 本例中,token所在的消息头名为 jwt
response = client.post(
"/api/mgr/signin",
data={
'username':'byhy',
'password':'88888888'
})
# 获取消息头jwt值
jwt = response.getheader('jwt')
# 后续发送请求,需要在消息头jwt中携带响应中的值
response = client.get(
"/api/path1",
# 消息头写在下面字典中
headers={
'jwt':jwt
})
检查响应中的数据
性能测试,我们不能只是检查是否收到了响应就行了。
我们还需要检查响应消息对不对。
要检查HTTP响应消息是否正确,就是检查 各个部分
是否正确,比如状态码、响应消息头、消息体等等。
这些 黑羽压测 有响应的自动代码生成条目, 如下
比如,你要检查响应消息的状态码,如下图箭头处,点击 查看响应状态码
会自动产生 代码行
print(f"响应状态码为 {response.status} ")
我们就知道了 response.status 就是从响应中获取状态码的。
所以我们就可以写出如下代码
# 创建客户端
client = HttpClient('127.0.0.1',
timeout=10
)
# 发送请求
response = client.get("/api/mgr/signin")
# 检查状态码,必须是200
if (response.status != 200):
print('状态码不是200,本次操作无法继续')
# 汇报错误,加入统计结果中
Stats.oneError()
# 日志写入详细信息,方便性能测试定位问题
TestLogger.write('/api/mgr/signin error')
# 后续代码
特别要注意 这两行 代码:
# 汇报错误,加入统计结果中
Stats.oneError()
# 日志写入详细信息,方便性能测试定位问题
TestLogger.write('/api/mgr/signin error')
黑羽压测代码 检查到 服务端响应数据 有错,就应该记录下来。
Stats.oneError()
是告诉黑羽压测控制台,有错误,这样会在统计图里面显示出一个错误统计。
TestLogger.write()
是立即把错误信息写入测试日志中(日志文件在项目目录的log文件夹中)。
写日志功能 非常有用
:
-
可以方便开发人员定位问题
比如 出现错误时,可以写入详细的错误信息,请求消息的sessionid号, 对应的用户id,设备号等。
这样开发人员就可以根据 日志中的信息 定位产品的问题。
-
还可以灵活的添加统计信息,实现各种特殊的需求
比如,要统计整个测试过程中 响应时长 的各种范围,以及各范围内 API请求数量和对应的用户
就可以自行添加如下代码:
response = client.get("/api/mgr/signin") rt = response.responseTime # 获取响应时长 if rt > 1000: # 大于1秒 TestLogger.write(f'API list_order >1s|{username}') elif rt > 500: # 大于0.5秒 TestLogger.write(f'API list_order >0.5s|{username}') elif rt > 100: # 大于0.1秒 TestLogger.write(f'API list_order >0.1s|{username}') elif rt > 50: # 大于0.05秒 TestLogger.write(f'API list_order >0.05s|{username}')
在测试结束后, 分析测试日志,即可得知。
怎么分析日志? 写Python程序啊,数据文件分析是Python最擅长的了,请看白月黑羽Python基础教程
前后消息数据关联
模拟性能测试的过程中,经常需要将 前面一个响应消息的一些数据 进行处理传入到后续的请求中。
比如,一个API消息 /getopcode ,响应消息体是 json格式,如下
{
"opcode" : "25ea6534y6sdef"
}
下一条 API 消息 /bugdevice, 是 json格式的消息体,如下,
{
"opcode-md5" : "3223sdfsdf23202304",
"action" : 'bug_sword'
}
其中 opcode-md5 是 前面返回的 opcode值的md5结果。
该怎么办呢?
同样,如下图所示,点击红色箭头处 查看消息体json格式
会自动产生 蓝色箭头处的代码行,如下
pprint(response.json('utf8'))
我们就知道了 response.json(‘utf8’) 就是从响应中获取json格式消息体内容的(转化为对应的Python数据对象)。
所以我们就可以写出如下代码
# 导入产生md5的库
import hashlib
m = hashlib.md5()
# 创建客户端
client = HttpClient('127.0.0.1',
timeout=10
)
# 发送请求1
response = client.get("/getopcode")
# 获取opcode
opcode = response.json('utf8')['opcode']
# 传入md5源数据
m.update(opcode.encode())
# 产生哈希值的十六进制表示
opcode-md5= m.hexdigest()
# 发送请求2
response = client.post(
"/bugdevice",
json={
'opcode-md5':opcode-md5,
'action':'bug_sword'
})
您需要高效学习,找工作? 点击咨询 报名实战班
点击查看学员就业情况
模拟不同的客户行为
做性能测试,应该尽量模拟真实的场景。
所以每个客户端都应该对应不同的客户,使用不同的压力数据。
比如,很多人会把不同客户对应的加压数据 存储在数据文件中。
需要黑羽压测从 数据文件中读入数据 并且分配到 各个客户端。
比如,现在有如下格式的数据文件 lt.data,
mike | 43654234 | 43
john | 63562234 | 13
jerry | 95692234 | 23
paton | 54972234 | 41
larry | 72992224 | 76
....
里面每行存储的是被测系统中的 用户名 、密码 、 等级
做性能测试时,必须要使用这个里面的 数据。
这样用 黑羽压测 怎么做呢?
大家进入到 性能场景界面,注意到右边有一个 自动代码产生条目 启动客户端,携带参数
点击,产生如下代码
# 定义每个客户端对应的参数
args = ['user1','user2','user3']
createClients(
'act-1', # 客户端名称
3, # 客户端数量
1, # 启动间隔时间,秒
args # 客户端参数
)
createClients 可以产生多个客户端的,而且我们可以为每个客户端提供 不同的参数数据
。
该函数最后一个参数 args 就是为每个客户端提供的参数数据 用的。
该参数的类型 应该是一个 列表 或者 元组, 里面的元素 就是 依次 传递给 每个客户端的 数据对象。
在上面的例子中,启动的3个客户端 分别接收到 的参数 数据 就是字符串 ‘user1’,‘user2’,‘user3’, 这3个客户端就会分别模拟 这3个客户 进行操作引起的压力。
现在的问题是: 这些参数, 在 单个客户端 脚本 中 如何获得,并使用呢?
我们可以 直接使用 arg
这个内置变量名。
arg
这个内置变量名 就存储了 性能场景脚本 分配的 参数对象。
比如,我们可以定义如下的客户端脚本:
# 创建客户端
client = HttpClient('127.0.0.1', # 目标地址:端口
timeout=10 # 超时时间,单位秒
)
# 打印传入的参数
print(f'传入参数 {arg}')
response = client.get(
f"/api/{arg}" # 请求URL,里面的用户名使用传入的参数
)
这样,我们运行性能测试场景,就会产生如下的输入信息:
传入参数 user1
1563502644 s: send 1
1563502644 s: recv 1 | avg reponse time 0.0010
传入参数 user2
1563502645 s: send 1
1563502645 s: recv 1 | avg reponse time 0.0000
传入参数 user3
1563502646 s: send 1
1563502646 s: recv 1 | avg reponse time 0.0000
好了,有了上面的示例,聪明的读者,你知道,对于要读入1000条用户数据给不同的客户端使用,该怎么写代码了吗?
对了,我们可以这样定义性能场景
# 读入文件每行内容到 lines
with open(r'd:\data.txt') as f:
lines = f.read().splitlines()
# 传入每个客户端参数列表 users
users = []
for line in lines:
# 把文件每行中的用户名、密码、等级取出存入列表对象
parts = line.split('|')
user = [part.strip() for part in parts]
users.append(user)
# 再启动1000个客户端,
# users里面的每个用户信息 依次传递给 每个客户端
createClients(
'act-1',
1000,
1,
users # 传入给每个客户端的参数
)
这样,每个启动的客户端arg变量里面得到的数据,就是如下格式的列表对象,
['mike', '43654234', '43']
我们 就可以使用里面的用户名、密码、等级等信息 给 本客户端 进行 测试了。
做功能测试
黑羽压测 是一款性能测试工具,但是我们也可以使用它,很方便的做 API接口功能测试
。
具体的操作,请大家点击此处链接,观看讲解视频
监控主机的系统资源占用
在性能测试的时候,我们往往需要监控 被测服务 主机的 CPU/内存/磁盘IO 使用情况,并且需要在测试结束时产生 性能图表。
黑羽压测 让这一切都变的简单。
具体的操作,请大家点击此处链接,观看讲解视频
部署到远程Linux运行
有时,我们被测系统在远程,黑羽压测控制台界面直接发起本地加压,离被测系统太远,不适合做压力源。
这时,可以 部署黑羽压测 到多台远程Linux机器上。
另外,如果被测系统的性能指标特别高, 需要有更多的测试机器,同时给被测系统加压力。
这时,我们可以 部署黑羽压测 到多台远程Linux机器上,启动压力测试。
具体的操作,请大家点击此处链接,观看讲解视频