Python Locust性能測試框架實踐


[本文出自天外歸雲的博客園]

Locust的介紹

Locust是一個python的性能測試工具,你可以通過寫python腳本的方式來對web接口進行負載測試。

Locust的安裝

首先你要安裝python2.6以上版本,而且有pip工具。之后打開命令行,分別安裝locustio和pyzmq(命令如下):

pip install locustio
pip install pyzmq

之后我們就可以寫性能測試腳本了。

PS:如果是python3,不能使用pip安裝目前。需要在github上下載locust項目包到本地,然后在包路徑下執行命令安裝:

python setup.py install

Locust腳本編寫

接下來我們拿兩個接口做一下測試,編寫腳本如下(每一步都有注釋)。我來解釋一下,首先我們要import進來三個類,分別是HttpLocust(用來模擬發請求的類)、TaskSet(顧名思義,任務集)、task(任務類)。額外的,為了方便觀察接口測試的執行結果,我引入了json類用來解析web接口的返回值。我還引入了subprocess類用來執行一下shell命令,自啟動Locust。這里有三個類,一個是UserBehavior(名字隨便起,但傳入TaskSet參數,說明這是一個包含了任務集的類),里面on_start函數可有可無,他會先於所有task函數運行。剩下被@task裝飾器裝飾的方法都是任務方法,里面包含了待請求的接口等信息,傳入的參數代表了權重,如下所示兩個被@task裝飾的方法分別傳入1和2,這意味着每3個模擬用戶里有1個模擬用戶執行list_header方法,2個模擬用戶執行list_goods方法。這個參數你也可以不傳入,那就意味着模擬用戶會隨機訪問所有被@task裝飾的方法。這里面我對於每個接口的返回值都做了一下判斷,首先將返回的字符串轉成json格式並獲取返回字段result的值,如果不是100就用Locust自帶的報錯方法打印出錯信息;另兩個類是HttpLocust類(仍然是名字隨便起但傳入參數必須得是HttpLocust),是用來模擬用戶的類,包含了一些模擬用戶信息,其中task_set變量的值用來指定模擬用戶所對應要完成的TaskSet類中包含的請求,min_wait和max_wait(最小等待時間和最大等待時間用來模擬用戶每兩步操作之間的間隔時間,這里也就是模擬用戶每執行兩個請求之間所間隔的時間)。對Locust類我們可以指定權重,對weight變量的值進行指定。如下所示,兩個Locust類的權重分別為1和3,這意味着兩個Locust類的模擬用戶人數為1:3的關系。最后我加了一個main函數用來執行shell命令,這個shell命令也可以不再本文件中執行,如果寫在腳本中的話,直接在命令行中調用該python文件即可,如果不寫在腳本中(注釋掉最后兩行),則需要在命令行終端里對Locust項目進行啟動。

from locust import HttpLocust,TaskSet,task
import subprocess
import json

#This is the TaskSet class.
class UserBehavior(TaskSet):
    #Execute before any task.
    def on_start(self):
        pass

    #the @task takes an optional weight argument.
    @task(1)
    def list_header(self):
        r = self.client.get("/homepage/list_header.html")
        if json.loads((r.content))["result"] != 100:
            r.failure("Got wrong response:"+r.content)

    @task(2)
    def list_goods(self):
        r = self.client.get("/homepage/list_goods.html")
        if json.loads((r.content))["result"] != 100:
            r.failure("Got wrong response:"+r.content)

#This is one HttpLocust class.
class WebUserLocust(HttpLocust):
    #Speicify the weight of the locust.
    weight = 1
    #The taskset class name is the value of the task_set.
    task_set = UserBehavior
    #Wait time between the execution of tasks.
    min_wait = 5000
    max_wait = 15000

#This is another HttpLocust class.
class MobileUserLocust(HttpLocust):
    weight = 3
    task_set = UserBehavior
    min_wait = 3000
    max_wait = 6000

