locust工具学习笔记(三)-Tasks属性、tag修饰符、TaskSet类

locust工具学习笔记(三)

虚拟用户数分配和权重的关系

1、一个场景文件中如果定义多个用户类,用来对不同用户行为进行压测时,可以用weight属性来控制用户行为执行权重

2、当用户权重不足1人时,则会被忽略(如果权重为5:1时如果启动3个用户,则配比是2.5:0.5,不足一人时用户行为2不会被执行)

from locust import User, task, constant
​
class UserBehavior1(User):
    wait_time = constant(1)
    weight = 2
    @task
    def task_1(self):
        print("用户行为1")
​
class UserBehavior2(User):
    wait_time = constant(1)
    weight = 1
    @task
    def task_2(self):
        print("用户行为2")
​
[2021-01-20 11:28:06,190] 910lanmingyong/INFO/locust.main: Starting web interface at http://0.0.0.0:8089 (accepting connections from all network interfaces)
[2021-01-20 11:28:06,197] 910lanmingyong/INFO/locust.main: Starting Locust 1.3.1
[2021-01-20 11:28:24,846] 910lanmingyong/DEBUG/locust.runners: Updating state to 'spawning', old state was 'ready'
[2021-01-20 11:28:24,846] 910lanmingyong/INFO/locust.runners: Spawning 10 users at the rate 1 users/s (0 users already running)...
用户行为1
用户行为1
用户行为1
用户行为1
用户行为1
用户行为2
用户行为1
用户行为2
用户行为1
用户行为2
用户行为1
用户行为2
用户行为1
用户行为2
用户行为2
用户行为1
用户行为2
用户行为1
用户行为1
用户行为2
用户行为2
用户行为1
用户行为1
用户行为2
用户行为1
用户行为1
用户行为2
用户行为2

Tasks属性

一般情况下需要测试的用户行为只需要在用户类的用户行为方法上添加@task修饰符即可,但是不在用户类中编写用户行为代码,而是引用外部用户行为方法时就可以死使用tasks属性实现。

from locust import User, task, constant
​
​
def task_1(self):
    print("用户行为1")
​
def task_2(self):
    print("用户行为2")
​
class UserBehavior(User):
    wait_time = constant(1)
    tasks = [task_1,task_2]
​
    #如果需要设置权重则为
    # tasks = {task_1:1, task_2:2}
​
[2021-01-20 12:55:38,120] 910lanmingyong/INFO/locust.runners: All users spawned: UserBehavior: 4 (0 already running)
用户行为2
用户行为1
用户行为1
用户行为1
用户行为1
用户行为1
用户行为2
用户行为1
用户行为2
​
from locust import User, task, constant
​
​
def task_1(self):
    print("用户行为1")
​
def task_2(self):
    print("用户行为2")
​
class UserBehavior(User):
    wait_time = constant(1)
    # tasks = [task_1,task_2]
​
    #如果需要设置权重则为
    tasks = {task_1:1, task_2:2}
​
[2021-01-20 12:57:43,757] 910lanmingyong/INFO/locust.runners: Spawning 3 users at the rate 1 users/s (0 users already running)...
用户行为2
用户行为2
用户行为2
[2021-01-20 12:57:45,758] 910lanmingyong/INFO/locust.runners: All users spawned: UserBehavior: 3 (0 already running)
用户行为2
用户行为1
用户行为1
用户行为2
用户行为2
用户行为1

tag修饰符

@tag修饰符主要是用例管理测试方法的执行,在测试方法上加上一个或者多个@tag修饰符,就可以在执行测试时通过@tag修饰符运行指定测试集合,而且它不会影响全局的任务收集。

在执行测试时,使用 -T 或者 -E 来挑选测试集合

-T 选中的集合

-E 排除选中的集合

例子如下:

from locust import task, constant, HttpUser, tag
​
​
class MyUser(HttpUser):
    wait_time = constant(1)
    @tag("smoke")
    @task(1)
    def task_1(self):
        print("my task1")
​
    @tag("test_env")
    @task(1)
    def task_2(self):
        print("my task2")
​
    @tag("pre_env")
    @task(1)
    def task_3(self):
        print("my task3")
​
    @tag("pre_env")
    @tag("test_env")
    @task(1)
    def task_4(self):
        print("my task4")
