1. 程式人生 > >Python Locust效能測試框架實踐

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效能測試框架,去官網上看看吧。