上期文章,我们讲了基于python的selenium,用于做自动化测试。今天就简单说一下性能测试方面的一些知识点。
性能测试的含义:测试软件的性能表现,考量软件运行的如何,一般关注时间/效率
、资源占用情况
、并发用户数/吞吐量
、可靠性
、可扩展性
等等。
开展性能测试的时间点:功能测试的中后期。切记:性能测试并不是在其他测试完成后,测试一下就可以了。
响应时间:应用系统从用户发送请求开始,到客户端接受到所有的数据所消耗的时间。网页响应的时间又可细分为:网络传输时间、DNS解析时间、服务器处理时间、数据库处理时间等。
在线用户、并发用户、虚拟用户:在线用户,指的是正在使用软件的用户;并发用户是指同一时刻与服务器进行数据交互的所有用户;虚拟用户是性能测试工具模拟真实用户的行为。(虚拟用户就是通过线程产生的)
吞吐量与吞吐率:吞吐量
指的是一段时间内服务器处理的总字节数。而吞吐率
指单位时间内服务器处理的字节数,即吞吐量/测试时间。
每秒事务数TPS:表示每秒系统处理的事务数。
思考时间/休眠时间/等待时间:指用户在进行操作时,每个操作之间的时间间隔。
负载测试、压力测试与并发测试:
loadrunner12系列安装包:hi,这是我用百度网盘分享的内容~复制这段内容打开「百度网盘」APP即可获取 链接:https://pan.baidu.com/s/1PjQfCzkXqPfkkXLajCIqGQ 提取码:jt61
jmeter官网:https://jmeter.apache.org/download_jmeter.cgi,jmeter安装包去官网下载即可。
loadrunner具体如何安装,我这里就不细说了,网上的帖子也有很多,大家自己查一下就知道了。我们侧重讲一下这个工具该怎么进行使用。
以上是我学习loadrunner是的笔记,里面记录了一些个人觉得比较重要的点。仅供参考。
安装好后,桌面有这三个图标,即loadrunner的三大组件。
- Virtual User Generator:用于录制脚本和调试脚本。
- Controller:控制器,在脚本调试好之后,在这里进行场景设计、负载测试,简单点说就是可以进行并发测试等等、设置虚拟用户数等。
- Analysis:在负载测试之后,将测试结果在analysis中打开,可查看很多的图表,进行分析。
loadrunner支持的协议有很多,我们这里选择Web(html、http)。
在工程创建好之后,左边栏会出现以下文件/文件夹:
loadrunner的脚本代码,使用的是C语言,在使用时,也会使用一些C库的库函数。
点击record即可进行录制脚本。
上图中,Recording Options中,有两种录制方法,有URL录制和HTML录制,简单点说就是URL录制时,更全面一点,且我们一般都是用URL录制。
录制脚本时的一些问题:
在初次安装loadrunner时,录制脚本可能会存在很多问题,比如录制时,不会自动打开浏览器、提示没网络、录制脚本后,没有代码生成等。
这些问题,我也无法解释清楚,网上的解决方案也挺多的,我就不细说了。
录制开启之后:
在浏览器进行一些操作,这样就能录制脚本了。切记,只有在进行服务器交互时,才会录制到的哦,也就是说,在录制的时候,我打开QQ发一条信息,这种情况,loadrunner是不会录制到的。
说一下127.0.0.1:1080/WebTours,这个是在安装loadrunner之后,自带的一个买机票的系统,可用于我们学习loadrunner时使用,可在一下安装路径中开启该服务。
在录制脚本完成之后,可以点击上方的三角符号,进行回放。
回放脚本时,想实时查看浏览器对应的情况,可有以下设置:
所谓的检查点,其实就是我们平时所听到的断言,就是判断当前页面的某些参数,是否符合预期的效果。
回放脚本后,点击View-》Snapshot,然后点击代码中的函数,就可以查看每一个函数,所产生的http响应:
选中文本,添加检查点函数。
检查点函数:
在上诉添加检查点中,有一个count属性(上图72行代码),这个count是参数,而不是我们平时写的变量。我们需要通过其他函数,读取到count里面的值。
lr_eval_string(参数名); // 读取参数里面的值,返回值是字符串类型
可以通过库函数,将字符串转换为int类型:
int count = atoi(lr_eval_string(参数名)); //将字符串转换为整数
还需要注意到一个点,在loadrunner中,不能在代码中间部分声明任何变量,也就是说,像int a = 10
,这样的代码,必须写在整个文件的最前面,这一点就比较鸡肋。
然后还需要认识一下,loadrunner中的输出函数,跟C语言的printf有点像。
lr_output_message(); //换行输出,在日志中
lr_message(); // 不换行输出,在日志中
以上两个输出函数,其实和C语言的printf一样,也是可以格式化输出
的。如下:
lr_output_message("%d\n", a);
lr_message("%d\n", a);
什么是事务?
事务包含一个或多个业务操作,这些操作要么都执行,要么都不执行。事务常被用来确保数据的一致性。
事务的四大特性:
- 原子性
- 事务是数据库的逻辑工作单位,事务中包含的各种操作要么都做,要么都不做。
- 一致性
- 事务执行的结果必须是使数据库从一个一致性状态变为另外一个一致性状态。因此当数据库只包含成功事务事务提交的结果时,就说数据库处于一致性状态。反之数据库在处理数据时发生故障,导致某些操作还未完成,这种就称为不一致状态。
- 隔离性
- 一个事务的执行不能由其他事务干扰。也就是一个事务内部的操作及使用的数据对其他并发事务是隔离的,并发执行的各个事务之间不能互相干扰。
- 持久性
- 也称为永久性。指一个事务一旦提交,它对数据库中的数据的改变就应该是永久的。接下来的其他操作或故障不应该对其有任何的影响。
在loadrunner中,使用两个函数来表示一个事务,两个函数之间的所有数据就是事务的所有操作。
lr_start_transaction(事务名称);
// 两个函数之间就是事务的所有操作
lr_end_transaction(事务名称,事务状态);
如上所示。上诉代码提到了事务状态
,就是描述当前这个事务执行的结果,是成功还是失败。
事务状态:
一般我们在写代码时,都是人为的判断事务的状态。这就与上文我们提到了检查点结合起来了。在说检查点的时候,里面有一个count属性,表示统计检查文本出现的次数。
将检查点与事务结合起来,就能够判断事务的状态了。有如下代码:
lr_start_transaction("登录事务");
// 插入检查点,例如检查登录之后的页面等
// 登录的一些操作
if (atoi(lr_eval_string("{count}") > 0) {
// 检查文本的数量超过0,说明已经检查到登录页面了
lr_end_transaction("登录事务", LR_PASS); //成功状态
} else {
// 检查文本的数量没有超过0,说明并没有检查到文本
lr_end_transaction("登录事务", LR_FAIL); //失败状态
}
参数化(跟自动化测试中的数据驱动一个意思),听名字感觉挺高大上的,其实就是这样的意思:
比如在执行脚本的时候,我们需要大量的注册账号之内的,如果手动的将所有账号密码填入脚本,这很浪费时间。
参数化,就是将读取一个文件,自动的将文件中的数据替换到代码里面去。
参数化文件的设置:
关联算是整个性能测试中,一个比较难的点。它所解决的问题就是:每次执行脚本时,需要对响应里面的参数进行提取。
学过http协议的同学,应该都知道cookie和session。
简单点说,cookie是为了解决http协议是一种无状态的协议所带来的缺陷。虽说无状态协议带来了很多好处,但是有一个地方不太友好。
无状态指的是:服务器上一次处理的http协议的结果,不会对当前有所影响。
举个例子:登录学校官网时,点击登录按钮后,进入首页,理论上来说此时你是处于登录状态的。但http协议是无状态的,不会保留你上次登录的这件事情。所以为了证明你已经登录了,服务器需要记录一下。就产生了cookie。
cookie:是电脑浏览器的一种机制,是一个键值对结果,用于存储sessionID(会话值)。(可在浏览器的地址栏左侧看到cookie)
sessionID:称为会话值,是服务器返回的一个数据,这个会话值,在服务器端对应了一个HttpSession对象。当你进入首页时,发送的http请求就会带上sessionID,表示你处于登录状态。
了解了session后,我们就知道:每次登录不同的账号时,服务器会返回一个不同的sessionID,所以我们在写脚本时,要将响应中的这个sessionID提取出来,在发送下一请求时,将sessionID一起发送出去,这就是关联的意思。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fgACVbml-1646652761741)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220307103927604.png)]
如上如,在发送sessionID请求之前,客户端肯定已经接收到sessionID的值了,我们只需要在发送这个请求之前,将那个值提取出来,然后填入这个请求中即可。
在该请求之前,找一个地方,右击鼠标:
在弹出的右侧栏中,搜索lr_reg_save_param()
函数,这个函数就是用来提取http响应中一些数据。
该函数的配置如下:
为了使代码跑的更准确,为了做到真正意义上的并发测试,需要我们设置集合点。
比如登录操作,我想要30人都打开网页之后,同时点击登录按钮,这样的场景就需要用到集合点。
只需在登录操作之前,按下图所示,即可添加。
添加集合点之后,还没有结束。我们需要在controller中开启集合点才行,并且设置并发用户数。
block块技术,是为实现局部代码迭代次数。
按F4,可进入Run-time Settings
,设置迭代次数,和添加block块。
然后可将action中的代码分发给每个block即可实现迭代。
将代码调试好之后,就可以去controller中进行负载测试,如下图,快速打开controller。
在跑完负载测试后,可以看到上方的图表,可直接打开analysis分析器,在里面可以查看更多的图表。
打开之后,可在此添加其他图表:
好啦,以上全部就是loadrunner的基本使用的,总的来说,比较复杂,需要自己动手多试试。
所谓的代理,就可以理解为“中介”。如下图:
在客户端和服务器之间,添加了代理服务器,那么就可以抓取到二者之间的通信数据。jmeter就是这样录制脚本的,而我们使用的fiddler之类的,也是这样的原理。
配置:
设置浏览器的代理服务器,ip地址就是当前电脑的ip,端口号一般就是8888,这个端口号要与jmeter录制脚本时开启的端口号一致。
jmeter中的配置:右击测试计划-》添加-》非测试元件-》http代理服务器。如下图:
当然也可以自己手动添加脚本:
右击线程组-》添加-》取样器-》http请求。
然后在页面填写相应的ip地址,端口号之内的,就可以了。当前为了脚本好修改,还可以添加一下http请求默认值。在这里面填写ip地址后,jmeter就可以自动的填写到相应的http请求中,后续更改也更快。
检查点的设置,和loadrunner相似,也是需要在http响应中找到文本,然后在产生这个响应的请求处,添加“断言”即可。
注意:添加的检查文本,尽量不要有.*?之类的特殊字符,如果有的话,jmeter可能会将此认为是一个正则表达式。如何解决中这种情况呢?那就就是进行转义,在特殊符号前加‘\’即可。
添加事务,稍微比loadrunner简单一点点吧。右击线程组=》添加-》逻辑控制器-》事务控制器。
然后将所有的http请求,全部拉到事务控制器里面即可。如图
在事务控制器里面的请求,给请求添加检查点,当检查点报错后,那么当前这个事务也会自动报错,不需要自己手动的判断事务的状态。
需要自己提前写好参数化文件,比如txt文件之类的,每一列直接分隔符用tab或者,都是可以的。
然后在需要进行参数化的脚本的前面引用写好的参数化文件即可。
具体的参数化文件的设置如下:
调用方法:在loadrunner中,参数调用是{参数名}
,而jmeter中是${参数名}
。
最后的线程共享模式,决定了每个线程使用数据的时机,具体解释如下:
具体关联所解决的问题,在上文loadrunner中已经结束过了,这里就复述了,着重说一下在jmeter中怎么进行关联。
使用(.*)这样的方式作为占位符。括号前面的我们称为左边界,后面的称为右边界。当然占位符有两种格式:
样的,调用参数的方法就是${参数名}
。
循环迭代
右击-》添加-》逻辑控制器-》循环控制器,这个控制器里面就可以设置循环迭代的次数。
同样的,需要循环迭代的所有请求,拉到循环控制器里面即可。额外需要注意的一点是,请求中有参数化时,需要连同CSV文件配置一起拉到里面去,有可能还需要根据需求更改CSV文件配置的线程共享模式。
集合点的添加,非常简单,在需要并发的请求前面,添加一个symchronizing Timer(同步计时器)即可,并配置里面的并发数。
这里就比较简答,只需要记住两条命令即可。
非GUI运行,在jmeter的bin目录下执行一下命令:
jmeter -n -t 脚本文件.jmx -r -l 结果文件.jtl
以上只是将脚本跑完了,要想生成具体的图表,还需要另外一条命令(还是在jmeter的bin目录下):
jmeter -g 结果文件.jtl -o 存储路径
这条命令执行后,就会生成一个文件夹,这个文件夹里面就是一些网页文件,用浏览器打开就可以看到图表。
步计时器)即可,并配置里面的并发数。