编写 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)打印所有信息