介绍一款轻量级性能测试工具---Locust
我做测试这几年,用过生成负载的最多的工具就是Jmeter。学习python过程中,公司同事用了这一款,我就了解了一下。下列使用方法仅供参考。
Locust是一款易于使用的分布式负载测试工具,基于python脚本进行接口性能负载测试,比较好上手,脚本简单,可支持数千并发用户,但是不支持回掉
安装
已经安装了python3.6
pip install locust
检查是否安装成功
locust --help
脚本编写
from locust import HttpLocust, TaskSet, task
# 定义用户行为
class UserBehavior(TaskSet):
@task
def baidu_index(self):
req=self.client.get("/")
assert req.status_code == 200
class WebsiteUser(HttpLocust):
task_set = UserBehavior
min_wait = 3000
max_wait = 6000
if __name__ == "__main__":
import os
os.system("locust -f Test.py --host=http://exam.hupu.com/bplweb")
UI用户界面
运行脚本之后,在浏览器访问http://localhost:8089/
Number of users to simulate:设置模拟的用户总数
Hatch rate (users spawned/second):每秒启动的虚拟用户数
Start swarming:执行locust脚本
运行脚本的页面
测试结果页面
脚本扩展学习
混合场景下,可以在用户行为类中定义多个task,task后面的数字是指一个Locust实例被挑选执行的权重,数值越大,执行频率越高,index和login随机执行的比例是1:2
from locust import HttpLocust, TaskSet, task
class BestTest(TaskSet):
@task(1)#给task装饰器传一个参数,代表先访问首页
def index(self):#首页
self.client.get('/')
#发get请求
@task(2)
def login(self):#登录
self.client.post('/login',{'username':'besttest','password':'123456'})
#发送post请求,第一个是路径,第二个这个接口的入参,账号和密码
class BestTestIndexUser(HttpLocust):
#这个类继承了HttpLocust,代表每个并发里面的每个用户
task_set = BestTest #这个是每个用户都去干什么,指定了BestTest这个类,它就会每个用户去运行besttest这个类里面的方法
接口测试过程中,会遇到关联接口测试,locust可以提取返回值并作为参数使用
from locust import HttpLocust, TaskSet, task
import json
from common import readConfig
class UserBehavior(TaskSet):
def on_start(self):
pass
def get_headers(self):
headers = {
"Content-Type": "application/json",
"channel": "SHOP"
}
body = {
"unionid": readConfig.unionid
}
res = self.client.post('/customers/login', headers=headers, data=json.dumps(body)).text
assert '成功' in res
res = json.loads(res)
uid = res['data']['uid']
ukey = res['data']['ukey']
return [uid, ukey]
@task(1)
def members_can_withdraw_account_information(self):
res = self.get_headers()
headers = {
"channel": "SHOP",
"uid": str(res[0]),
"ukey": res[1]
}
response = self.client.put("/customers/customer_state",headers=headers).text
assert '成功' in response
class WebsiteUser(HttpLocust):
task_set = UserBehavior
min_wait = 3000
max_wait = 6000
所有并发虚拟用户共享同一份测试数据,各虚拟用户在数据列表中循环取值,比如三个用户并发请求,总共有5个url
from locust import TaskSet, task, HttpLocust
class UserBehavior(TaskSet):
def on_start(self):
self.index = 0
@task
def test_visit(self):
url = self.locust.share_data[self.index]
print('visit url: %s' % url)
self.index = (self.index + 1) % len(self.locust.share_data)
self.client.get(url)
class WebsiteUser(HttpLocust):
task_set = UserBehavior
share_data = ['url1', 'url2', 'url3', 'url4', 'url5']
min_wait = 1000
max_wait = 3000
所有并发虚拟用户共享同一份测试数据,并且保证虚拟用户使用的数据不重复,比如三个用户并发注册账号,但是注册信息要不同
from locust import TaskSet, task, HttpLocust
import queue
class UserBehavior(TaskSet):
@task
def test_register(self):
try:
data = self.locust.user_data_queue.get()
except queue.Empty:
print('account data run out, test ended.')
exit(0)
print('register with user: {}, pwd: {}'\
.format(data['username'], data['password']))
payload = {
'username': data['username'],
'password': data['password']
}
self.client.post('/register', data=payload)
class WebsiteUser(HttpLocust):
task_set = UserBehavior
user_data_queue = queue.Queue()
for index in range(100):
data = {
"username": "test%04d" % index,
"password": "pwd%04d" % index,
"email": "test%04d@debugtalk.test" % index,
"phone": "186%08d" % index,
}
user_data_queue.put_nowait(data)
min_wait = 1000
max_wait = 3000
有更多测试技术问题,还希望多多交流。欢迎一起讨论。添加wx18796903983