软件测试与测试优先的编程
一. 软件测试
1.什么是软件测试?
软件测试是一种提高软件质量的重要手段。它能够发现程序中存在的bug,并确认程序是否达到用户需求。即使是最好的测试,也无法达到100%的无错误。一些软件的残留缺陷率如下:
2.什么是测试用例?
测试用例就是输入,执行条件和期望结果的集合。
即测试用例:输入+执行条件+期望结果
如:{2,4}, {0,0}, {-2,4} for program y=x^2
测试用例是软件质量保证的基石。
3.测试的特点
测试与其他活动的目标相反。测试的目标是为了发现错误,是一种破坏、证错、“负能量”的行为。
一个好的测试需要具备如下条件:
1.能发现错误。
2.不冗余。
3.最佳特性,多种测试方案中最好的。
4.既不会太复杂,也不会太简单。
4.测试的层级
除此之外还有很多其它的测试类型,如冒烟测试,兼容性测试等等。
5.静态测试与动态测试
静态测试和动态测试的最大区别是静态测试不需要执行程序,而动态测试需要按照一组测试用例执行程序。
6.测试与调试
测试是一种发现错误的手段,而调试不仅需要识别错误根源,更要消除错误。这是二者之间的区别。具体可以体现在下图:
7.白盒测试与黑盒测试
白盒测试:对程序内部代码结构的测试。
黑盒测试:对程序外部表现出来的行为的测试。
8.软件测试的困难之处
软件测试的目的是为了确认程序是否满足用户需求,而为了实现这一目的,就需要测试者设计一系列测试用例用来检测程序是否能输出预期结果。而困难之处就在于如何科学地设计测试用例。
1.通过暴力枚举出所有可能的输入情况是不可能做到的。
2.只设计几个用例靠偶然测试没有意义。
3.基于样本的统计数据对软件测试的意义不大。
4.软件行为在离散输入空间中差异巨大,无统计分布规律可言。
…
这些难点决定了软件测试的难度之大。
所以我们更应该重视测试的作用,要转变心态,用“让其出错”和“尽快出错”作为写高质量代码的日常法宝,学会对自己的代码暴力一些。
二.测试优先编程
1.测试优先的编程
测试优先的编程,顾名思义,就是在写代码之前先写测试,不要把测试留到最后。整个过程如下:
写测试用例,就是理解、修正、完善规约设计的过程。测试优先有助于更好地理解规约说明。
一个好的规约需要包含参数类型,返回值类型以及它们之间的约束和联系,规约的表现形式如下:
2.测试优先的好处
首先,由下图可见,先写测试会节省大量的调试时间。
其次,测试优先还具有如下好处:
三.单元测试
1.单元测试的内容
单元测试就是针对软件的最小单元模型开展测试,隔离各个模块,容易定位错误和调试。
单元测试需要考虑如下内容:
2.单元测试的过程
3.自动单元测试工具——JUnit
Junit是Java中广泛使用的一种单元测试框架,具体信息可查阅如下网址:
http://www.junit.org
http://junit.sourceforge.net/javadoc/
四.黑盒测试
1.黑盒测试的测试用例
黑盒测试的测试用例是围绕着规约和需求设计的, 用尽可能少的测试用例,尽快运行,并尽可能大的发现程序的错误。
黑盒测试的规约,程序和测试用例的关系可表示如下:
2.等价类划分
等价类划分是设计黑盒测试的测试用例的一种方法。
基于等价类划分的测试:将被测函数的输入域划分为等价类, 从等价类中导出测试用例。
每个等价类代表着对输入约束加以满足/违反的有效 /无效数据的集合。
这种方法基于的假设:相似的输入,将会展示相似的行为。故可从每个等价类中选一个代表作为测试用例即可。这样做就可以达到降低测试用例数量的效果。
3.边界值分析法
由于大量的错误发生在输入域的“边界”而非中央,所以对边界值的检查尤为重要。边界值分析方法是对等价类划分方法的补充。
一些常见边界如下:
五.白盒测试
1.白盒测试的流程
白盒测试根据程序执行路径设计测试用例,且一般较早执行。
其规约,程序和测试用例的关系如下:
白盒测试的具体流程图如下:
六.测试覆盖度
1.代码覆盖度
代码覆盖度:已有的测试用例(白盒测试)有多大程度覆盖了被测程序。
代码覆盖度越低,测试越不充分 但要做到很高的代码覆盖度,需要更多的测试用例,测试代价高。
2.EclEmma
EclEmma是Eclipse中的一个非常好的代码覆盖度测试工具。
七.测试策略
测试策略(根据什么来选择测试用例)非常重要,需要在程序中显式记录下来。目的是为了在代码评审过程中,其他人可以理解你的测试,并评判你的测试是否足够充分。