测试计划
可以将测试计划可视化为用于运行测试的JMeter脚本。测试计划由测试元素组成,例如线程组,逻辑控制器,样本生成控制器,监听器,定时器,断言和配置元素。 每个测试计划中至少应有一个线程组。 我们可以根据要求添加或删除元素。 前言中的快速开始就是一个测试计划。
测试计划控制面板中的元素:
-
名称和注释
-
用户定义的变量
-
独立运行每个线程组
-
主线程结束后运行tearDown线程组
-
函数测试模式
-
添加目录或jar包到classpath
用户定义的变量
当在测试计划的多个部分中存在重复的数值时,可以通过用户定义的变量
来提供更灵活的设置。
测试计划控制面板中的用户定义的变量
的作用域覆盖整个测试计划。
你可以通过${变量名称}
的方式来引用这些变量。这种方式允许你在不同的请求或操作中使用相同的数值,从而更加方便地维护和修改。
示例接口代码:
@api.route('/TestPlan/', methods=['GET', 'POST'])
def testplan(): # Jmeter教程测试计划-用户定义的变量api
if request.method != 'POST':
return jsonify({'code': 400, 'data': 'ERROR: The request method is not POST'})
data = request.get_json()
if "UserDefinedVariables" not in data:
return jsonify({'code': 400, 'data': 'ERROR: The request body is error!'})
return jsonify({'code': 200, 'data': 'Your request parameters is ' + '"UserDefinedVariables:'
+ data['UserDefinedVariables'] + '"'})!'})
示例Jmeter脚本
-
测试计划面板中添加用户定义的变量
名称:
UserDefinedVariables
值随意输入:
我是用户定义的变量
-
测试计划下添加线程组
-
线程组下添加HTTP请求
请求地址:
HTTP://127.0.0.1:5000/TestPlan/
请求方式:
POST
消息体数据:
{"UserDefinedVariables":"${UserDefinedVariables}"}
-
HTTP请求下添加HTTP信息头管理器
右键HTTP请求-添加-配置元件-HTTP信息头管理器,添加信息头,指定请求体类型
名称:
Content-Type
值:
application/json
-
测试计划下添加查看结果树
运行,查看结果树
请求头信息
Connection: keep-alive
Content-Type: application/json
Content-Length: 58
Host: 127.0.0.1:5000
User-Agent: Apache-HttpClient/4.5.14 (Java/20.0.2)
请求体数据{"UserDefinedVariables":"我是用户定义的变量"}
可以清晰地看出,接口请求参数中调用了用户定义的变量
的值:我是用户定义的变量
。
结语
此外,JMeter提供的配置元件中也包含用户定义的变量
元件,通过测试计划/线程组/取样器-添加-配置元件-用户定义的变量
进行添加。用法与测试计划面板中的用户定义的变量
一致,不同之处在于作用域。
测试计划面板中用户定义的变量
具有整个测试计划范围的作用,而配置元件中的用户定义的变量
则根据其位置确定作用范围。
举例来说,在测试计划下添加的用户定义的变量
将在整个测试计划中生效,与测试计划面板中的用户定义的变量
作用范围一致。然而,如果用户定义的变量
位于取样器中,其作用范围将仅限于该特定取样器内。这种灵活性允许在不同配置元件中使用变量,使其作用范围更具体而有针对性。
建议使用更自由的配置元件中的用户定义的变量
。
独立运行每个线程组
当一个测试计划下有多个线程组时,且这些线程组都处于执行状态时,可能会使用测试计划中的独立运行每个线程组
勾选框,以防止各个线程组之间相互影响。
在这种情况下,通过勾选独立运行每个线程组
,确保每个线程组在执行时都是相互独立的。这意味着它们将不会共享任何变量或资源,从而避免潜在的相互干扰。
这个选项的使用对于模拟多个并发场景或测试不同业务流程的情况非常重要。它确保每个线程组在测试计划中都能够独立运行,从而更准确地模拟真实世界的使用情境,提高测试的可靠性和准确性。
示例接口代码
@api.route('/TestPlan1/', methods=['GET', 'POST'])
def testplan1():
sleep(3) # 接口设置了休眠三秒,即接口在接收到请求数据三秒后,返回响应数据。
if request.method != 'GET':
return jsonify({'code': 200, 'data': ' 请求方式错误!'})
return jsonify({'code': 200, 'data': '处理完毕'})
示例Jmeter脚本
-
测试计划下添加两个线程组
名称依次为:
线程组1
、线程组2
-
两个线程组下皆添加取样器
名称与对应线程组一致:
线程组1
、线程组2
请求地址一致:
HTTP://127.0.0.1:5000/TestPlan1/
请求方式一致:
GET
-
测试计划下添加查看结果树
运行,查看结果树
不勾选独立运行每个线程组
,运行结果
线程组1中取样器结果
hread Name:线程组1 1-1
Sample Start: 2024-01-16 11:19:34 CST
Load time:3004
Connect Time:1
Latency:3004
Size in bytes:231
Sent bytes:210
Headers size in bytes:165
Body size in bytes:66
Sample Count:1
Error Count:0
Data type ("text"|"bin"|""):text
Response code:200
Response message:OK
线程组2中取样器结果
hread Name:线程组2 2-1
Sample Start: 2024-01-16 11:19:34 CST
Load time:3003
Connect Time:1
Latency:3003
Size in bytes:231
Sent bytes:210
Headers size in bytes:165
Body size in bytes:66
Sample Count:1
Error Count:0
Data type ("text"|"bin"|""):text
Response code:200
Response message:OK
Sample Start 是请求发出的时间,可以观察到两个线程组内的 HTTP 请求在同一时刻发出,即 2024-01-16 11:19:34
。因为两个线程组是并发、随机执行的。
勾选独立运行每个线程组
,运行结果
线程组1中取样器结果
hread Name:线程组1 1-1
Sample Start: 2024-01-16 11:32:52 CST
Load time:3004
Connect Time:1
Latency:3004
Size in bytes:231
Sent bytes:210
Headers size in bytes:165
Body size in bytes:66
Sample Count:1
Error Count:0
Data type ("text"|"bin"|""):text
Response code:200
Response message:OK
线程组1中取样器结果
hread Name:线程组2 2-1
Sample Start: 2024-01-16 11:32:55 CST
Load time:3003
Connect Time:1
Latency:3003
Size in bytes:231
Sent bytes:210
Headers size in bytes:165
Body size in bytes:66
Sample Count:1
Error Count:0
Data type ("text"|"bin"|""):text
Response code:200
Response message:OK
Sample Start 是请求发出的时间,可以观察到两个线程组内的 HTTP 请求并非在同一时刻发出。具体而言,HTTP 请求1的请求发出时间是 2024-01-16 11:32:52
,而 HTTP 请求2的请求发出时间是 2024-01-16 11:32:55
。两者之间的时间差正好为三秒,与接口休眠的三秒相符,这表明两个线程组是顺序执行的。
结语
当勾选了独立运行每个线程组
选项时,能够确保测试计划中的相同类型线程组按照顺序执行。在某些特定的测试情况下,这个选项非常有用。相反,若未勾选 独立运行每个线程组
时,线程组是并发执行。
但线程组中的多个取样器并不会并发,而是在较短时间内发出全部请求,尤其是在取样器数量较多的情况下。
因此,在模拟高并发时,如果需要多线程组、所有取样器请求并发,建议在测试计划中添加同步定时器(Synchronizing Timer)
。
同步定时器(Synchronizing Timer)
可以确保在并发场景下的同一时间点触发多个线程组中多个取样器的请求,以更真实地模拟多用户同时访问系统的情况。这样的设置有助于提高测试的准确性和可靠性,使测试更符合实际应用场景。
主线程结束后运行tearDown线程组
该选项主要适用于在取样器错误后配置的普通线程,并指定了在错误发生后要执行的动作,如停止测试或立即停止测试。
勾选主线程结束后运行tearDown线程组
后,当普通线程由于取样器错误而导致线程结束执行时,系统会继续执行 tearDown 线程。这意味着即使在测试中发生了错误,系统仍会在整个测试结束前执行 tearDown 线程,以确保在测试运行结束时执行一些清理或必要的操作。
需要注意的是,在 JMeter 中,普通线程组的执行优先级大于 tearDown 线程组,因此 tearDown 线程组将会等待所有普通线程组执行完毕后才会执行。
这一设置非常有用,可以确保在测试过程中出现错误时执行必要的清理步骤,同时允许根据具体情况选择在错误发生后是立即停止测试还是允许测试计划中其他线程组或线程继续执行。
示例接口代码
@api.route('/TestPlan1/', methods=['GET', 'POST'])
def testplan1():
sleep(3) # 接口设置了休眠三秒,即接口在接收到请求数据三秒后,返回响应数据。
if request.method != 'GET':
return jsonify({'code': 200, 'data': ' 请求方式错误!'})
return jsonify({'code': 200, 'data': '处理完毕'})
示例Jmeter脚本*
-
测试计划下添加线程组
在取样器错误后要执行的动作,勾选
停止测试
或立即停止测试
-
测试计划下添加tearDown线程组
-
线程组和tearDown线程组下添加同样的http请求
名称分别为:
线程组请求
,tearDown线程组请求
请求地址:
HTTP://127.0.0.1:5000/TestPlan1/
请求方式:
GET
-
线程组请求取样器下添加响应断言
添加,输入值:
1111
-
测试计划下添加查看结果树
PS:响应断言用于匹配实际响应信息,作为验证接口响应的一种手段。例如,示例接口响应的是 {'code': 200, 'data': '处理完毕'}
,而添加的断言是 1111
,这两者无法匹配,则可以判断该取样器请求存在错误。
运行,查看结果树
不勾选主线程结束后运行tearDown线程组
,运行结果
响应头信息
HTTP/1.1 200 OK
Server: Werkzeug/3.0.1 Python/3.12.1
Date: Fri, 16 Jan 2024 14:52:02 GMT
Content-Type: application/json
Content-Length: 47
Connection: close
因为不勾选主线程结束后运行tearDown线程组
,而且响应体{"code": 200,"data": "处理完毕"}
与断言1111
无法匹配,响应断言判断该取样器请求发生错误,所以只有线程组被执行完毕后,而 tearDown 线程组并未被执行。
此时,修改响应断言为:{"code":200,
再运行。
即使不勾选主线程结束后运行tearDown线程组
,因为响应体{"code": 200,"data": "处理完毕"}
与断言{"code":200,
匹配,响应断言判断该取样器请求正常,所以线程组被执行完毕后,执行 tearDown 线程组。
勾选主线程结束后运行tearDown线程组
,运行结果
响应断言改回为:1111
即使响应断言判断请求发生错误,因为勾选主线程结束后运行tearDown线程组
,线程组被执行后,tearDown 线程组紧接被执行。
结语
在确保测试环境的可靠性和稳定性方面,通过勾选主线程结束后运行tearDown线程组
以及配置线程组中的取样器错误后执行的动作,可以在主线程结束后执行 tearDown 线程组,从而进行一些关键的清理和还原操作。这一设置在测试流程中发生错误或异常情况时,能够确保系统状态的正确还原,为后续测试提供稳定的基础。
具体而言,主线程结束后执行 tearDown 线程组的步骤可以被理解为测试执行的最后一道关口,确保在测试结束时执行特定的操作。通过配置线程组中的取样器错误后执行的动作,例如停止测试
或立即停止测试
,可以更加灵活地处理测试中的异常情况。
这样的设置在以下方面发挥关键作用:
-
环境清理: tearDown 线程组可以包含用于清理测试过程中创建的临时数据、资源或连接的操作。这有助于保持测试环境的整洁和可重复性。
-
资源释放: 如果测试过程中涉及到占用系统资源的操作,例如文件打开、网络连接等,tearDown 线程组可以负责释放这些资源,避免资源泄露和系统负担。
-
数据还原: 在测试期间可能对数据库或配置文件进行了修改,tearDown 线程组可以负责将这些更改还原,确保下一次测试能够在干净的环境中进行。
-
错误处理: 配置线程组中的取样器错误后执行的动作可以根据具体需求选择停止测试或立即停止测试。这样的灵活性使得能够在测试遇到问题时及时采取适当的措施,防止进一步的不稳定性。
通过精心配置这些选项,可以确保测试系统的可靠性和稳定性,同时为测试人员提供了在测试结束时进行必要清理和还原操作的机会,以确保下一次测试能够在一致的基础上进行。
函数测试模式
若选择了此选项,并且监听组件(比如“查看结果树”)配置了将结果保存到文件中,JMeter将每次的请求结果记录到文件中。值得注意的是,这种做法相对消耗资源,在负载测试中并不建议勾选。然而,在平时脚本调试的情况下,可以考虑启用该选项。
这样的设置主要适用于需要详细记录每次请求结果的情况,以便后续分析或排查问题。在负载测试中,由于可能生成大量的结果数据,将其全部保存到文件可能导致性能和资源开销的增加,因此需要谨慎使用。
总体而言,这一功能的选择应该根据具体需求和测试目标来决定。在进行性能测试时,特别是在高并发负载下,建议避免勾选该选项以保持测试的高效性。然而,在脚本开发和调试阶段,启用此选项可以帮助更全面地了解每次请求的细节,有助于及时发现和解决问题。
实际应用场景相对有限,因此在本文中不进行详细演示。
添加目录或jar包到classpath
添加文件或 JAR 包功能主要用于调用外部的 JAR 包。当脚本需要引用外部的 Java 文件或 JAR 包时,可以通过将 JAR 包的路径添加到此功能中。这样,在 Beanshell 脚本中就可以通过 import 语句导入外部 JAR 包,并直接调用其中的方法。
在后续的内容中,当涉及到 Beanshell 时,将详细阐述如何使用这一功能。这个特性提供了一种扩展 JMeter 功能的途径,使得用户可以方便地集成和调用外部 Java 类库,从而实现更复杂和灵活的测试脚本。
总结
JMeter的测试计划是测试工作的主要组织结构,它定义了测试的执行流程、配置和执行的参数。在测试计划中,包括了多个关键组件,如线程组、tearDown线程组、HTTP取样器、响应断言等,它们构成了一个完整的测试计划。
当你执行测试时,添加的所有所需组件和元件组成了一个有机整体,即一个完整的测试计划。这个测试计划反映了你对系统性能和功能的验证方式以及测试场景的设计。
本篇主要探讨了测试计划组件面板中各元素的使用,这包括了配置用户定义的变量、定义并发用户行为的线程组、定义进测试后清理的tearDown线程组,这些元素的组合和配置,直接影响着测试的有效性和准确性。
在JMeter中,设计一个强大且高效的测试计划需要综合考虑系统特性、测试目标和性能需求。合理配置这些组件,有效运用各种元素,是确保测试计划成功执行和提取有价值信息的关键步骤。
在下一篇章中,EtherealBoyJiang将引领读者深入探讨线程组的重要性和使用方法。线程组作为JMeter测试计划的核心组件之一,对于模拟并发用户的行为至关重要。
评论区