软件测试

在之前写的「上线前的思考中」,我将测试放在了首位,当然这只是层次最低的测试的一种,同样对于测试工作,也是有方法可言,有成熟的规矩可守的。

在《软件测试的艺术中》,将测试定义为:为了发现错误而执行程序的过程。测试同样是目标驱动的行为,测试的目的是为了发现错误,而错误的发现是通过正常或者非正常甚至带着破坏性的测试手段达到的。

通常,将测试策略分为黑盒测试和白盒测试两种。二者的本质区别在于对软件内部逻辑的感知还是屏蔽。私以为,一般来讲类似于单测这种动作应归于白盒,而压力测试、性能测试等应归类于黑盒测试。

下面主要来谈两个方面:单元测试 & 如性能测试这种更高级别的测试。

1 单元测试

对于大部分的软件系统,单元测试可以算得上是软件质量最有力的保证。也是性价比最高的一种测试方式,可以用最少的时间发现最多的问题,尤其是低级别的问题。

单元测试可以划分为原子测试和增量测试。

在原子测试(单个模块的测试)层面,测试用例集的设计关乎整个测试的质量。通常来讲,正向、反向策略以及边界测试是最通常的覆盖策略。通常,单独模块的测试需要上游的驱动模块和对下游依赖模块打桩。这种驱动以及打桩操作通常是基于假设的mock操作。

所谓的增量测试,是指对多个有关联的原子模块的测试集合,其操作流程是将待测试模块组装到已经测试完成的模块集合中。根据上下游模块的测试顺序又可将增量测试分为自顶向下和自底向上增量测试。

2 系统测试

系统测试通常有如下分类:

2.1 系统测试计划

所谓的测试流程,是目标与过程的抽象。基本流程如下:

归根到底,流程无非是 发现问题->调优过程的循环。

另外,测试除了要达到找到问题、调优的目的之外,另一项重要的作用是确定系统临界值进而指定报警策略。

2.2 测试执行方法

通常将测试执行方法分为:单场景 & 混合场景测试。
前者是指对单个场景的性能、可靠性等的测试。后者更逼近于实际线上情况,是指在复合、组合场景下的测试行为。

3 一个例子

一个来自于coolshell的例子:http://coolshell.cn/articles/17381.html

一般来说,性能测试要统一考虑这么几个因素:Thoughput吞吐量,Latency响应时间,资源利(CPU/MEM/IO/Bandwidth…),成功率,系统稳定性。
下面的这些性能测试的方式基本上来源自我的老老东家汤森路透,一家做real-time的金融数据系统的公司。
一,你得定义一个系统的响应时间latency,建议是TP99,以及成功率。比如路透的定义:99.9%的响应时间必需在1ms之内,平均响应时间在1ms以内,100%的请求成功。
二,在这个响应时间的限制下,找到最高的吞吐量。测试用的数据,需要有大中小各种尺寸的数据,并可以混合。最好使用生产线上的测试数据。
三,在这个吞吐量做Soak Test,比如:使用第二步测试得到的吞吐量连续7天的不间断的压测系统。然后收集CPU,内存,硬盘/网络IO,等指标,查看系统是否稳定,比如,CPU是平稳的,内存使用也是平稳的。那么,这个值就是系统的性能
四,找到系统的极限值。比如:在成功率100%的情况下(不考虑响应时间的长短),系统能坚持10分钟的吞吐量。
五,做Burst Test。用第二步得到的吞吐量执行5分钟,然后在第四步得到的极限值执行1分钟,再回到第二步的吞吐量执行5钟,再到第四步的权限值执行1分钟,如此往复个一段时间,比如2天。收集系统数据:CPU、内存、硬盘/网络IO等,观察他们的曲线,以及相应的响应时间,确保系统是稳定的。
六、低吞吐量和网络小包的测试。有时候,在低吞吐量的时候,可能会导致latency上升,比如TCP_NODELAY的参数没有开启会导致latency上升(详见TCP的那些事),而网络小包会导致带宽用不满也会导致性能上不去,所以,性能测试还需要根据实际情况有选择的测试一下这两咱场景。
(注:在路透,路透会用第二步得到的吞吐量乘以66.7%来做为系统的软报警线,80%做为系统的硬报警线,而极限值仅仅用来扛突发的peak)