​
​
#locustfile_dome9.py  -T smoke   只执行tag=smoke标签测试集
E:\PyProject\Learning>locust -f E:\PyProject\Learning\locusti\locustfile_dome9.py  -T smoke
[2021-01-21 12:55:52,296] 910lanmingyong/INFO/locust.main: Starting web interface at http://0.0.0.0:8089 (accepting connections from all network interfaces)
[2021-01-21 12:55:52,302] 910lanmingyong/INFO/locust.main: Starting Locust 1.3.1
[2021-01-21 12:56:01,725] 910lanmingyong/INFO/locust.runners: Spawning 5 users at the rate 1 users/s (0 users already running)...
my task1
my task1
my task1
my task1
my task1
my task1
my task1
my task1
my task1
my task1
​
#locustfile_dome9.py  -E smoke 不执行tag=smoke测试集
E:\PyProject\Learning\locusti\locustfile_dome9.py  -E smoke
[2021-01-21 12:59:29,493] 910lanmingyong/INFO/locust.main: Starting web interface at http://0.0.0.0:8089 (accepting connections from all network interfaces)
[2021-01-21 12:59:29,499] 910lanmingyong/INFO/locust.main: Starting Locust 1.3.1
[2021-01-21 12:59:37,535] 910lanmingyong/INFO/locust.runners: Spawning 5 users at the rate 2 users/s (0 users already running)...
my task2
my task2
my task2
my task3
my task2
my task3
my task4
my task4
[2021-01-21 12:59:39,557] 910lanmingyong/INFO/locust.runners: All users spawned: MyUser: 5 (0 already running)
my task3
my task4
my task4
my task2
my task4
my task2
my task2
my task2
my task2
my task4
my task4
my task4
my task3

TaskSet类

TaskSet类定义了每个用户的任务集合 。每一个Locust启动的用户都会从TaskSet中随机挑选一个任务执行,如果配置权重则按权重配比挑选执行。

第一种使用方式:

使用tasks属性将多个TaskSet子类嵌套在一起

from locust import task, constant, HttpUser, tag, TaskSet, User
​
​
class MyUser1(TaskSet):
    wait_time = constant(1)
​
    @task
    def task_1(self):
        print("my task1")
​
    @task
    def task_2(self):
        print("my task2")
​
​
class MyUser2(TaskSet):
​
    @task
    def task_3(self):
        print("my task3")
​
    @task
    def task_4(self):
        print("my task4")
​
​
class MyUserAll(User):
    wait_time = constant(1)
    tasks = {MyUser1:1,MyUser2:2}
​
    @task
    def task_5(self):
        print("my task5")
​
    @task
    def task_6(self):
        print("my task6")
        
#执行输出
[2021-01-22 16:35:45,634] 910lanmingyong/INFO/locust.main: Starting web interface at http://0.0.0.0:8089 (accepting connections from all network interfaces)
[2021-01-22 16:35:45,641] 910lanmingyong/INFO/locust.main: Starting Locust 1.3.1
[2021-01-22 16:35:54,929] 910lanmingyong/INFO/locust.runners: Spawning 5 users at the rate 1 users/s (0 users already running)...
my task2
my task1
my task4
my task2
my task4
my task5
my task1
my task4
my task2
my task6
[2021-01-22 16:35:58,933] 910lanmingyong/INFO/locust.runners: All users spawned: MyUserAll: 5 (0 already running)
my task1
my task3
my task1
my task6
my task4
my task2
my task3
my task1
my task3
my task3
my task1
my task3

第二种使用方式:

TaskSet类的相互嵌套,可以实现实际测试中复杂的场景要求

from locust import task, constant, HttpUser, tag, TaskSet, User
​
​
class MyUser1(TaskSet):
    wait_time = constant(1)
​
    @task(1)
    def task_1(self):
        print("my task1")
​
    @task(1)
    def task_2(self):
        print("my task2")
​
    @task(3)
    class MyUser2(TaskSet):
​
        @task(2)
        def task_3(self):
            print("my task3")
​
        @task(1)
        def task_4(self):
            print("跳出MyUser2,否则这个用户就会一直执行在MyUser2中执行task_3任务")
            self.interrupt()
​
​
​
class MyUserAll(User):
    wait_time = constant(1)
    tasks = [MyUser1]
