Jmeter 压力测试并输出HTML报告

Jmeter 压力测试并输出HTML报告,第1张

在进行性能测试执行之前,需要进行场景的设计:

以什么方式启动,如何持续进行,直至测试结束

三部曲:启动---持续进行---结束

PS:一般情况下,建议限制Jmeter的的线程数在300及以内,这样能更好的发挥出jmeter的性能

测试步骤:

测试计划---线程组--HTTP请求---监听器---运行脚本---查看报告

PS:默认情况下,JMeter运行需要占用1 GB的内存,这可能还不够,取决于你的测试计划和需要运行的线程数

一个测试计划描述了一系列Jmeter运行时需要执行的步骤,可以包含一个或者多个线程组,逻辑控制器,取样发生控制,监听器,定时器,断言和配置元件。

启动JMeter,会出现一个空的测试计划,此次练习通过手写脚本来实现

(不熟悉 *** 作的,也可以通过模板的形式创建,在菜单栏文件--Templates,下拉列表中选择Recording,点击Create,一个完整的Test Plan就生成了,当然我们可以删除不需要的内容)

作用:模拟用户个数、发送请求的频率及次数

PS:设置合理的线程数对能否达到测试目标有着决定性的影响,另外,设置合理的循环次数也很重要

此处添加3个HTTP请求

1、添加响应断言 :设置响应码为200

2、查看结果树,验证请求

调试时线程数和循环次数设为1就可以了,记得调试好之后再改回去

3、禁用查看结果树,命令行执行脚本

我们在启动Jmeter时就会看到命令行的提示信息,进行负载测试时请不要使用GUI模式,也就是用命令行模式运行 JMeter 测试脚本,这样可以大大缩减所需要的系统资源

备注:GUI 即图形用户界面模式,只应用于创建测试脚本、调试脚本

图中也给出了命令格式: jmeter -n -t [jmx file] -l [result file] -e -o [Path to output folder] ,JMeter 默认去当前目录寻找脚本文件,并把日志记录在当前目录,当然也可以使用绝对路径来执行

参数说明:

(1)直接生成HTML报告

PS:输出文件(-l后的文件)必须是不存在的,report文件夹为空文件夹或者不存在(-o后面的),不然无法生存报告

启动CMD窗口,输入以下命令:

jmeter -n -t C:\Users\zhangXXX\Desktop\baidu.jmx -l C:\Users\zhangXXX\Desktop\html.csv -e -o C:\Users\zhangXXX\Desktop\baidu-reports

(2)使用之前的测试结果,生成测试报告

启动CMD窗口,先生成测试结果,再生成报告,输入以下命令:

PS:-g 指定已存在的测试结果文件

以上两种方法,其实最终都依赖生成的测试报告。双击报告文件夹中的index.html就可以查看报告

Dashboard:

Test and Report informations:指的是测试和报告信息

APDEX(Application Performance Index):应用程序性能满意度的标准,范围在0-1之间,1表示达到所有用户均满意,越接近1满意度越高

Requests Summary:请求的通过率(OK)与失败率(KO),百分比显示

Statistics:数据分析,基本将Summary Report和Aggrerate Report的结果合并

Errors:错误情况,依据不同的错误类型,将所有错误结果展示

Charts: 用图表的形式展示测试数据,让测试报告更加直观**

主要有如下特点:

(1)将测试过程中经常使用的数据,用图表的形式展示,让测试结果更加直观

(2)每个图表数据,有两种展示形式

(3)支持请求样例过滤显示

(4)支持导出PNG图片格式

Over Time Charts:

Throughput Charts:

Response Times Charts:

4、添加所需监听器,导入日志文件即可查看

在性能测试过程中,我们往往需要将测试结果保存在一个文件当中,也可以为日后的性能测试报告提供更多的素材

在Jmeter中,结果都存放在 .jtl 文件中,格式有很多种,可以根据需要进行更爱,选择某个监听器,在 configure页面 进行相应配置,让我们来查看下保存后的文件有哪些内容:

接下来添加一个聚合报告,然后导入日志文件,查看结果,还可以添加其他的监听器, *** 作方法一样

PS:如果测试计划中增加了监听器(生成概要结果),在执行命令时就可以看到每个线程的执行情况

PS:设置好线程数、循环次数、集合点、事务、断言、关联等等后即可执行压力测试

原理和LR的agent差不多,因为jmeter由Java开发,耗内存、cpu,所以需要采用分布式

步骤:

1、关闭防火墙

2、在所要运行jmeter并作为负载生成器的机器上安装jmeter(确保在所有系统中使用了相同版本号的Jmeter和jdk)

PS:目标服务器需要在相同网段,确保Jmeter可以访问目标服务器

3、确定其中一台机器作为主controller,其他的机器作为agent,然后运行所有agent机器上的jmeter-server文件

4、在controller机器的jmeter中bin目录下,找到jmeter.properties文件,添加节点IP,修改localhost为压力机IP

5、启动conttoller机子上的jmeter应用,选择菜单【运行】---远程启动来分别启动agent,也可以直接选择【远程全部启动】来将所有个agent启动

