Load testing by Python Locust

閱讀時間約 15 分鐘

Locust 介紹

An open source load testing tool. Define user behaviour with Python code, and swarm your system with millions of simultaneous users.
如果你也是python 使用者,這邊介紹一個效能測試的工具locust,他是直接用python code去寫測試script,自由度比較高,不像老牌測試工具jmeter 是需要GUI操作,假設我們有一個登入情境,密碼是需要RSA加密,那用python 可以去引用一些第三方library去完成這個任務,或是一些比較複雜行為,如果是jmeter沒有在他功能範圍內,就不知道要怎麼使用。
Official Site: https://locust.io/
Installation
pip install locust

Write a locust script

這邊一個範例是先登入拿取token後去測試/files API
from locust import HttpUser, task, between
import json
from test_data import *
import random


class WebsiteTestUser(HttpUser):
wait_time = between(0.5, 1)
host = "http://host_address"

def on_start(self):
        """ on_start is called when a Locust start before any task is scheduled """
if len(USER_CREDENTIALS) > 0:
account, password = USER_CREDENTIALS.pop()
self.access, self.refresh = self.login_to_get_token(account, password)

def on_stop(self):
""" on_stop is called when the TaskSet is stopping """
pass

def login_to_get_token(self, account, password):
path = '/login'
headers = {'Content-Type': 'application/json'}
payload = {
"email": account,
"password": password
}
resp = self.client.post(url=path, headers=headers, data=json.dumps(payload))

return resp.json()['access_token'], resp.json()['refresh_token']

def refresh_token(self, token):
url = "/refreshToken"
headers = {'Content-Type': 'application/json'}
payload = {"refresh_token": token}
resp = self.client.post(url, headers=headers, data=json.dumps(payload))
self.access = resp.json()['access_token']
self.refresh = resp.json()['refresh_token']

@task(1)
def get_file(self):
uuid_list = [
'7ca74e17-ac8a-48fc-84ed-0e947cb4c333',
'666e4a5b-6704-41e9-b08d-b18dd1d50c0f',
'c8c17345-d533-41b0-bbd5-5e39d023fcb6',
]
path = f'/files/{random.choice(uuid_list)}'
headers = {'Content-Type': 'application/json', 'Authorization': f'Bearer {self.access}'}
with self.client.get(url=path, headers=headers, catch_response=True) as response:
if response.status_code == 401 and response.json()['status'] == "UnauthorizedError":
self.refresh_token(self.refresh)
他就是一個正常的python module,我們可以直接import 需要的packages
from locust import HttpUser, task, between
import json
from test_data import *
import random
這邊define一個class 繼承HttpUser,讓我們可以用來發送 HTTP requests去測試我們要測試的API或系統。between 讓simulated users在一個隨機等待時間範圍區間發送requests,也可以用constant去固定每個task中間的等待時間。
class WebsiteTestUser(HttpUser):
wait_time = between(0.5, 1)
@task decorator 可以對要測試的task設定權重比例,Locust會creates a greenlet (micro-thread)讓每一個模擬的user去呼叫我們主要要被測試的task methods,其他沒有@task decorator的internal methods如範例中的refresh_token 就只會在我們要呼叫的時候被使用,self.client attribute 可以用來發送 HTTP calls,也會被記錄在locust報告的統計資訊中。
@task(1)
def get_file(self):
    ...
    with self.client.get(url=path, headers=headers, catch_response=True) as response:
    ...

Run the script with GUI

locust -f locust_file.py
然後可以打開browser 到預設的port 8089, http://localhost:8089/ 去設定預期要模擬的人數跟每一秒要增加多少人到預期的量。
設定concurrent users and spawn rate
即時會有統計數據可以看
requests per second and response time charts
也能在過程中去增減模擬的使用者

Running without the web UI

