Locust的使用

轉(zhuǎn)自 (https://www.cnblogs.com/qingchengzi/p/9505548.html

啟動(dòng):

終端中--->進(jìn)入到代碼目錄: locust -f xxxoo.py --host=xxxxx.com

  • -f 指定性能測(cè)試腳本文件
  • -host 被測(cè)試應(yīng)用的URL地址【如果不填寫,讀取繼承(HttpLocust)類中定義的host】
  • 通過(guò)瀏覽器訪問:http://localhost:8089(Locust啟動(dòng)網(wǎng)絡(luò)監(jiān)控器,默認(rèn)為端口號(hào)為:8089)

Number of users to simulate 設(shè)置虛擬用戶數(shù)
Hatch rate(users spawned/second)每秒產(chǎn)生(啟動(dòng))的虛擬用戶數(shù)
點(diǎn)擊Start swarming 按鈕,開始運(yùn)行性能測(cè)試。

no-web模式運(yùn)行啟動(dòng)

 終端中-->進(jìn)入代碼目錄:>> locust -f xxoo.py  --no-web -c10  -r2 -t 1m

啟動(dòng)參數(shù):

    --no-web   表示不使用web界面運(yùn)行測(cè)試。  -c 設(shè)置虛擬用戶數(shù) 。  -r 設(shè)置每秒啟動(dòng)虛擬用戶數(shù)  。 -t  設(shè)置運(yùn)行時(shí)間.。

no-web模式運(yùn)行將測(cè)試結(jié)果保存到當(dāng)前.py目錄中:locust -f xxoo.py --csv=起一個(gè)名字 

例如:

      locust -f test3.py --csv=foobar --no-web -c2 -t10s

分布式壓測(cè):

      主從機(jī)中必須運(yùn)行相同的測(cè)試代碼(把主機(jī)中代碼復(fù)制一份到多個(gè)從機(jī)中),主機(jī)負(fù)責(zé)收集測(cè)試數(shù)據(jù),從機(jī)進(jìn)行施壓測(cè)試;

      在主機(jī)終端中-->進(jìn)入代碼目錄:>> locust -f xxxoo.py --master

      從機(jī)中終端中-->進(jìn)入代碼目錄:>> locust -f  xxxoo.py --slave --master-host=主機(jī)ip 

      分布式壓測(cè)no-web模式保存結(jié)果到主機(jī)中當(dāng)前運(yùn)行.py的目錄中:>>locust -f test2.py  --csv=foobartt --no-web -c2 -t10s --master

locust --help 查看幫助信息

概述:
Locust寓意蝗蟲,蝗蟲過(guò)境,寸草不生;而Locust工具生成并發(fā)請(qǐng)求就和一大群蝗蟲一般,向我們的被測(cè)系統(tǒng)發(fā)起攻擊,以此測(cè)試系統(tǒng)在高并發(fā)壓力下是否能正常運(yùn)轉(zhuǎn)。

Locust測(cè)試框架中,采用python進(jìn)行開發(fā),對(duì)常見的http(s)協(xié)議的系統(tǒng),Locust采用request庫(kù)作為客戶端,在發(fā)請(qǐng)求時(shí)和request庫(kù)使用方法一樣。

在模擬并發(fā)時(shí),Locust采用協(xié)程、非阻塞IO來(lái)實(shí)現(xiàn)網(wǎng)絡(luò)層的并發(fā)請(qǐng)求,因此單臺(tái)壓力機(jī)也能產(chǎn)生數(shù)千并發(fā)請(qǐng)求,再加上對(duì)分布式運(yùn)行的支持,Locust能在使用較少壓力機(jī)的前提下支持極高的并發(fā)數(shù)測(cè)試。

實(shí)例腳本

from locust import HttpLocust, TaskSet, task

class WebsiteTasks(TaskSet):
  def on_start(self):   #進(jìn)行初始化的工作,每個(gè)Locust用戶開始做的第一件事
      payload = {
          "username": "test_user",
          "password": "123456",
      }
      header = {
          "User-Agent":"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36",
      }
      self.client.post("/login",data=payload,headers=header)#self.client屬性使用Python request庫(kù)的所有方法,調(diào)用和使用方法和requests完全一致;

  @task(5)    #通過(guò)@task()裝飾的方法為一個(gè)事務(wù),方法的參數(shù)用于指定該行為的執(zhí)行權(quán)重,參數(shù)越大每次被虛擬用戶執(zhí)行的概率越高,默認(rèn)為1
  def index(self):
      self.client.get("/")

  @task(1)
  def about(self):
      self.client.get("/about/")

class WebsiteUser(HttpLocust):
  host     = "https://github.com/" #被測(cè)系統(tǒng)的host,在終端中啟動(dòng)locust時(shí)沒有指定--host參數(shù)時(shí)才會(huì)用到
  task_set = WebsiteTasks          #TaskSet類,該類定義用戶任務(wù)信息,必填。這里就是:WebsiteTasks類名,因?yàn)樵擃惱^承TaskSet;
  min_wait = 5000  #每個(gè)用戶執(zhí)行兩個(gè)任務(wù)間隔時(shí)間的上下限(毫秒),具體數(shù)值在上下限中隨機(jī)取值,若不指定默認(rèn)間隔時(shí)間固定為1秒
  max_wait = 15000

偽代碼中對(duì)https://github.com/網(wǎng)站的測(cè)試場(chǎng)景,先模擬用戶登錄系統(tǒng),然后隨機(jī)訪問首頁(yè)/和/about/,請(qǐng)求比例5:1,并且在測(cè)試過(guò)程中,兩次請(qǐng)求的間隔時(shí)間1-5秒的隨機(jī)值;
on_start方法,在正式執(zhí)行測(cè)試前執(zhí)行一次,主要用于完成一些初始化的工作,例如登錄操作;

WebsiteTasks類中如何去調(diào)用 WebsiteUser(HttpLocust)類中定義的字段和方法呢?

通過(guò)在WebsiteTasks類中self.locust.xxoo xxoo就是我們?cè)赪ebsiteUser類中定義的字段或方法;

