Python Locust性能測試框架實踐

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

Locust的介紹

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

Locust的安裝

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

pip install locustio
pip install pyzmq

以後咱們就能夠寫性能測試腳本了。github

PS:若是是python3,不能使用pip安裝目前。須要在github上下載locust項目包到本地,而後在包路徑下執行命令安裝:web

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項目進行啓動。shell

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項目的啓動,咱們能夠在命令行終端中執行如下命令:json

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

這裏的「-f」指定了要執行的python文件路徑,「--host」指定了模擬用戶請求接口的host名。執行該命令,Locust項目就啓動了。若是遇到下面的錯誤,注意[Errorno 10048]那行,能夠看出端口8089被佔用致使Locust項目啓動失敗,這裏咱們須要找到對應占用了8089端口的進程並殺掉:api

爲了檢測佔用端口的進程我寫了一個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性能測試框架,去官網上看看吧。

相關文章
相關標籤/搜索