如果不用web UI也可以用terminal帶一些需要用到的flag去跑,--headless 代表不用web UI,-u代表要幾個users,-r代表spawn rate,-t 代表要跑多少時間,--html代表要產生的html report。
locust -f locust_file.py --headless -u 5 -r 1 -t 360s --html test_report.html
也可以用設定config file的方式去跑
locust --config=/load_testing/config.conf
config file example
locustfile = /load_testing/locust_file.py
headless = true
host = http://example.com
users = 10
spawn-rate = 1
run-time = 10s
html = locust_report.html

Trigger locust test with Gitlab CI

Gitlab CI - run pipeline
也可以利用Gitlab CI 設定variables在config file上,去跑測試
config file example
locustfile = /builds/project_name/load_testing/RUN_TARGET.py
headless = true
host = https://example.com
users = RUN_USERS
spawn-rate = 1
run-time = RUN_TIME
html = locust_report.html
Gitlab CI Yaml example
stages:
- test
locust:
stage: test
variables:
TARGET: ""
USERS: "1"
TIME: "10s"
before_script:
- cat /builds/project_name/load_testing/__locust.conf
- sed -e 's/RUN_TARGET/'$TARGET'/1' -e 's/RUN_USERS/'$USERS'/1' -e 's/RUN_TIME/'$TIME'/1' /builds/project_name/load_testing/__locust.conf > /builds/project_name/load_testing/locust_run.conf
- cat /builds/project_name/load_testing/locust_run.conf
script:
- locust --config=/builds/project_name/load_testing/locust_run.conf
rules:
- if: $TARGET
allow_failure: true
artifacts:
when: always
paths:
- locust_report.html
expire_in: 1 week
Another Gitlab CI Yaml example 不用config file也不用variables
stages:
- test
locust:
stage: test
image: /runner-image/qa-python:3.7.7-20220719
variables:
GIT_SSL_NO_VERIFY: "1"
script:
- locust -f load_testing/test1.py --headless -u 10 -r 1 -t 360s --html report1.html
- locust -f load_testing/test2.py --headless -u 10 -r 1 -t 360s --html report2.html
- locust -f load_testing/test3.py --headless -u 10 -r 1 -t 360s --html report3.html
rules:
- changes:
- requirements.txt
allow_failure: true
artifacts:
when: always
paths:
- report1.html
- report2.html
- report3.html
expire_in: 1 week

總結

