Locust學習筆記3——模擬登錄案例(非加密)


  引言

  當我們接到壓測任務的時候,如果被測系統需要登錄的時候,首先需要處理登錄,然后再進行其他接口壓測。

  Taks屬性使用

  首先看一下官方文檔:

  Using the @task decorator to declare tasks is a convenience, and usually the best way to do it. However, it’s also possible to define the tasks of a User or TaskSet by setting the tasks attribute (using the @task decorator will actually just populate the tasks attribute).

The tasks attribute is either a list of Task, or a <Task : int> dict, where Task is either a python callable or a TaskSet class (more on that below). If the task is a normal python function they receive a single argument which is the User instance that is executing the task.

Here is an example of a User task declared as a normal python function:

from locust import User, constant

def my_task(l):
    pass

class MyUser(User):
    tasks = [my_task]
    wait_time = constant(1)

  If the tasks attribute is specified as a list, each time a task is to be performed, it will be randomly chosen from the tasks attribute. If however, tasks is a dict - with callables as keys and ints as values - the task that is to be executed will be chosen at random but with the int as ratio. So with a tasks that looks like this:

{my_task: 3, another_task: 1}

  my_task would be 3 times more likely to be executed than another_task.

Internally the above dict will actually be expanded into a list (and the tasks attribute is updated) that looks like this:

[my_task, my_task, my_task, another_task]

  and then Python’s random.choice() is used pick tasks from the list.

 

  上面總結出來就是:如果隨機權重,就用列表,如果指定權重,就用字段。

 

  官方案例

  普通寫法

from locust import TaskSet,HttpLocust,between

def login(x):
    x.client.post('/login',{'username':'admin','password':'123456'})

def logout(x):
    x.client.post('/logout',{'username':'admin','password':'123456'})

def home(x):
    x.client.get('/')

def systeminfo(x):
    x.client.get('systeminfo')

class TestLogin(TaskSet):

    tasks = {home: 3,systeminfo: 1}

    def on_start(self):
        login(self)

    def on_stop(self):
        logout(self)

class WebSiteUser(HttpLocust):
    task_set = TestLogin
    wait_time = between(3,6)

 

  實例:

from locust import TaskSet,HttpLocust,between,task

def login(x):
    url = '/api/private/v1/login'
    body = {
        "username": "admin",
        "password": "123456"
    }
    r = x.client.post(url=url, data=body)
    print(r.text)

def logout(x):
    print("退出系統")

def home(x):
    print("進入主頁")


def systeminfo(x):
    print("進入系統管理")

class TestLogin(TaskSet):

    tasks = {home: 1,systeminfo: 1}
    # @task
    def setup(self):
        print("開始...")

    def teardown(self):
        print("結束...")

    def on_start(self):
        print("啟動")
        login(self)
    # @task
    def on_stop(self):
        print("停止")
        logout(self)


class WebSiteUser(HttpLocust):
    def setup(self):
        print('locust setup')
    def teardown(self):
        print('locust teardown')
    task_set = TestLogin
    wait_time = between(1,2)

if __name__ == '__main__':
    import os
    os.system('locust -f locustfile.py --host=http://192.168.1.105:8899 --port=8089 ')

  

  說明:

  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

 

  運行結果:

[2020-06-22 21:30:10,993] WIN10-804191526/INFO/locust.main: Starting web monitor at http://*:8089
[2020-06-22 21:30:10,993] WIN10-804191526/INFO/locust.main: Starting Locust 0.14.6
[2020-06-22 21:30:20,212] WIN10-804191526/INFO/locust.runners: Hatching and swarming 2 users at the rate 1 users/s (0 users already running)...
[2020-06-22 21:30:20,213] WIN10-804191526/INFO/stdout: locust setup
[2020-06-22 21:30:20,213] WIN10-804191526/INFO/stdout: 
[2020-06-22 21:30:20,213] WIN10-804191526/INFO/stdout: 開始...
[2020-06-22 21:30:20,213] WIN10-804191526/INFO/stdout: 
[2020-06-22 21:30:20,213] WIN10-804191526/INFO/stdout: 啟動
[2020-06-22 21:30:20,213] WIN10-804191526/INFO/stdout: 
[2020-06-22 21:30:21,213] WIN10-804191526/INFO/locust.runners: All locusts hatched: WebSiteUser: 2 (0 already running)
[2020-06-22 21:30:21,213] WIN10-804191526/INFO/stdout: 啟動
[2020-06-22 21:30:21,213] WIN10-804191526/INFO/stdout: 
[2020-06-22 21:30:41,220] WIN10-804191526/INFO/stdout: 
[2020-06-22 21:30:41,220] WIN10-804191526/INFO/stdout: 
[2020-06-22 21:30:41,220] WIN10-804191526/INFO/stdout: 進入主頁
[2020-06-22 21:30:41,220] WIN10-804191526/INFO/stdout: 
[2020-06-22 21:30:42,217] WIN10-804191526/INFO/stdout: 
[2020-06-22 21:30:42,217] WIN10-804191526/INFO/stdout: 
[2020-06-22 21:30:42,217] WIN10-804191526/INFO/stdout: 進入系統管理

 

  界面:

 

  項目實例

  標准寫法

from locust import TaskSet,HttpLocust,between,task



class TestLogin(TaskSet):

    def setup(self):
        print("開始...")

    def teardown(self):
        print("結束...")

    def _login(self):
        url = '/api/private/v1/login'
        body = {
            "username": "admin",
            "password": "123456"
        }
        r = self.client.post(url=url, data=body)
        print(r.text)
        assert "等1" in r.text

    def logout(self):
        print("退出系統")

    @task(1)
    def home(self):
        print("進入主頁")

    @task(1)
    def systeminfo(self):
        print("進入系統管理")

    def on_start(self):
        """ on_start is called when a Locust start before any task is scheduled """
        print("啟動")
        self._login()

    def on_stop(self):
        """ on_stop is called when the TaskSet is stopping """
        print("停止")
        self.logout()


class WebsiteUser(HttpLocust):
    task_set = TestLogin
    def setup(self):
        print('locust setup')

    def teardown(self):
        print('locust teardown')
    wait_time = between(5,6)


if __name__ == '__main__':
    import os
    os.system('locust -f locustfile_pro.py --host=http://192.168.1.105:8899 --port=8084')

  結果:

[2020-06-22 23:47:09,088] WIN10-804191526/INFO/locust.main: Starting web monitor at http://*:8084
[2020-06-22 23:47:09,088] WIN10-804191526/INFO/locust.main: Starting Locust 0.14.6
[2020-06-22 23:48:05,436] WIN10-804191526/INFO/locust.runners: Hatching and swarming 1 users at the rate 1 users/s (0 users already running)...
[2020-06-22 23:48:05,436] WIN10-804191526/INFO/stdout: locust setup
[2020-06-22 23:48:05,436] WIN10-804191526/INFO/stdout: 
[2020-06-22 23:48:05,436] WIN10-804191526/INFO/locust.runners: All locusts hatched: WebsiteUser: 1 (0 already running)
[2020-06-22 23:48:05,436] WIN10-804191526/INFO/stdout: 開始...
[2020-06-22 23:48:05,436] WIN10-804191526/INFO/stdout: 
[2020-06-22 23:48:05,436] WIN10-804191526/INFO/stdout: 啟動
[2020-06-22 23:48:05,436] WIN10-804191526/INFO/stdout: 
[2020-06-22 23:48:05,513] WIN10-804191526/INFO/stdout: 測試
[2020-06-22 23:48:05,513] WIN10-804191526/INFO/stdout: 
[2020-06-22 23:48:05,513] WIN10-804191526/INFO/stdout: 響應數據是:{"data":{"id":500,"rid":0,"username":"admin","mobile":"12345678","email":"adsfad@qq.com","token":"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOjUwMCwicmlkIjowLCJpYXQiOjE1OTI4NDA4ODUsImV4cCI6MTU5MjkyNzI4NX0.wN9CrRtyENoQgMWKgtaK5toa47fB3qz1nvki9PvqdVg"},"meta":{"msg":"登錄成功","status":200}}
[2020-06-22 23:48:05,513] WIN10-804191526/INFO/stdout: 
[2020-06-22 23:48:05,513] WIN10-804191526/INFO/stdout: 進入主頁
[2020-06-22 23:48:05,513] WIN10-804191526/INFO/stdout: 
[2020-06-22 23:48:11,277] WIN10-804191526/INFO/stdout: 進入系統管理

  界面:

 

   需要注意的是如果是V0.13.0版本以上就不能用min_wait和max_wait了。不然會報錯:

