Python 编写locust性能测试代码
前言
在Locust测试脚本中,所有业务测试场景都是在HttpLocust和TaskSet两个类的继承子类中进行描述;
from locust import HttpLocust, TaskSet, task # 定义用户行为 class UserBehavior(TaskSet): @task def baidu_index(self): self.client.get("/") class WebsiteUser(HttpLocust): task_set = UserBehavior min_wait = 3000 max_wait = 6000
通过命令行启动
locust -f .\load_test.py --host=https://www.baidu.com
- f 指定性能测试脚本文件。
- --host 指定被测试应用的URL的地址,注意访问百度使用的HTTPS协议。
然后通过浏览器访问,并设置测试参数:http://localhost:8089(Locust启动网络监控器,默认为端口号为: 8089)
TaskSet类
一个TaskSet类定义了一个用户操作行为的任务集合,测试任务开始后,任务可以顺序执行(schedule_task)、挑选下一个任务(execute_next_task)、执行任务(execute_task)、休眠等待(wait)、中断控制(interrupt)等待。
这样就可以模拟用户的业务测试场景,对虚拟用户的所有行为进行组织和描述,并可以对不同任务的权重进行配置,一个TaskSet类重要的属性有哪些?
wait_time属性
用户wait_time方法是一种可选功能,用于使模拟用户在任务执行之间等待指定的时间。
内置了三个等待时间功能:
- constant 在固定的时间内;
- between 在最大值和最小值之间的随机时间;
- constant_pacing 自适应时间,以确保任务每X秒(最多)运行一次。
例如,使每个用户在每次任务执行之间等待0.5到10秒:
from locust import TaskSet, task, between class MyUser(TaskSet): @task def my_task(TaskSet): print("executing my_task") wait_time = between(0.5, 10)
也可以在类上直接声明自己的wait_time方法。例如,下面的TaskSet类将休眠一秒钟,然后休眠两秒,然后休眠三秒,依此类推。
class MyUser(TaskSet): last_wait_time = 0 def wait_time(self): self.last_wait_time += 1 return self.last_wait_time ...
用户任务属性
有两种方式定义任务(用户行为)
@task装饰器
使用task装饰器为用户添加任务
且@task采用可选的weight参数,该参数可用于指定任务的执行率。在以下示例中,task2被选择为task1的机会是两倍:
from locust import TaskSet, task class UserBehavior(TaskSet): @task(1) def test_job1(self): self.client.get('/test1') @task(3) def test_job2(self): self.client.get('/test2')
采用task属性
from locust import TaskSet def test_job1(obj): obj.client.get('/test1') def test_job2(obj): obj.client.get('/test2') class UserBehavior(TaskSet): tasks = {test_job1: 1, test_job2: 2} # tasks = [(test_job1,1), (test_job1,3)] # 两种方式等价
上面两种定义任务信息方式中,均设置了权重属性,即执行test_job2的频率是test_job1的两倍。若不指定,默认比例为1:1。
不同用户权重属性
如果测试文件中存在多个用户类,也就是有多个用户在操作,可以让一个用户有更多操作的机会,比如以这里为例来说,网络用户的可能性是移动用户的三倍:
class WebUser(TaskSet): weight = 3 ... class MobileUser(TaskSet): weight = 1 ...
任务标签
通过使用@tag
装饰器标记任务,您可以对使用在命令行中使用--tags
and--exclude-tags
参数指定任务执行,而其他任务跳过。考虑以下示例:
from locust import TaskSet, constant, task, tag class MyUser(TaskSet): wait_time = constant(1) @tag('tag1') @task def task1(self): pass @tag('tag1', 'tag2') @task def task2(self): pass @tag('tag3') @task def task3(self): pass @task def task4(self): pass
如果--tags tag1,那么只有task1任务和task2执行;
如果--tags tag2 tag3,那么只有task2任务和task3执行。
注意:可以为一个任务打上多个tag。
编写接口压测脚本文件locustfile.py
from locust import HttpLocust, TaskSet, task class UserBehavior(TaskSet): def setup(self): print('task setup') def teardown(self): print('task teardown') def on_start(self): # 虚拟用户启动Task时运行 print('start') def on_stop(self): # 虚拟用户结束Task时运行 print('end') @task(2) def index(self): self.client.get("/") @task(1) def profile(self): self.client.get("/profile") class WebsiteUser(HttpLocust): def setup(self): print('locust setup') def teardown(self): print('locust teardown') host = http: // XXXXX.com task_set = UserBehavior min_wait = 5000 max_wait = 9000 if __name__ == '__main__': pass
说明:
Locust类有setup和teardown,TaskSet类有setup、teardown、on_start、on_stop。
每次启动locust时运行setup方法,退出时运行teardown方法,locust执行TaskSet时运行TaskSet的setup方法,退出时运行teardown方法,每个虚拟用户执行操作时运行on_start方法,退出时执行on_stop方法,运行上面的脚本,执行顺序如下:
执行顺序:Locust setup → TaskSet setup → TaskSet on_start → TaskSet tasks → TaskSet on_stop → TaskSet teardown → Locust teardown
创建ScriptTasks()类继承TaskSet类: 用户行为类,用于定义测试业务场景。
创建index()、about()、demo()方法分别表示一个行为,访问http://example.com。用@task() 装饰该方法为一个任务。1、2表示一个Locust实例被挑选执行的权重,数值越大,执行频率越高。在当前ScriptTasks()行为下的三个方法得执行比例为2:1:1
WebsiteUser()类: 用于定义模拟用户。
task_set : 指向一个定义了的用户行为类。
host: 指定被测试应用的URL的地址
min_wait : 用户执行任务之间等待时间的下界,单位:毫秒。
max_wait : 用户执行任务之间等待时间的上界,单位:毫秒。
参考:
https://docs.locust.io/en/stable/writing-a-locustfile.html
https://www.cnblogs.com/monogem/p/10715637.html