1. 程式人生 > 其它 >locust工具學習筆記(三)

locust工具學習筆記(三)

技術標籤:效能測試軟體測試locust負載測試介面壓測

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,則將其加到任務選擇隊首。

歡迎大家關注我的訂閱號,會定期分享一些關於測試相關的文章,有問題也歡迎一起討論學習!