在性能测试过程中,我们通常需要将测试结果保存在一个文件当中,既可以保存测试结果,也可以为日后的性能测试报告提供更多的素材

Jmeter中,结果都存放在.jtl文件,一般以csv文件格式记录,只需要选择某个监听器,点击页面的configure按钮,建议勾选如下项:Save Field Name,Save Assertion Failure Message

技术点:HTTP相关设置+参数化+断言+关联+简单控制器+查看结果树

关联:通过Json控件或正则表达式获取

(1)线程组建议替换为jp@gc - Stepping Thread Group,功能比线程组多很多

(2)可以加事务控制器

(3)查看结果树替换为聚合报告或类似的报告,如果还是想看查看结果树记得勾选仅日志错误(查看结果树打印的日志比较多,会影响性能)

(4)造数据

总结:

一个子系统建议放在同一个 “测试计划”中,流程测试可以通过“线程组”来区分,这样也便于设定不同的测试数据个数。

比较独立的接口,可以统一放在一个线程组内,顺序完成测试。

流程性接口的测试:如果要测试的接口可以组成一个流程,只需要顺序添加多个“HTTP 请求”的Sampler,各请求之间可以提取需要在上下文传递的数据作为参数,以保证流程中数据的一致性

性能测试参数

熟悉 Apache ab 工具的同学都知道,它是没有界面的,通过命令行执行。 Locust 同样也提供的命令行运行,好处就是更节省客户端资源。

启动参数:

--no-web 表示不使用Web界面运行测试。

-c 设置虚拟用户数。

-r 设置每秒启动虚拟用户数。

-t 设置设置运行时间。

出现的报错及解决办法:

使用Locust进行性能测试,Locust no-web模式执行命令locust -f zkxl_verify_ locust.py --host= https://www.baidu.com --no-web -c 10 -r 2 -t 1m

提示locust: error: unrecognized arguments: --no-web -c

参考locust官方文档 https://docs.locust.io/en/latest/running-locust-without-web-ui.html?highlight=no-web

将命令参数--no-web 更改为 --headless,将命令中指定用户并发数的参数 -c 改为 -u,即更改命令为:locust -f zkxl_verify_ locust.py --host= https://www.baidu.com --headless -u 10 -r 2 -t 1m 即可.

locust的测试数据可以保存到CSV文件中,有两种方法可以进行此 *** 作:

首先,通过Web UI运行Locust时,可以在“Download Data”选项卡下得到CSV文件。

其次,可以使用标签运行Locust,该标签将定期保存两个CSV文件。如果计划使用--no-web标签以自动化方式运行Locust

文件将被命名为example_response_times.csv 和 example_stats.csv (使用--csv=example)并记录Locust构建的信息。

如果你想要更快(慢)的写入速度,也可以自动以写入频率:

此数据将写入两个文件,并将_response_times.csv和_stats.csv添加到你提供的名称中:

打开命令提示符(或Linux终端),输入 locust --help 。

参考: 官方文档

一旦单台机器不够模拟足够多的用户时,Locust支持运行在多台机器中进行压力测试。

为了实现这个,你应该在 master 模式中使用 --master 标记来启用一个 Locust 实例。这个实例将会运行你启动测试的 Locust 交互网站并查看实时统计数据。master 节点的机器自身不会模拟任何用户。相反,你必须使用 --slave 标记启动一台到多台 Locustslave 机器节点,与标记 --master-host 一起使用(指出master机器的IP/hostname)。

常用的做法是在一台独立的机器中运行master,在slave机器中每个处理器内核运行一个slave实例。

在 master 模式下启动 Locust:

在每个 slave 中执行(192.168.0.14 替换为你 msater 的IP):

参数

--master

设置 Locust 为 master 模式。网页交互会在这台节点机器中运行。

--slave

设置 Locust 为 slave 模式。

--master-host=X.X.X.X

可选项,与 --slave 一起结合使用,用于设置 master 模式下的 master 机器的IP/hostname(默认设置为127.0.0.1)

--master-port=5557

可选项,与 --slave 一起结合使用,用于设置 master 模式下的 master 机器中 Locust 的端口(默认为5557)。注意,locust 将会使用这个指定的端口号,同时指定端口+1的号也会被占用。因此,5557 会被使用,Locust将会使用 5557 和 5558。