#[2021-01-22 17:01:42,488] 910lanmingyong/INFO/locust.main: Starting web interface at http://0.0.0.0:8089 (accepting connections from all network interfaces)
[2021-01-22 17:01:42,494] 910lanmingyong/INFO/locust.main: Starting Locust 1.3.1
[2021-01-22 17:01:49,780] 910lanmingyong/INFO/locust.runners: Spawning 5 users at the rate 1 users/s (0 users already running)...
my task1
跳出MyUser2,否则这个用户就会一直执行在MyUser2中执行task_3任务
my task1
my task2
跳出MyUser2,否则这个用户就会一直执行在MyUser2中执行task_3任务
my task3
my task2
my task3
my task3
my task3
跳出MyUser2,否则这个用户就会一直执行在MyUser2中执行task_3任务
my task3
my task3
[2021-01-22 17:01:53,783] 910lanmingyong/INFO/locust.runners: All users spawned: MyUserAll: 5 (0 already running)
my task3
my task3
my task3
my task3
跳出MyUser2,否则这个用户就会一直执行在MyUser2中执行task_3任务
my task3
跳出MyUser2,否则这个用户就会一直执行在MyUser2中执行task_3任务
my task3
my task3
my task3
my task3
my task3
my task3
my task3
跳出MyUser2,否则这个用户就会一直执行在MyUser2中执行task_3任务
跳出MyUser2,否则这个用户就会一直执行在MyUser2中执行task_3任务
跳出MyUser2,否则这个用户就会一直执行在MyUser2中执行task_3任务
my task3
my task3
跳出MyUser2,否则这个用户就会一直执行在MyUser2中执行task_3任务
my task2

第三种使用方式:

在User类中可以嵌入TaskSet类,作为User的子类

from locust import task, constant,TaskSet, User
​
class MyUserAll(User):
    wait_time = constant(1)
​
    @task
    def task_1(self):
        print("my task1")
    @task
    class MyUser2(TaskSet):
​
        @task(3)
        def task_3(self):
            print("my task2")
​
        @task(1)
        def task_4(self):
            print("my task3")
​
​
'''
说明:
1、场景执行时MyUser1和MyUser2执行的权重是相同的
2、MyUser2任务执行时75%会执行task_2,25%会执行task_3
3、因为MyUser2中没有self.interrupt()方法所以最后所有的用户都会在执行task_3,和task_4
'''
​
[2021-01-22 19:07:01,255] 910lanmingyong/INFO/locust.runners: 5 Users have been stopped
[2021-01-22 19:07:11,342] 910lanmingyong/INFO/locust.runners: Spawning 5 users at the rate 2 users/s (0 users already running)...
my task1
my task1
my task1
my task2
my task1
my task3
my task1
my task3
[2021-01-22 19:07:13,346] 910lanmingyong/INFO/locust.runners: All users spawned: MyUserAll: 5 (0 already running)
my task1
my task2
my task3
my task1
my task2
my task3
my task2
my task3
my task2
my task2
my task2
my task3
my task2
my task2
my task3
my task2
my task2
my task3
my task2
my task2
my task2
my task2
my task2
my task2
my task2
my task2
my task2
my task2
my task3
my task2
my task3
my task2
my task2
my task2
my task2
my task3
my task3
my task2
my task3
my task2
my task3
my task3
my task2
my task2
my task3
my task2

TaskSet类还有其他的有用方法:

  • on_start()函数 locust用户进入TaskSet之后首先会执行on_start()。

  • on_start()函数

    locust用户退出TaskSet之后会执行on_stop()。

  • locust属性 指向每个TaskSet所属的loucst用户实例。

  • parent属性 指向TaskSet的父类TaskSet,在TaskSet有嵌套的情况下使用,如果调用parent的TaskSet是最顶层的,则返回它所属的locust用户实例。

  • client属性 指向TaskSet所属的父HttpLocust类的client属性,self.client与self.locust.client效果相同。如果TaskSet所属的父类是个Locust类,则无client属性。

  • interrupt(reschedule=True) 方法顶层的TaskSet,不能调用这个方法。如果reschedule置为True时,从被嵌套任务出来马上选择新任务执行,如果reschedule置为False,从被嵌套任务出来后,随机等待min_wait和max_wait之间的一段时间,再选择新任务执行。

  • schedule_task(task_callable, args=None, kwargs=None, first=False) 方法将一个可调用的对象task_callable添加进某个Locust对象的任务选择队列,其中args和kwargs是传递给可调用对象的参数,如果first置为True,则将其加到任务选择队首。

欢迎大家关注我的订阅号,会定期分享一些关于测试相关的文章,有问题也欢迎一起讨论学习!

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值