這邊簡單介紹效能測試工具locust,也介紹了幾種方式去跑這個測試工具,透過效能測試我們可以知道我們測試的系統大概可以承受多少的交易量,反應時間是否有達到使用者都能順暢使用的標準,或是業務上應該要達到的標準,超出負荷的時候,系統是怎麼樣回應,下降回可承受的量是否能回復正常運行,在跑長時間測試的時候看看回應是不是都是很穩定,是否有不如預期的行為產生,看看是硬體資源(CPU/Memory/Disk IO)是否需要調整,看看網路端是否異常,DB連線數量上面是否被限制,又或是程式碼效能需要再調整,總之效能測試是一種很重要的非功能性測試,開發人員或測試人員可以在開發好一個API的時候就先測試看看,比較底層的API或服務,可能dependency比較少比較好釐清問題,早點測試早點發現問題先處理成本也會比較低,祝福大家系統的品質透過測試都能越來越好。
avatar-img
21會員
66內容數
留言0
查看全部
avatar-img
發表第一個留言支持創作者!
Sean Hsiao的沙龍 的其他內容
電動車龍頭 特斯拉 Tesla, Inc 相信大家一提到電動車就會直覺聯想到特斯拉,特斯拉到目前為止也是全球電動車銷量冠軍,他的出現以及科技創新也對全球車市以及對傳統車廠帶來一定的壓力與影響,也讓我們消費者多了更多選擇,這邊分享一下在現任CEO, Elon Musk 接手特斯拉之前,之前的創辦人Ma
FIFA World Cup Qatar 2022 四年一度的世界盃今天在卡達開啟序幕,地主隊卡達對上厄瓜多開賽不到五分鐘 馬上就遇到經典問題,什麼是越位? 足球比賽中,進攻一方在踢或觸及球的瞬間(球門球、角球和界外擲球除外),進攻方球員比對方球員(守門員除外)離對方球門線更近,而且有干擾對方、干
電動車龍頭 特斯拉 Tesla, Inc 相信大家一提到電動車就會直覺聯想到特斯拉,特斯拉到目前為止也是全球電動車銷量冠軍,他的出現以及科技創新也對全球車市以及對傳統車廠帶來一定的壓力與影響,也讓我們消費者多了更多選擇,這邊分享一下在現任CEO, Elon Musk 接手特斯拉之前,之前的創辦人Ma
FIFA World Cup Qatar 2022 四年一度的世界盃今天在卡達開啟序幕,地主隊卡達對上厄瓜多開賽不到五分鐘 馬上就遇到經典問題,什麼是越位? 足球比賽中,進攻一方在踢或觸及球的瞬間(球門球、角球和界外擲球除外),進攻方球員比對方球員(守門員除外)離對方球門線更近,而且有干擾對方、干
你可能也想看
Google News 追蹤
Thumbnail
徵的就是你 🫵 超ㄅㄧㄤˋ 獎品搭配超瞎趴的四大主題,等你踹共啦!還有機會獲得經典的「偉士牌樂高」喔!馬上來參加本次的活動吧!
Thumbnail
隨著理財資訊的普及,越來越多台灣人不再將資產侷限於台股,而是將視野拓展到國際市場。特別是美國市場,其豐富的理財選擇,讓不少人開始思考將資金配置於海外市場的可能性。 然而,要參與美國市場並不只是盲目跟隨標的這麼簡單,而是需要策略和方式,尤其對新手而言,除了選股以外還會遇到語言、開戶流程、Ap
Thumbnail
從範例學python的目標讀者: 針對剛進入的初學者,想學習Python語言。 有基礎本數學邏輯基礎即可。 從小遊戲學python的目標讀者: 針對已經有經驗的C/C++, Python, 或其他有程式基礎的讀者。 想實作一些小專案,從實做中學習如何分析需求、元件分拆、到底層實作
Thumbnail
更快、更短、更即時是串流傳輸必要的元素, 而我們常常在使用Python請求API時都是等待式回應, 也就是一個請求過去之後, 待對方處理完畢後再行回應, 但假設需要下載的檔案、內容非常大時, 是不是使用者只能傻傻的等待整個傳輸結束後才能顯示? 這樣的使用者體驗也實在太糟糕了, 對於使用者來說除了完全
Thumbnail
前段時間我們有介紹「【Python 軍火庫🧨 - websockets】雙向溝通的渠道」, 這種方式可以達到基本的連線沒問題,但隨著資安意識的抬頭, 我們的websocket連線也會需要在通道之上進行加密, 那麼我們將根據使用情境來教您如何選用適當的連線。 Server端 我們的Serve
Thumbnail
logging 是 Python 中用於記錄程式運行時信息的模組,它可以幫助你在開發過程中更好地管理和追蹤程式的執行狀態和錯誤信息。 本文較著重使用兩種不同的方法來創建日誌紀錄。 其他有關logging的教學,我推薦以下文章,他介紹蠻詳細的,我就不多贅述了。
Thumbnail
我們在「【🔒 Python API框架篇 - FastAPI】Ep.1 啟航」有分享 FastAPI 這套API框架, 那麼當我們想要在應用程式剛執行時就註冊一些事件或者共享GPU運算模型、變數…等,當整個應用程式關閉時也進行釋放作業, 這樣的一個週期循環就是所謂的生命週期, 而在FastAPI這
Thumbnail
在Python中,queue是一個非常有用的模块。 它提供了多種佇列(queue)實現,用於在多線程環境中安全地交換信息或者數據。 佇列(queue)是一種先進先出(FIFO)的數據結構,允許在佇列的一端插入元素,另一端取出元素。(FIFO 是First In, First Out 的縮寫)
Thumbnail
當我們在撰寫一套系統的時候, 總是會提供一個介面讓使用者來觸發功能模組並回傳使用者所需的請求, 而傳統的安裝包模式總是太侷限, 需要個別主機獨立安裝, 相當繁瑣, 但隨著時代的演進與互聯網的崛起, 大部分的工作都可以藉由網頁端、裝置端來觸發, 而伺服端則是負責接收指令、運算與回傳結果, 雲端
Thumbnail
Python 產生器(Generator)是一種特殊的迭代器,能夠以更有效率的方式處理大量數據。本文將介紹產生器的基礎概念、使用方法,並提供實際應用範例
Thumbnail
徵的就是你 🫵 超ㄅㄧㄤˋ 獎品搭配超瞎趴的四大主題,等你踹共啦!還有機會獲得經典的「偉士牌樂高」喔!馬上來參加本次的活動吧!
Thumbnail
隨著理財資訊的普及,越來越多台灣人不再將資產侷限於台股,而是將視野拓展到國際市場。特別是美國市場,其豐富的理財選擇,讓不少人開始思考將資金配置於海外市場的可能性。 然而,要參與美國市場並不只是盲目跟隨標的這麼簡單,而是需要策略和方式,尤其對新手而言,除了選股以外還會遇到語言、開戶流程、Ap
Thumbnail
從範例學python的目標讀者: 針對剛進入的初學者,想學習Python語言。 有基礎本數學邏輯基礎即可。 從小遊戲學python的目標讀者: 針對已經有經驗的C/C++, Python, 或其他有程式基礎的讀者。 想實作一些小專案,從實做中學習如何分析需求、元件分拆、到底層實作
Thumbnail
更快、更短、更即時是串流傳輸必要的元素, 而我們常常在使用Python請求API時都是等待式回應, 也就是一個請求過去之後, 待對方處理完畢後再行回應, 但假設需要下載的檔案、內容非常大時, 是不是使用者只能傻傻的等待整個傳輸結束後才能顯示? 這樣的使用者體驗也實在太糟糕了, 對於使用者來說除了完全
Thumbnail
前段時間我們有介紹「【Python 軍火庫🧨 - websockets】雙向溝通的渠道」, 這種方式可以達到基本的連線沒問題,但隨著資安意識的抬頭, 我們的websocket連線也會需要在通道之上進行加密, 那麼我們將根據使用情境來教您如何選用適當的連線。 Server端 我們的Serve
Thumbnail
logging 是 Python 中用於記錄程式運行時信息的模組,它可以幫助你在開發過程中更好地管理和追蹤程式的執行狀態和錯誤信息。 本文較著重使用兩種不同的方法來創建日誌紀錄。 其他有關logging的教學,我推薦以下文章,他介紹蠻詳細的,我就不多贅述了。
Thumbnail
我們在「【🔒 Python API框架篇 - FastAPI】Ep.1 啟航」有分享 FastAPI 這套API框架, 那麼當我們想要在應用程式剛執行時就註冊一些事件或者共享GPU運算模型、變數…等,當整個應用程式關閉時也進行釋放作業, 這樣的一個週期循環就是所謂的生命週期, 而在FastAPI這
Thumbnail
在Python中,queue是一個非常有用的模块。 它提供了多種佇列(queue)實現,用於在多線程環境中安全地交換信息或者數據。 佇列(queue)是一種先進先出(FIFO)的數據結構,允許在佇列的一端插入元素,另一端取出元素。(FIFO 是First In, First Out 的縮寫)
Thumbnail
當我們在撰寫一套系統的時候, 總是會提供一個介面讓使用者來觸發功能模組並回傳使用者所需的請求, 而傳統的安裝包模式總是太侷限, 需要個別主機獨立安裝, 相當繁瑣, 但隨著時代的演進與互聯網的崛起, 大部分的工作都可以藉由網頁端、裝置端來觸發, 而伺服端則是負責接收指令、運算與回傳結果, 雲端
Thumbnail
Python 產生器(Generator)是一種特殊的迭代器,能夠以更有效率的方式處理大量數據。本文將介紹產生器的基礎概念、使用方法,並提供實際應用範例