Locust 任務巢狀

FisherMan發表於2020-05-18

在上一章的簡介及使用中,介紹了一個 locust 用例的組成及配置。本章在上一個用例的基礎上會增加任務巢狀的情況
我們知道,locust 的第一個特點是,可以用普通的 python 進行指令碼的編寫 (拿上一章的例子),這就可以有多種實現方式,隨之任務巢狀也會有多種形式
一、指令碼任務的多樣性
demo_1.py

from locust import Locust, TaskSet, task, between
from time import time
#使用@task來宣告任務,執行的時候,my_task_3不執行
class MyTaskSet(TaskSet):

    # TaskSet相當於下面所有task的大腦
    @task(1)  # 宣告任務
    def task1(self):
        print("執行task1")

    @task(5)
    def task2(self):
        print("執行task2")

    def my_task_3(self):
        print("執行task3")


class WebUser(Locust):
    task_set = MyTaskSet

    weight = 5
    wait_time = between(5, 15)
    host = ""  # 域名host

demo_2.py

from locust import Locust, TaskSet, between


class MyTask(TaskSet):
    def task1(self):
        print('task1')

    def task2(self):
        print('task2')
    # 下面tasks三種選擇一種
    tasks = [task1, task2]  # 以列表形式,預設權重為1:1
    tasks = {task1: 1, task2: 5}  # 以字典形式,帶權重
    tasks = [(task1,1),(task2,5)]    #以列表形式,元組格式(callable,int)
    # 以列表和字典的形式進行執行時,隨機選擇每個任務執行


class User(Locust):
    task_set = MyTask
    wait_time = between(1, 4)

demo3.py

from locust import Locust, TaskSet, between


# 將 任務也可以放在外面,統一以列表的形式傳入
def task1(obj):
    print('task1')


def task2(obj):
    print('task2')



class MyTask(TaskSet):
    #以下三種選擇一種
    tasks = [task1, task2]  # 以列表形式,預設權重為1:1
    tasks = {task1: 1, task2: 5}  # 以字典形式,帶權重
    tasks = [(task1,1),(task2,5)]
    # 以列表和字典的形式進行執行時,隨機選擇每個任務執行


class User(Locust):
    task_set = MyTask
    wait_time = between(1, 4)

可以看出,上面三個 demo.py 基本等同,我們的 locust 指令碼可以用 python 的類和函式隨意定義任務,減輕了我們進行指令碼編寫的時間,為我們進行效能測試工作提供了很大的便利。
二、指令碼任務的巢狀
巢狀發生在什麼情況下呢?
舉個例子,開啟淘寶 app,有的使用者會停留在首頁,購物車,個人中心,而使用者在首頁,購物車,個人中心又會進行不同的動作。
為了模仿使用者的行為,按照分層的邏輯就產生了下面的結構:

  • 使用者行為
    • 首頁
      • 瀏覽
      • 點選到活動頁
    • 購物車
      • 結算頁
      • 修改商品
    • 個人中心
      • 訂單列表頁
      • 個人資料

巢狀一

from locust import Locust, TaskSet, constant, task


class UserBehavior(TaskSet):
    @task(30)
    class FrontPage(TaskSet):
        @task(20)
        def view_page(self):
            pass

        @task(80)
        def click_activity(self):
            pass

    @task(40)
    class CartPage(TaskSet):
        @task(20)
        def order_page(self):
            pass

        @task(80)
        def edit_product(self):
            pass

    @task(30)
    class MinePage(TaskSet):
        @task(80)
        def order_list(self):
            pass

        @task(20)
        def mine_information(self):
            pass

巢狀二(Tips:子任務的類要放在父任務類的上面,才能被父類引用)

from locust import Locust, TaskSet, constant, task


class FrontPage(TaskSet):
    @task(20)
    def view_page(self):
        pass

    @task(80)
    def click_activity(self):
        pass


class CartPage(TaskSet):
    @task(20)
    def order_page(self):
        pass

    @task(80)
    def edit_product(self):
        pass


class MinePage(TaskSet):
    @task(80)
    def order_list(self):
        pass

    @task(20)
    def mine_information(self):
        pass


class UserBehavior2(TaskSet):
    tasks = {FrontPage: 30, CartPage: 40, MinePage: 30}

總結:這兩種巢狀方法可以二選一,但是推薦使用第二種巢狀,方便後面更深層次的任務巢狀。

  • 注意事項:
    • 1.def 函式 task 下,不要巢狀 class(在巢狀的類中寫 def 函式時,self 無效)
class ErrorTask(TaskSet):
    def run(self):
        class TaskSub(TaskSet):
            pass
  • 2.繼承 taskset 的 class 類,不建議使用init,可以在 class 中增加非任務的函式,或者呼叫非繼承 taskset 的非任務類

相關文章