1.并发测试
最近小屌丝一直在埋头苦练性能的知识,很是努力。但是,小屌丝的最近遇到的问题,可是挺棘手的。
例如:
小屌丝:鱼哥,你说这性能测试,是不是就是并发测试?
小鱼:性能测试和并发测试,是两个概念,且并发测试不等同于性能测试。
小屌丝:鱼哥,那你说,性能测试是不是包含并发测试?
小鱼:吐血ing…性能测试只是并发测试的一个小类而已
小屌丝:哦,那性能测试…
小鱼:住嘴!!你别问,我怂~我给你详细的讲什么是并发测试,以及从我实际的项目中给你解析常见的并发问题!
小屌丝:挖草,这次赚大发了!
小屌丝:鱼哥,请开始你的表演!
1.1并发测试的定义
1.并发测试的定义中,最主要的有两点
①点层面上的:
例如:周一早上7:30半,小学生要统一到操场升国旗。
>>即:同一时间做某件事
②线层面上的:
例如:中午11:30-13:00,小学生有的跳皮筋,有的踢足球,但同时对服务器产生压力。
>>即:一个时间段做不同的事
2.并发测试不等于性能测试
这个问题,我面试的时候,问过多个求职者,大部分求职者的第一反应都是说并发测试就是性能测试!
性能测试中把并发又分为负载和压力测试。
虽然并发测试与性能测试有交集,但是,并发测试并不仅仅应用于性能测试。并发测试更多被运用于其他领域。
1.2并发测试的分类
并发测试不仅仅是性能测试,它存在各个测试阶段,并且测试目的各不相同。
①功能并发测试:要先进行测试单业务功能场景的并发测试,在进行混合业务功能场景的并发测试。
>>功能并发测试目的为验证系统功能是否符合需求规格说明书的要求。
②性能并发测试:同时满足某些系统性能指标的前提下,让被测对象承担不同的工作量,以评估被测对象的最大处理能力及是否存在缺陷。
>>性能并发测试的目的为验证系统性能指标是否符合需求规格说明书的要求
③稳定性的并发测试:判断测试系统的长期稳定运行的能力。
>>稳定性并发测试目的为验证系统稳定性是否符合需求规格说明书的要求。
④异常性并发测试:模拟系统在较差、异常资源配置下运行,以评估被测对象在资源不足的情况下的工作状态。
>>异常并发测试的目的为验证系统的异常响应机制是否满足需求规格说明书的要求。
2.常见并发问题
当下流行一种时尚的软件设计理念,叫"微服务"。
把复杂功能组合拆分成若干个独立的服务进行开发,然后有选择性的组合执行各服务。
微服务开发框架有利于并发测试设计,每个服务都是测试的切入口,可以单独执行。换句话说,测试切入口越多,越有利于测试场景的设计,有效的执行并发用例。
并发切入口从以下三个方面查找统计:
①客户端操作:使用工具捕获提交到服务器的请求,分析链接、参数进行测试。
②系统接口:查阅相关的接口文档,开发并模拟其他系统功能进行测试。
③定时任务:定时任务视开发框架,可能需要二次开发,以接口形式进行测试。
并发测出的问题,是一种综合证,往往有多种错误交织在一起的,所以不能乱用"药"。
解决这类问题,通常分以下5个步骤(比把大象放冰箱多了2步):
- 通过并发测试找到故障点;
- 以故障点的现象分析问题原因;
- 确定产生原因后讨论解决方案;
- 根据解决方案实施修复;
- 同并发测试验证修复情况。
2.1事务并发的问题
由于事务处理而导致的并发问题,我们需要先了解什么是事务。
事务的定义:是数据库操作的最小单元,是作为单个逻辑工作单元执行的一些列操作;这些操作作为一个整体一起向系统提交,要么执行,要么不执行;事务是一组不可在分割的操作集合(工作逻辑单元)。
系统内部事务控制:事务的控制好坏往往取决于码农们的开发技术、业务理解能力、专注程度,由于这类错误而导致的bug是非常低级别且严重的(必须出示黄牌进行警告)!
举例说明
某一天,小屌丝接到白富美的邀约,说要去看"xx牌"电影,让小屌丝帮忙订个票。
挖草~~小屌丝鸡冻的,赶紧掏出他的iphone4,打开某团,找到某电影,选择位置,并点击"确定选择",然后进入到支付页面,提交订单,选择支付宝去支付,支付成功收到短信。
我们来分享一下故事场景的上半部分:
小屌丝用手机打开某团,找到白富美想看的电影,选择了座位,提交订单到支付页面。
"选座"与"提交订单"都是某团内部接口。
如果将这两个作为一个事务,有以下四个特性:
- 原子性:要么都整,要么都不整。
- 一致性:锁定座位提交订单后必须生成订单号,取消订单则解锁座位。
- 隔离性:座位被别人选中,没有网络,操作日志记录失败等。
- 持续性:事务提交后永久存在,不会受到任何故障影响。
而作为测试人员,需要考虑的测试点有:
- 一个座位被多个账号锁定,生成了订单;
- 座位锁定成功,但没有生成订单;
- 取消订单,座位未解锁;
- 生成重复订单号;
- 操作日志没有完整的记录所有行为。
我们再来分析订电影票场景的下半部分:
小屌丝在支付页面,使用了支付宝进行支付,支付成功后收到平台短信。
"支付成功"是外部接口。对于外部接口的事务控制,需要考虑两个系统的设计。
对支付接口进行并发接口测试,要考虑的事务问题:
- 同一笔订单,不能同时选择多种方式,不能进行多次支付;
- 重复通知上传支付结果(支付成功,支付超时),只能处理一次订单。
- 日志记录完整记录发送、接受的支付信息,与测试用例内容相匹配。
2.2极限值并发的问题
由极限值而导致的并发问题,那么,什么又是极限值呢?
极限值:标准要求的数值范围的界限,“极限值"也被称为"极限数值”、“临界值”、“界限数值”。
举例说明
那是2020年的第一场雪,白富美要搞一个生日party,为了活跃气氛,白富美想搞一个抽奖环节,于是找到小屌丝,告诉小屌丝的具体安排,然后让小屌丝去撸码。
具体安排为:当天23:00~23:59还在场的朋友,每人一个礼物(华为P50必须安排),每个人另外有3次抽奖机会(挖草~这是炫父??),同时发朋友圈高调炫耀的,还能在获得1次抽奖机会,已经抽到一等奖的,不能再获得二等奖和三等奖,中奖概率按照预估概率进行计算,如果已中奖数量达到上限,必须停止抽奖。
小屌丝根据白富美的需求,开发完代码,进行并发测试。
小屌丝设计的并发测试场景:
- 当天时间23:00~23:59,给在场每个人一份礼物;
- 在场每个人有3次抽奖机会;
- 高调发朋友圈,可以再来一次抽奖机会;
- 已获得一等奖的,不能在获得二等奖和三等奖;
- 中奖概率按预估概率进行设定;
- 已中奖数量达到奖品数量上限,该奖项停止。
在这个场景中,先分析测试对象分别有:活动时间、抽奖次数、中奖概率、奖品数量上限、中奖规则。
小屌丝设计的并发测试用例覆盖点为:
- 测试活动:不在活动时间范围内,也能参与抽奖;
- 抽奖次数:未分享朋友圈炫耀的,抽奖次数超过3次;
- 抽奖次数:朋友圈高调炫耀的,抽奖次数超过1次;
- 中奖概率:设置中奖概率有效的小数位数;
- 简化数量上限:奖项数量上限控制;
- 中奖规则:已中一等奖,是否还能中二等奖、三等奖。
2.3压力并发的问题
由压力负载而导致的并发问题,可以归类于性能问题。
关于性能的问题,我之前有写过几篇,如:
但是今天我要在这里说一些数据库事务的隔离级别。
>>>隔离级别有4个,有低到高依次如下:
①Readuncommitted(未授权读取、读未提交)
如果一个事物已经开始写数据,则另外一个事务不允许同时进行写操作,但允许其他事务读此行数据。该隔离级别可以通过"排他写锁"实现。
该隔离级别避免了更新丢失,却可能出现脏读。
>>即事务B读取到了事务A未提交的数据。
②Readcomitted(授权读取,读提交)
读取数据的事务允许其他事务继续访问该行数据,但是未提交的写事务将会禁止其他事务访问该行。
该隔离级别避免了脏读,但是却可能出现不可重复读。
>>即事务A先读取了数据,事务B紧接着更新了数据,并提价了事务,而事务A再次读取该数据时,数据已经发生了改变。
③Repeatableread(可重复读取)
读取数据的事务将会禁止写事务,写事务则禁止任何其他事务。
该隔离级别避免了不可重复读取和脏读,但是有时可能出现幻读。这可以通过"共享读锁"和"排他写锁"实现。
④Serializable(序列化)
提供严格的事务隔离。它要求事务序列化执行,事务只能一个接着一个的执行,但不能并发执行。如果仅仅通过"行级锁"是无法实现事务序列化的,必须通过其他机制保证新插入的数据不会被刚刚执行查询操作的事务访问到。
序列表是最高的事务隔离级别,同时代价也花费最高,性能最低,一般很少使用。在该级别下,事务都会乖乖的顺序执行,不仅避免脏读、不可重复读,还避免了幻读。
那么,什么是脏读、不可重复读、幻读,能不能解释一下呢?
(1)脏读
一个事物读取到了另一个事务未提交的数据操作结果。
(2)更新丢失
更新丢失包含以下两种情况:
①回滚丢失
>>当2个事务更新相同的数据源时,如果第一个事务被提交,而另外一个事务却被撤销,那么会连同第一个事务所做的更新也被撤销,即第一个事务做的更新丢失了。
②覆盖丢失
>>当2个或多个事务查询同样的记录然后各自会以最初的查询结果更新该行时,会造成覆盖丢失,因为每个事物都不知道其他事务的存在,最后一个事务对记录做的修改将会覆盖其他事务对该记录做的已提交的更新。
(3)不可重复读(Non-repeatableReads)
一个事务对同一行数据重复读取2次,但是却得到不同的结果,包括以下情况。
①虚读:事务R1读取某一数据后,事务R2对其做了修改,当事务R1再次读取该数据时得到不同的值。
②幻读:事务在操作过程中进行两次查询,第二次查询的结果包含了第一次查询中未出现的数据或者取消了第一次查询中出现的数据(不要求两次查询的sql语句相同)。这是由在两次查询过程中由另外一个事务插入数据造成的。
通常的数据库设置默认隔离级别为Readcommitted(授权读取、读提交)。
2.4异常数据干扰并发的问题
对于这类情况的异常数据测试也可以称之为系统健壮性测试。
测试重点是,要根据业务逻辑或系统相关的配置情况构建能够造成异常的测试数据,要求这些数据不能被当做正常数据处理,也不能影响其他正常数据(这挺难的)。
例如:
测试人员构建测试场景为不断触发定时批处理任务,如果码农在代码中忽视对异常数据逻辑处理,就会造成数据库连接池饱满、内存溢出、遇到异常数据直接报错中断(待执行任务队列越来越多)等问题。