偽代碼:

from locust import HttpLocust, TaskSet, task
import hashlib
import queue
 
class WebsiteTasks(TaskSet):
 
    @task(5)
    def index(self):
        data = self.locust.user_data_queue  #獲取WebsiteUser里面定義的ser_data_queue隊(duì)列
        md5_data=self.locust.md5_encryption() #獲取WebsiteUser里面定義的md5_encryption()方法
        self.client.get("/")
 
class WebsiteUser(HttpLocust):
    host     = "https://github.com/"
    task_set = WebsiteTasks
    min_wait = 5000
    max_wait = 15000
    user_data_queue = queue.Queue()
 
    def md5_encryption(self,star):
         '''md5加密方法'''
         obj    = hashlib.md5()
         obj.update(bytes(star,encoding="utf-8"))
         result = obj.hexdigest()
         return result

偽代碼中測(cè)試場(chǎng)景如何表達(dá)?

代碼主要包含兩個(gè)類:

WebsiteUser繼承(HttpLocust,而HttpLocust繼承自Locust)
WebsiteTasks繼承(TaskSet)
在Locust測(cè)試腳本中,所有業(yè)務(wù)測(cè)試場(chǎng)景都是在Locust和TaskSet兩個(gè)類的繼承子類中進(jìn)行描述;

簡(jiǎn)單說(shuō):Locust類就類似一群蝗蟲,而每只蝗蟲就是一個(gè)類的實(shí)例。TaskSet類就類似蝗蟲的大腦,控制蝗蟲的具體行為,即實(shí)際業(yè)務(wù)場(chǎng)景測(cè)試對(duì)應(yīng)的任務(wù)集;

在Locust類中,靜態(tài)字段client即客戶端的請(qǐng)求方法,這里的client字段沒有綁定客戶端請(qǐng)求方法,因此在使用Locust時(shí),需要先繼承Locust類class HttpLocust(Locust),然后在self.client = HttpSession(base_url=self.host)綁定客戶端請(qǐng)求方法;

對(duì)于常見的HTTP(s)協(xié)議,Locust已經(jīng)實(shí)現(xiàn)了HttpLocust類,其self.client=HttpSession(base_url=self.host),而HttpSession繼承自requests.Session。因此在測(cè)試HTTP(s)的Locust腳本中,可以通過(guò)client屬性來(lái)使用Python requests庫(kù)的所 有方法,調(diào)用方式與 reqeusts完全一致。另外,由于requests.Session的使用,client的方法調(diào)用之間就自動(dòng)具有了狀態(tài)記憶功能。常見的場(chǎng)景就是,在登錄系統(tǒng)后可以維持登錄狀態(tài)的Session,從而后續(xù)HTTP請(qǐng)求操作都能帶上登錄狀態(tài);

Locust類中,除了client屬性,還有幾個(gè)屬性需要關(guān)注:

task_set ---> 指向一個(gè)TaskSet類,TaskSet類定義了用戶的任務(wù)信息,該靜態(tài)字段為必填;
max_wait/min_wait ---> 每個(gè)用戶執(zhí)行兩個(gè)任務(wù)間隔的上下限(毫秒),具體數(shù)值在上下限中隨機(jī)取值,若不指定則默認(rèn)間隔時(shí)間為1秒;
host --->被測(cè)試系統(tǒng)的host,當(dāng)在終端中啟動(dòng)locust時(shí)沒有指定--host參數(shù)時(shí)才會(huì)用到;
weight--->同時(shí)運(yùn)行多個(gè)Locust類時(shí),用于控制不同類型的任務(wù)執(zhí)行權(quán)重;
Locust流程,測(cè)試開始后,每個(gè)虛擬用戶(Locust實(shí)例)運(yùn)行邏輯都會(huì)遵守如下規(guī)律:

先執(zhí)行WebsiteTasks中的on_start(只執(zhí)行一次),作為初始化;
從WebsiteTasks中隨機(jī)挑選(如果定義了任務(wù)間的權(quán)重關(guān)系,那么就按照權(quán)重關(guān)系隨機(jī)挑選)一個(gè)任務(wù)執(zhí)行;
根據(jù)Locust類中min_wait和max_wait定義的間隔時(shí)間范圍(如果TaskSet類中也定義了min_wait或者max_wait,以TaskSet中的優(yōu)先),在時(shí)間范圍中隨機(jī)取一個(gè)值,休眠等待;
重復(fù)2~3步驟,直到測(cè)試任務(wù)終止;
TaskSet類實(shí)現(xiàn)了虛擬用戶所執(zhí)行任務(wù)的調(diào)度算法,包括規(guī)劃任務(wù)執(zhí)行順序(schedule_task)、挑選下一個(gè)任務(wù)(execute_next_task)、執(zhí)行任務(wù)(execute_task)、休眠等待(wait)、中斷控制(interrupt)等待。在此基礎(chǔ)上,就可以在TaskSet子類中采用非常簡(jiǎn)潔的方式來(lái)描述虛擬用戶的業(yè)務(wù)測(cè)試場(chǎng)景,對(duì)虛擬用戶的所有行為進(jìn)行組織和描述,并可以對(duì)不同任務(wù)的權(quán)重進(jìn)行配置。
@task
通過(guò)@task()裝飾的方法為一個(gè)事務(wù)。方法的參數(shù)用于指定該行為的執(zhí)行權(quán)重。參數(shù)越大每次被虛擬用戶執(zhí)行的概率越高。如果不設(shè)置默認(rèn)為1。
TaskSet子類中定義任務(wù)信息時(shí),采取兩種方式:@task裝飾器和tasks屬性。
采用@task裝飾器定義任務(wù)信息時(shí):

from locust import TaskSet, task

class UserBehavior(TaskSet):
    @task(1)
    def test_job1(self):
        self.client.get('/test1')

    @task(3)
    def test_job2(self):
        self.client.get('/test2')

采用tasks屬性定義任務(wù)信息時(shí)

from locust import TaskSet

def test_job1(obj):
    obj.client.get('/test1')

def test_job2(obj):
    obj.client.get('/test2')

class UserBehavior(TaskSet):
    tasks = {test_job1:1, test_job2:3}
    # tasks = [(test_job1,1), (test_job1,3)] # 兩種方式等價(jià)

上面兩種定義任務(wù)信息方式中,均設(shè)置了權(quán)重屬性,即執(zhí)行test_job2的頻率是test_job1的兩倍。

若不指定,默認(rèn)比例為1:1。

關(guān)聯(lián):
在某些請(qǐng)求中,需要攜帶之前response中提取的參數(shù),常見場(chǎng)景就是session_id。Python中可用通過(guò)re正則匹配,對(duì)于返回的html頁(yè)面,可用采用lxml庫(kù)來(lái)定位獲取需要的參數(shù);

from locust import HttpLocust, TaskSet, task
from lxml import etree

class WebsiteTasks(TaskSet):

    def get_session(self,html): #關(guān)聯(lián)例子
        tages = etree.HTML(html)
        return tages.xpath("http://div[@class='btnbox']/input[@name='session']/@value")[0]

    def on_start(self):
        html = self.client.get('/index')
        session = self.get_session(html.text)
        payload = {
            "username": "test_user",
            "password": "123456",
            'session' : session
        }
        header = {
            "User-Agent":"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36",
        }
        self.client.post("/login",data=payload,headers=header)

    @task(5)
    def index(self):
        self.client.get("/")
        assert response['ErrorCode']==0   #斷言

    @task(1)
    def about(self):
        self.client.get("/about/")

class WebsiteUser(HttpLocust):
    host     = "https://github.com/"
    task_set = WebsiteTasks
    min_wait = 5000
    max_wait = 15000
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Locust是什么? Locust 是一個(gè)開源負(fù)載測(cè)試工具。使用 Python 代碼定義用戶行為,也可以仿真百萬(wàn)個(gè)...
    zychen143閱讀 7,404評(píng)論 1 2
  • 安裝 locust官方介紹https://locust.io/ ① 可以直接通過(guò)pip安裝,安裝命令 pip in...
    滾滾圓閱讀 1,497評(píng)論 0 0
  • 一、概述Locust的原意是蝗蟲,作者之所以選擇這個(gè)名字,是因?yàn)長(zhǎng)ocust工具生成的并發(fā)請(qǐng)求就跟一大群蝗蟲一樣,...
    jinjin1009閱讀 1,944評(píng)論 0 0
  • 最近一直在使用Locust進(jìn)行壓力測(cè)試,因此想總結(jié)一下學(xué)習(xí)和實(shí)踐的一些成果。Locust官方文檔 版本:pytho...
    禾苗zj閱讀 8,464評(píng)論 0 4
  • locustfile.py 是 locust 運(yùn)行的腳本文件,就像 jmeter 的 jmx 文件一樣。 locu...
    貓與測(cè)試閱讀 2,790評(píng)論 0 2

友情鏈接更多精彩內(nèi)容