eprecationWarning: Usage of min_wait and max_wait is deprecated since version 0.13. Instead use: wait_time = between(5, 6)
), DeprecationWarning

  腳本解讀:

1、創建TestLogin()類繼承TaskSet類:  用於定義測試業務。
2、創建login()、logout()、home()、systeminfo()方法分別表示一個行為,訪問http://127.0.0.1:8899。用@task() 裝飾該方法為一個任務。1、2表示一個Locust實例被挑選執行的權重,數值越大,執行頻率越高。在當前TestLogin()行為下的兩個方法得執行比例為1:1
3、WebsiteUser()類: 用於定義模擬用戶。
4、task_set :  指向一個定義了的用戶行為類。
5、host:   指定被測試應用的URL的地址
6、min_wait :   用戶執行任務之間等待時間的下界,單位:毫秒。
7、max_wait :   用戶執行任務之間等待時間的上界,單位:毫秒。

  備注:默認情況下,時間是在min_wait和max_wait之間隨機選擇,但是可以通過將wait_function設置為任意函數來使用任何用戶定義的時間分布。

  對於指數分布的等待時間平均為1秒:

class WebsiteUser(HttpLocust):
    task_set = TestLogin
    wait_function = lambda self: random.expovariate(1) * 1000

 

  啟動程序

  最新文檔:

  歷史文檔:

在cmd窗口,進入到執行py文件的路徑下,進行start,默認的啟用方法如下:

>>> locust -f 需要執行的腳本.py --host=http://需要用到的url

官網針對啟用,專門的介紹如下:

To run Locust with the above Locust file, if it was named locustfile.py and located in the current working directory, we could run:

locust --host=http://example.com
If the Locust file is located under a subdirectory and/or named different than locustfile.py, specify it using -f:

locust -f locust_files/my_locust_file.py --host=http://example.com
To run Locust distributed across multiple processes we would start a master process by specifying --master:

locust -f locust_files/my_locust_file.py --master --host=http://example.com
and then we would start an arbitrary number of slave processes:

locust -f locust_files/my_locust_file.py --slave --host=http://example.com
If we want to run Locust distributed on multiple machines we would also have to specify the master host when starting the slaves (this is not needed when running Locust distributed on a single machine, since the master host defaults to 127.0.0.1):

locust -f locust_files/my_locust_file.py --slave --master-host=192.168.0.100 --host=http://example.com
You may wish to consume your Locust results via a csv file. In this case, there are two ways to do this.

First, when running the webserver, you can retrieve a csv from localhost:8089/stats/requests/csv and localhost:8089/stats/distribution/csv. Second you can run Locust with a flag which will periodically save the csv file. This is particularly useful if you plan on running Locust in an automated way with the --no-web flag:

locust -f locust_files/my_locust_file.py --csv=foobar --no-web -n10 -c1
You can also customize how frequently this is written if you desire faster (or slower) writing:
import locust.stats locust.stats.CSV_STATS_INTERVAL_SEC = 5 # default is 2 seconds

 備注:8089是該服務啟動的端口號,如果是本地啟動,可以直接在瀏覽器輸入http://localhost:8089打開UI界面,如果是其他機器搭建locust服務,則輸入該機器的IP+端口即可;

  總結

  關於Locust性能測試模擬案例介紹到此,有興趣的朋友可以加入測開交流群進行溝通與學習,一起成長!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM