編寫 bzt 腳本的正確姿勢

語言: CN / TW / HK

這是今年1月24日的舊文,發現沒在這裏發過,就搬運過來了。

聲明

  1. 本文討論的使用場景主要為 使用已有的 jmx 腳本,並配合 json 對 jmx 腳本進行部分參數的動態修改
  2. 只補充一些官方文檔上沒有提到的使用注意事項,所以官網上闡述得比較清楚的點,文章裏就不再贅述。

什麼是 bzt?

bzt,全名是 Blazemeter taurus ,是Blazemeter旗下的一款開源組件,官方宣稱此組件的底層依賴於 JMeterGatlingLocust.ioSelenium WebDriver ,並且經過了自動化程度高、可操作性好的封裝,使得性能測試與功能測試的過程變得更加簡單。

使用 bzt 壓測的基本流程

使用 bzt 中的 jmeter 引擎壓測,有兩種方式:

  1. 直接運行已有的 jmx 文件
    bzt example.jmx
  2. 利用 yaml 或者 json 生成一個 jmx 腳本並運行
    bzt example.yaml / bzt example.json

可以發現,其實 jmeter 裏運行的始終是 jmx 文件,只不過 bzt 對 jmx 文件做了一層包裝,使得沒有接觸過 jmeter 的用户也可以根據官方文檔的指引用 yaml/json 生成較為簡單的 jmx 腳本。

編寫腳本的注意事項

本文主要討論的使用場景來源於我們所開發的 TCPS 平台——用户上傳自己的 jmx 腳本,而用户每次運行腳本時都可能會修改這幾個值:①需要壓測的線程、②併發數和③壓測時長;另外在運行腳本前,用户還需要調試腳本,並得到請求的 response 數據。

1. 如何修改已有腳本的某項參數值

通過 bzt 所提供的 set-prop 參數,可以動態修改已有腳本的某些參數值,如圖:

但是官方文檔中沒有提到的事情有:

  1. 只能通過節點的 testname 識別到該節點。
  2. 當有多個節點的 testname 相同時,會修改所有擁有相同 testname 的節點的值
  3. 沒有辦法識別 jmx 的層級,如果需要區分兩個不同層級的節點,建議修改 testname

2. 如何選擇性地執行已有腳本的線程組?

圖中的紅框部分就是啟用部分線程組,禁用另一部分線程組,以達到動態選擇線程組去執行的目的。

語法格式很好明白,但是有那麼幾點注意事項:

  1. 通過 ThreadGroup 的 testname 去識別線程組,並且把該 ThreadGroup 節點的 enable 值設置為 true 或者 false ,如圖:

  2. 在設置 enable 的線程組數組時,如果腳本里有多個 testname 相同的線程組,有以下幾種情況:

    (1)這幾個線程組節點的 enable 值都為 false ;bzt 不會運行任何一個線程組

    (2)這幾個線程組節點的 enable 值有些為 false ,有些為 true ;bzt 只會運行 enable 值為 true 的線程組

    (3)這幾個線程組節點的 enable 值都為 true ;bzt 會運行全部線程組

  3. 在設置 disable 的線程組數組時,不管線程組原本的 enable 值為 true 或者 false ,都會被設置為 false

3. 如何查看具體的測試結果?

bzt 提供兩種查看結果的方式,分別是 xml 格式和 csv 格式。

查看 xml 結果

如果想得到 xml 格式的結果,具體的腳本設置如下:

{
    "execution": [
        {
            "write-xml-jtl": "error",
            "scenario": "example"
        }
    ],
    "scenarios": {
        "example": {
            "script": "example.jmx"
        }
    },
    "modules": {
        "jmeter": {
            "xml-jtl-flags": {
                "xml":`true`,
                "fieldNames":`true`,
                "time":`true`,
                "timestamp":`true`,
                "latency":`true`,
                "connectTime":`true`,
                "success":`true`,
                "label":`true`,
                "code":`true`,
                "message":`true`,
                "threadName":`true`,
                "dataType":`true`,
                "encoding":`true`,
                "assertions":`true`,
                "subresults":`true`,
                "responseData":`false`,
                "samplerData":`false`,
                "responseHeaders":`true`,
                "requestHeaders":`true`,
                "responseDataOnError":`true`,
                "saveAssertionResultsFailureMessage":`true`,
                "bytes":`true`,
                "threadCounts":`true`,
                "url":`true`
            }
        }
    }
}

其中 write-xml-jtl 的值有 error (默認值) 、 fullnone 三種,以下依次介紹三種情況。

  1. write-xml-jtl 的值為 error

    設置完成並運行後,會從項目文件夾裏得到 error.jtlkpi.jtl 兩個結果文件,如圖

    查看這兩個文件,裏面的內容分別是

    這是因為我測試的兩個接口都返回了404,而 write-xml-jtl 的值為 error 則表示把錯誤日誌以 xml 格式輸出。

  2. write-xml-jtl 的值為 full

    運行後,會從項目文件夾裏得到 trace.jtlkpi.jtl 兩個結果文件,如圖

    查看這兩個文件的內容,會得到

    因為我們把 write-xml-jtl 的值設置為 full ,那麼 bzt 就把所有的日誌都以 xml 格式打印在了 trace.jtl 這個文件裏了。

  3. write-xml-jtl 的值為 none

    運行後,項目文件夾裏只有 kpi.jtl 這個結果文件,如圖

    查看這個文件的內容,如圖

    這意味着如果我們把 write-xml-jtl 的值設置為 none ,它不會打印任何值,項目裏只有默認生成的結果文件。

查看 csv 結果

如果想得到 csv 格式的結果,腳本設置如下:

{
    "modules": {
        "jmeter": {
            "csv-jtl-flags": {
                "xml": false,
                "fieldNames": true,
                "time": true,
                "timestamp": true,
                "latency": true,
                "connectTime": true,
                "success": true,
                "label": true,
                "code": true,
                "message": true,
                "threadName": true,
                "dataType": false,
                "encoding": false,
                "assertions": false,
                "subresults": false,
                "responseData": false,
                "samplerData": false,
                "responseHeaders": false,
                "requestHeaders": false,
                "responseDataOnError": false,
                "saveAssertionResultsFailureMessage": false,
                "bytes": true,
                "hostname": true,
                "threadCounts": true,
                "url": false
            }
        }
    }
}

用同樣的接口測試後,會得到一個 kpi.jtl 文件,如圖

查看文件,可以看到剛才設置的值都被打印出來了,如圖

如果把所有的屬性值都設置成 true ,那麼會得到下面這個文件

注意事項

無論是使用 xml 還是 csv ,有兩點需要注意

  1. 當使用 csv-jtl-flags 的時候, xml 屬性必須為 false ,不然會得到 Error: Could not determine delimiter 報錯,如圖

  2. 當使用 xml-jtl-flags 的時候,如果 xml 屬性為 false ,bzt 不會報錯,但是生成的所有結果文件都會是 csv 格式,如圖

    (1)只打印錯誤信息

    (2)打印所有信息