--master-bind-host=X.X.X.X`

可选项,与 --master 一起结合使用。决定在 master 模式下将会绑定什么网络接口。默认设置为*(所有可用的接口)。

--master-bind-port=5557

可选项,与 --master 一起结合使用。决定哪个网络端口 master 模式将会监听。默认设置为 5557。注意 Locust 会使用指定的端口号,同时指定端口+1的号也会被占用。因此,5557 会被使用,Locust 将会使用 5557 和 5558。

--expect-slaves=X

no-web 模式下启动 master 时使用。master 将等待X连接节点在测试开始之前连接。

如下图,我启动了一个 master 和两个 slave,由两个 slave 来向被测试系统发送请求。

client属性:

TaskSet类:实现了虚拟用户所执行任务的调度算法,包括规划任务执行顺序(schedule_task)、挑选下一个任务(execute_next_task)、执行任务(execute_task)、休眠等待(wait)、中断控制(interrupt)等等。

在此基础上,我们就可以在TaskSet子类中采用非常简洁的方式来描述虚拟用户的业务测试场景,对虚拟用户的所有行为(任务)进行组织和描述,并可以对不同任务的权重进行配置。

在TaskSet子类中定义任务信息时,可以采取两种方式, @task 装饰器和 tasks 属性。

@task(1)中的数字表示任务的执行频率,数值越大表示执行的频率越高

采用tasks属性定义任务:

tasks = {test_job1:1, test_job2:2}中,test_job1:1,test_job2:2表示事件执行的频率,即test_job2的执行频率是test_job1的两倍

on_start函数是在Taskset子类中使用比较频繁的函数。在正式执行测试前执行一次,主要用于完成一些初始化的工作。

例如,当测试某个搜索功能,而该搜索功能又要求必须为登录态的时候,就可以先在on_start中进行登录 *** 作,HttpLocust使用到了requests.Session,因此后续所有任务执行过程中就都具有登录态了

在TaskSequence类中,[email protected]_task()可以用来控制任务的执行顺序;里面的数值越小执行越靠前;

在Taskset类中,内置WAIT_TIME功能,它用于确定模拟用户在执行任务之间将等待多长时间。Locust提供了一些内置的函数,返回一些常用的wait_time方法。

1、 between(min,max)函数 :用得比较多的函数

wait_time = between(3.0, 10.5):任务之间等待的时间是3到10.5秒之间的任意时间

还可以用任意函数来定义等待时间, 比如平均1秒的等待时间

wait_time = lambda self: random.expovariate(1) 1000

2、 constant(number) 函数:

wait_time=constant(3):任务之间等待的时候是3秒钟,且等待的时候不能超过任务运行的总时间,也就是在执行py文件时设置的时间

3、 constant_pacing(number) *函数:

wait_time=constant_pacing(3):所以任务每隔3秒执行,但是当到达运行的总时间时,任务运行结束;

现实中有很多任务其实也是有嵌套结构的,比如用户打开一个网页首页后,用户可能会不喜欢这个网页直接离开,或者喜欢就留下来,留下来的话,可以选择看书、听音乐、或者离开;

在有Taskset嵌套的情况下,执行子任务时, 通过 self.interrupt() 来终止子任务的执行, 来回到父任务类中执行, 否则子任务会一直执行;

在上一页的案例中,在stay这个类中,对interrupt()方法的调用是非常重要的,这可以让一个用户跳出stay这个类有机会执行leave这个任务,否则他一旦进入stay任务就会一直在看书或者听音乐而难以自拔。

在进行接口多用户并发测试时,数据的重复使用可能会造成脚本的失败,那么需要对用户数据进行参数化来使脚本运行成功。

已登录功能为例:

创建 login_user() 方法,定义登录字典 users , 通过randint 随机获取字典中的用户数据。

在 login() 登录任务中,调用 login_user() 方法实现 随机用户的登录。

在此我们举出百度搜索的例子,假设每个人搜索的内容是不相同的;那么我们可以假设把数据放到队列中,然后从队列中依次把数据取出来;

可以利用python中Queue队列来进行处理;

Queue的种类

Queue.Queue(maxsize=0):先进先出队列

Queue.LifoQueue(maxsize=0):后进先出队列

Queue.PriorityQueue(maxsize=0):构造一个优先队列

参数maxsize是个整数,指明了队列中能存放的数据个数的上限。一旦达到上限,插入会导致阻塞,直到队列中的数据被消费掉。如果maxsize小于或者等于0,队列大小没有限制

Queue的基本方法

个别情况下测试数据可重复使用,因此我们可以把参数化数据定义为一个列表,在列表中取出数据;

在某些请求中,需要携带之前response中提取的参数,常见场景就是session_id。Python中可用通过re正则匹配,对于返回的html页面,可用采用lxml库来定位获取需要的参数;

我们以Phpwind登陆的来进行举例,在登陆的接口中需要把token参数传给服务器,token的值由页的接口返回;

方法一:使用正则表达式

方法二:采用lxml库来定位获取需要的参数

技术点:

1、导模块:lxml模块

2、etree.HTML() 从返回html页面获取html文件的dom结构

3、xpath() 获取token的xpath路径

catch_response = True :布尔类型,如果设置为 True, 允许该请求被标记为失败。

通过 client.get() 方法发送请求,将整个请求的给 response, 通过 response.status_code 得请求响应的 HTTP 状态码。如果不为 200 则通过 response.failure('Failed!') 打印失败!

参考文章:

https://www.jianshu.com/p/a48f4af81e67

https://www.cnblogs.com/fnng/p/6081798.html

http://class.itest.info/locust 【虫师】

https://cloud.tencent.com/developer/article/1594240 【官方文档的中文翻译】


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/7090372.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-01
下一篇 2023-04-01

发表评论

登录后才能评论

评论列表(0条)

保存