在前面幾篇文章中襟沮,只介紹了如何創(chuàng)建Locust類身辨、TaskSet類去模擬用戶障簿,本文介紹如何對(duì)提供HTTP接口的系統(tǒng)進(jìn)行壓力測(cè)試馒铃。Locust已經(jīng)有HttpLocust
類蟹腾,每個(gè)HttpLocust
類的實(shí)例都有一個(gè)client
屬性用于構(gòu)造HTTP請(qǐng)求。
HttpLocust類
一個(gè)HttpLocust類的實(shí)例可以表示一組用于HTTP壓力測(cè)試的“用戶”区宇,該用戶的行為由task_set
屬性定義娃殖,這些與父類Locust
類都一致。
HttpLocust類有個(gè)額外的client
屬性议谷,用于建立與保持HTTP請(qǐng)求會(huì)話炉爆。熟悉Python的朋友一般都知道requests
庫,HttpLocust類的client正是封裝了該庫,用法基本一致芬首。
當(dāng)你的Locust類繼承自HttpLocust鲫凶,那你指向的TaskSet可以直接使用client屬性發(fā)起HTTP請(qǐng)求,下面是一個(gè)例子衩辟,可以用來對(duì)/和/about兩個(gè)URL進(jìn)行壓力測(cè)試:
from locust import HttpLocust, TaskSet, task
class MyTaskSet(TaskSet):
@task(2)
def index(self):
self.client.get("/")
@task(1)
def about(self):
self.client.get("/about/")
class MyLocust(HttpLocust):
task_set = MyTaskSet
min_wait = 5000
max_wait = 15000
上面的示例代碼中,每個(gè)模擬用戶在5-15秒的等待間隔會(huì)發(fā)起一次請(qǐng)求波附,task的權(quán)重顯示了對(duì)URL / 的請(qǐng)求會(huì)是 /about 的兩倍艺晴。
有心的讀者會(huì)發(fā)現(xiàn),我們可以在TaskSet中直接使用self.client調(diào)用HttpSession掸屡,而不是self.locust.client封寞。這是因?yàn)闉榱擞脩舴奖悖?code>TaskSet類中的self.client已經(jīng)直接指向self.locust.client。
HTTP client基本用法
在client屬性中,每個(gè)HttpLocust實(shí)例都有一個(gè)HttpSession
實(shí)例仅财。 HttpSession類實(shí)際上是requests.Session
的一個(gè)子類狈究,可用于發(fā)出get
,post
盏求,put
抖锥,delete
,head
碎罚,patch
和options
等HTTP請(qǐng)求并報(bào)告給Locust的用于統(tǒng)計(jì)磅废。 HttpSession實(shí)例會(huì)在請(qǐng)求之間保存cookie,以便它可以用來登錄網(wǎng)站荆烈、保持請(qǐng)求會(huì)話拯勉。
下面是一個(gè)簡(jiǎn)單的例子,它向 /about 發(fā)出GET請(qǐng)求(假設(shè)self是TaskSet或HttpLocust類的實(shí)例:
response = self.client.get("/about")
print("Response status code:", response.status_code)
print("Response content:", response.text)
下面是POST請(qǐng)求的例子:
response = self.client.post("/login", {"username":"testuser", "password":"secret"})
人為標(biāo)記成功失敗
默認(rèn)情況下憔购,Locust將HTTP響應(yīng)碼為OK(2xx)的請(qǐng)求標(biāo)記為成功宫峦,其他的就標(biāo)記為失敗∶的瘢可能大多數(shù)時(shí)候這種處理方式就是我們想要的导绷,但是有的時(shí)候就是想測(cè)試返回404的情況呢?或者server在返回錯(cuò)誤時(shí)屎飘,錯(cuò)誤信息在響應(yīng)的消息體中而不體現(xiàn)在響應(yīng)碼诵次,這些情況的處理就需要手動(dòng)控制成功/失敗。
使用catch_response參數(shù)和with枚碗,可以獲取response的內(nèi)容并標(biāo)記失斢庖弧:
with client.get("/", catch_response=True) as response:
if response.content != b"Success":
response.failure("Got wrong response")
正如可以將請(qǐng)求OK響碼標(biāo)記為失敗一樣,用catch_response參數(shù)與with語句也可以將請(qǐng)求不為2xx的響應(yīng)碼標(biāo)記為成功:
with client.get("/does_not_exist/", catch_response=True) as response:
if response.status_code == 404:
response.success()
設(shè)置檢查點(diǎn)
Locust中設(shè)置檢查點(diǎn)是很簡(jiǎn)單的肮雨,可以直接用assert設(shè)置檢查點(diǎn)遵堵,對(duì)response的內(nèi)容檢查,并輸出錯(cuò)誤信息:
response = self.client.get('/test_assert')
assert '‘success' in response.content, "Respense error: " + response
動(dòng)態(tài)參數(shù)請(qǐng)求分組
網(wǎng)站的實(shí)參(Query String)經(jīng)常是動(dòng)態(tài)的,比如/blog?id=diff_id陌宿,一次查詢一個(gè)新的id锡足,如果不指定分組,在Locust的測(cè)試結(jié)果中和會(huì)看到默認(rèn)以"/blog?id=diff_id"的很多分組壳坪,而這些請(qǐng)求都是在測(cè)試獲取某個(gè)id的blog舶得,其實(shí)可以被分為一組。
通過給client傳入name參數(shù)能夠?qū)崿F(xiàn)分組:
# 這些id不同的請(qǐng)求都會(huì)被分組到 /blog/?id=[id] 中
for i in range(10):
client.get("/blog?id=%i" % i, name="/blog?id=[id]")