1、JMeter和Locust的對比說明
1)開源許可證
工具許可范圍的問題是最重要的問題之一,因為您可能想知道是否需要支付額外的第三方工具來完成負載測試。 如果某個工具是開源的,那么您幾乎可以實現為性能測試設置的任何目標,而無需任何額外付款。 開源JMeter和Locust也不例外。
JMeter和Locust都提供了許可軟件許可證,該許可證支持免費軟件,對軟件的分發方式提出最低要求。 JMeter是由Apache開發的,它基於Apache License 2.0,而Locust是由一個由社區驅動的開發人員組成的小團隊開發的 ,基於MIT許可證。 在這兩種情況下,這些工具都是開源的,允許您自由使用它們,而不受任何使用限制。
2)負載測試創建和維護
性能測試工作流程有三個主要步驟:創建,運行和分析。 一般第一步是最耗時的。
編寫JMeter性能測試的最常用方法是使用其GUI模式。 JMeter GUI模式提供了一個桌面客戶端,允許您輕松創建測試,而無需編寫單行代碼(直到您需要創建棘手的測試)。 所以最簡單的場景可能如下所示:
JMeter非常簡單,通常,即使是沒有經驗的工程師也可以毫無困難地上手。但是如果需要,您可以使用Java在GUI和非GUI模式下使用代碼。 但是,由於腳本實現的復雜性(因為JMeter旨在與GUI模式一起使用)以及缺乏如何制作此類腳本的文檔,因此這種方式在JMeter社區中並不流行。
Locust則需要python編程基礎。
3)支持的協議
理想情況下,您應該能夠使用盡可能少的工具測試所有工具,只要它不會影響測試質量。
使用JMeter,您可以使用完整的內置函數和第三方插件,在一個地方創建所有內容的性能測試。 您無需編碼即可測試不同的協議甚至數據庫。 這些包括JDBC,FTP,LDAP,SMTP等。JMeter還可以通過jar包擴展,比如加載jython,可以使用python腳本。
根據文檔,Locust主要用於基於HTTP Web的測試。但可以擴展其默認功能並創建自定義Python函數來測試可以使用Python編程語言進行測試的任何內容。
4)並發用戶數
JMeter和Locust有完全不同的方式來處理機器資源。 JMeter有一個基於線程的模型,它為每個用戶分配一個單獨的線程。 每個步驟的線程分配和基准測試需要大量資源,這就是為什么JMeter對於您可以在一台機器上模擬的用戶數量非常有限的原因。 您可以在一台計算機上運行的用戶數取決於許多因素,如腳本復雜性,硬件,響應大小等。 如果您的腳本很簡單,JMeter允許您在一台機器上運行多達數千個,但腳本執行逐漸變得不可靠。
Locust有完全不同的用戶模擬模型,它基於事件和異步方法(協程),以gevent coroutine作為整個過程的基石。 這種實現允許Locust框架在一台機器上輕松模擬數千個並發用戶,即使是在非常規的筆記本電腦上,也可同時運行內部有許多步驟的復雜測試。
5)增強靈活性
這兩個工具提供相對相同的生成負載的方式 - 您可以指定在性能測試期間要使用的用戶數以及它們應該加速的速度。
在JMeter中,您可以在指定字段的“線程組”控制器中配置負載:但是JMeter還有其他插件,可以讓您配置非常靈活的負載。 最好的方法之一是使用Ultimate Thread Group ,它允許用戶制作非常具體的加載模式:
Locust有不同的方法。 當您運行性能腳本時,Locust會自動在http://localhost:8089上啟動Web界面的服務器,該界面為您提供僅指定線性負載的輸入元素, 當然也可以命令行執行通過參數定制。
6)腳本錄制
這是JMeter具有強大優勢的地方,因為它具有腳本錄制的內置功能,而Locust根本沒有此功能。 除此之外,還有許多第三方插件可以為JMeter制作腳本錄制。 記錄此類腳本最方便的方法之一是使用BlazeMeter chrome擴展。
7)測試監控
JMeter和Locust都提供了強大的內置功能來監控性能腳本並分析您的測試結果。 JMeter有許多不同的元素叫做監聽器。 每個偵聽器都提供特定類型的監視,你也可以使用許多現有的自定義監聽器擴展默認庫。另一方面,JMeter監聽器在其運行的機器上消耗大量資源。這就是為什么通常,JMeter是以非GUI模式執行的,沒有任何監聽器或監控過程,在這種情況下,可使用3方工具,如BlazeMeter 。
Locust的監測能力稍弱,不過幾乎提供了所有可用於監控基本負載的信息。在腳本運行期間,Locust運行一個簡單的Web服務器,
2、編寫Locust示例代碼
locust_sample.py
from locust import HttpUser, TaskSet, task
class WebsiteTasks(TaskSet):
def on_start(self):
self.client.post("/login", { "username": "test", "password": "123456" })
@task(2)
def index(self):
self.client.get("/")
@task(1)
def about(self):
self.client.get("/about/")
tasks = {index: 2, about: 1} # 與裝飾器效果一致
class WebsiteUser(HttpUser):
# task_set = WebsiteTasks # Usage of User.task_set is deprecated since version 1.0. Set the tasks attribute instead (tasks = [WebsiteTasks])
tasks = [WebsiteTasks]
host = "http://debugtalk.com"
min_wait = 1000
max_wait = 5000
啟動測試:locust -H http://debugtalk.com -f locust_sample.py
3、Locust類詳細講解
在Locust類中,具有一個client屬性,它對應着虛擬用戶作為客戶端所具備的請求能力,也就是我們常說的請求方法。通常情況下,我們不會直接使用Locust類,因為其client屬性沒有綁定任
何方法。因此在使用Locust時,需要先繼承Locust類,然后在繼承子類中的client屬性中綁定客戶端的實現類。對於常見的HTTP(S)協議,Locust已經實現了HttpUser(1.0之前使用HttpLocust)類,其client屬性綁
定了HttpSession類,而HttpSession又繼承自requests.Session。因此在測試HTTP(S)的Locust腳本中,我們可以通過client屬性來使用Python requests庫的所有方法,包括
GET/POST/HEAD/PUT/DELETE/PATCH等,調用方式也與requests完全一致。另外,由於requests.Session的使用,因此client的方法調用之間就自動具有了狀態記憶的功能。常見的場景
就是,在登錄系統后可以維持登錄狀態的Session,從而后續HTTP請求操作都能帶上登錄態。而對於HTTP(S)以外的協議,我們同樣可以使用Locust進行測試,只是需要我們自行實現客戶端
。在客戶端的具體實現上,可通過注冊事件的方式,在請求成功時觸發events.request_success,在請求失敗時觸發events.request_failure即可。然后創建一個繼承自Locust類的類,對其
設置一個client屬性並與我們實現的客戶端進行綁定。后續,我們就可以像使用HttpUser類一樣,測試其它協議類型的系統。
原理就是這樣簡單!
在Locust類中,除了client屬性,還有幾個屬性需要關注下:
-
tasks(1.0以下是task_set): tasks = [WebsiteTasks] Collection of python callables and/or TaskSet classes that the Locust user(s) will run.指向一個TaskSet類的列表,TaskSet類定義了用戶的任務信息,該屬性為必填;**
-
max_wait/min_wait: 每個用戶執行兩個任務間隔時間的上下限(毫秒),具體數值在上下限中隨機取值,若不指定則默認間隔時間固定為1秒;
-
host:被測系統的host,當在終端中啟動locust時沒有指定--host參數時才會用到;
-
weight:同時運行多個Locust類時會用到,用於控制不同類型任務的執行權重。
測試開始后,每個虛擬用戶(Locust實例)的運行邏輯都會遵循如下規律:
-
先執行WebsiteTasks中的on_start(只執行一次),作為初始化;
-
從WebsiteTasks中隨機挑選(如果定義了任務間的權重關系,那么就是按照權重關系隨機挑選)一個任務執行;
-
根據Locust類中min_wait和max_wait定義的間隔時間范圍(如果TaskSet類中也定義了min_wait或者max_wait,以TaskSet中的優先),在時間范圍中隨機取一個值,休眠等待;
-
重復2~3步驟,直至測試任務終止。
4、TaskSet類詳細講解
性能測試工具要模擬用戶的業務操作,就需要通過腳本模擬用戶的行為。在前面的比喻中說到,TaskSet類好比蝗蟲的大
腦,控制着蝗蟲的具體行為。
具體地,TaskSet類實現了虛擬用戶所執行任務的調度算法,包括規划任務執行順序(schedule_task)、挑選下一個任
務(execute_next_task)、執行任務(execute_task)、休眠等待(wait)、中斷控制(interrupt)等等。在此基
礎上,我們就可以在TaskSet子類中采用非常簡潔的方式來描述虛擬用戶的業務測試場景,對虛擬用戶的所有行為(任務
)進行組織和描述,並可以對不同任務的權重進行配置。
在TaskSet子類中定義任務信息時,可以采取兩種方式,@task裝飾器和tasks屬性。
采用@task裝飾器定義任務信息時,描述形式如下:
class WebsiteTasks(TaskSet):
def on_start(self):
self.client.post("/login", { "username": "test", "password": "123456" })
@task(2)
def index(self):
self.client.get("/")
@task(1)
def about(self):
self.client.get("/about/")
采用tasks屬性定義任務信息時,描述形式如下:
class WebsiteTasks(TaskSet):
def on_start(self):
self.client.post("/login", { "username": "test", "password": "123456" })
# @task(2)
def index(self):
self.client.get("/")
# @task(1)
def about(self):
self.client.get("/about/")
tasks = {index: 2, about: 1} # 與裝飾器效果一致
在TaskSet子類中除了定義任務信息,還有一個是經常用到的,那就是on_start函數。這個和LoadRunner中的vuser_init功能相同,在正式執行測試前執行一
次,主要用於完成一些初始化的工作。例如,當測試某個搜索功能,而該搜索功能又要求必須為登錄態的時候,就可以先在on_start中進行登錄操作;前面也提 到,HttpUser使用到了requests.Session,因此后續所有任務執行過程中就都具有登錄態了。
5、實戰測試
1)測試代碼
from locust import HttpUser, TaskSet, task
class WebsiteTasks(TaskSet):
def on_start(self):
# self.client.post("/login", { "username": "test", "password": "123456" })
self.client.get("/login?key=00d91e8e0cca2b76f515926a36db68f5&phone=13594347817&passwd=123456")
# @task(2)
def videoCategory(self):
self.client.get("/videoCategory")
# @task(1)
def videoRecommend(self):
self.client.get("/videoRecommend?id=127398")
def todayVideo(self):
self.client.get("/todayVideo")
def getJoke(self):
self.client.get("/getJoke?page=1&count=2&type=video")
def novelSearchApi(self):
self.client.get("/searchPoetry?name=古風二首%20二")
tasks = {videoCategory: 2, videoRecommend: 1, todayVideo: 2, getJoke: 3, novelSearchApi: 2} # 與裝飾器效果一致
class WebsiteUser(HttpUser):
# https://blog.csdn.net/c__chao/article/details/78573737
# task_set = WebsiteTasks # Usage of User.task_set is deprecated since version 1.0. Set the tasks attribute instead (tasks = [WebsiteTasks])
tasks = [WebsiteTasks]
host = "https://api.apiopen.top"
min_wait = 1000
max_wait = 5000
2)測試結果截圖
①配置模擬的用戶數量、每秒增加的用戶數、測試地址
②運行時數據
③運行的異常信息
④下載運行結果
⑤TPS每秒請求數
⑥響應時間
⑦用戶數
3)測試時服務器的數據
后續在做記錄
個人博客 蝸牛