#if __name__ == '__main__':
#    subprocess.Popen('locust -f .\locust_test_1.py --host=http://api.g.caipiao.163.com', shell=True)

Locust的啟動

對Locust項目的啟動,我們可以在命令行終端中執行以下命令:

locust -f .\locust_test_1.py --host=http://api.g.caipiao.163.com

這里的“-f”指定了要執行的python文件路徑,“--host”指定了模擬用戶請求接口的host名。執行該命令,Locust項目就啟動了。如果遇到下面的錯誤,注意[Errorno 10048]那行,可以看出端口8089被占用導致Locust項目啟動失敗,這里我們需要找到對應占用了8089端口的進程並殺掉:

為了檢測占用端口的進程我寫了一個PowerShell小腳本:

function checkPid($result,$port){
    $port = $port.split(":")[1]
    if(($result.split())[6].split(":")[($result.split())[6].split(":").Count-1] -eq $port){
        $tPid = ($result.split())[($result.split()).count-1]
        if($tPid -ne "0"){
            Write-Host "您查詢的端口被以下程序占用:" -ForegroundColor Red
            $target = tasklist|findstr $tPid
            Write-Host $target
            $sig = $true
        }else{
            $sig = $false
        } 
    }else{
        $sig = $false
    }
    $sig
}
function checkPort($port){
    $port = ":" + $port
    $results = netstat -ano|findstr $port
    if($results.count -gt 0){
        if($results.count -eq 1){
            $sig = checkPid $results $port
            if($sig -eq $false){
                Write-Host "您所查詢的端口未被占用!" -ForegroundColor Green
            }
        }else{
            foreach($result in $results){
                if($result){
                   $sig = checkPid $result $port
                   if($sig -eq $true){
                       break
                   }
                }
            }
            if($sig -eq $false){
                Write-Host "您所查詢的端口未被占用!" -ForegroundColor Green        
            }
        }
    }else{
        Write-Host "您所查詢的端口未被占用!" -ForegroundColor Green
    }
}
$port = $null
while($port -ne "exit()"){
    $port = Read-Host "請輸入要查詢的端口號"
    if($port -eq "exit()"){
        break
    }
    checkPort $port
}

運行該腳本,輸入端口號8089我們可以看出python.exe進程占用了該端口號:

然后我們在PowerShell中殺掉該進程,再啟動Locust項目,就成功了(如下):

接下來就可以在瀏覽器中訪問我們的locust頁面來完成負載測試了,如果不想通過瀏覽器來設置完成負載測試,純粹命令行模式也是支持的,輸入以下命令:

locust -f .\locust_test_1.py --host='http://api.winyyg.com' --no-web -c 1000 -r 10 -n 1000

接下來負載測試就會自動執行,按“ctrl+c”結束負載測試:

對於命令行中的參數的解釋:--no-web是用來選擇無瀏覽器模式,-c后面接的是模擬用戶數,-r后面接的每秒模擬用戶並發數,-n后面接的是模擬請求數。

Locust負載測試

在瀏覽器中輸入“http://localhost:8089/”訪問,會看到如下頁面:

這里我們按提示輸入要模擬的用戶總數和每秒鍾並發的用戶數量,點擊“Start swarming”就可以運行負載測試了:

點擊“STOP”按鈕停止負載測試,現在STATUS為“STOPPED”,點擊“New test”可以進行一個新的測試:

從上圖可以看出在Statistics標簽下列出了一些性能相關的測試結果,比如總的請求數量、請求失敗的個數、每秒鍾的請求數、最小\最大響應時間、平均響應時間等。右上角顯示了請求失敗率和總的RPS(每秒鍾請求數)。對應在Statistic右側的Failures、Exceptions、Download Data標簽下我們分別可以查看失敗的請求、捕獲的異常以及下載測試結果。這里不做過多介紹了,可以實際應用看一下。如果想深入的了解Locust性能測試框架,去官網上看看吧。


免責聲明!

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



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