【HIT软件构造】程序测试——黑盒测试和白盒测试以及测试用例的选择

前言

对程序的测试是软件构造过程中的一个重要的过程。在测试的过程中我们可以找到程序中所存在的错误及漏洞,从而不断地完善程序的功能,修改程序的错误,从而最终得到一个完美的程序。
由于当前阶段编程主要是用于完成课程任务,涉及到的程序复杂度也不高,测试也从未系统地学习过。对于大部分同学来说,对于自己编写的程序的测试仅仅局限于给出一组输入的样例,能得到预期的结果即可。虽然这对于当前阶段来说已经够用了,但更为科学系统地测试方法更能帮助我们更快地找错。掌握好程序测试的方法,能合理地选择测试用例,将对我们的编程有着极大的帮助。
本篇文章将着重对黑盒测试、白盒测试以及测试用例的选择展开说明。

1.测试流程

测试主要包含四个测试流程,根据老师所讲以及我个人理解,其测试的目标分别如下:

  • 单元测试:测试程序中最小单元内的功能是否正常实现,如每个方法,每个类等,是否达到了设计该单元要实现的功能。
  • 集成测试:测试程序中各个模块间、各个类间的接口能否正常的工作,也就是说测试一下程序的各个部分能否协调配合地工作。
  • 系统测试:将程序所要执行的系统环境、所需要的各种参数都配置好后,测试能否实现我们预计的功能。也就是测试在需要的工作环境下,程序能否完成需要的任务。
  • 验收测试:这个测试过程并不是由编程人员完成,而是由用户完成。用户根据自己的需求对软件进行测试,看看程序能否正常的满足自己的需求。

除了这次个流程之外,还有一个额外的流程——回归测试,正常情况下,我们是不是要进行这个流程的。但当上述四个流程中任意一个检查出了代码的错误,并且我们对代码进行修改后,都需要进行回归测试,即返回到最初开始重新测试。因为没人能够保证这次的修改不会引发出新的BUG,毕竟程序的各个部分都是有着千丝万缕的联系的,牵一发而动全身。有时候修改了BUG,甚至会导致出现更多的BUG的情况(相信许多人都经历过的崩溃时刻),所以在每次改动后我们一定要从头在进行一次测试。

2.黑盒测试及其测试用例的选择

2.1黑盒测试

什么是黑盒测试呢?根据它的名字去理解,我们将程序视为一个“黑盒”,我们不知道黑盒里面有些什么,只知道这个“黑盒”对于我们给予它的“刺激”它能做出相应的“反应”,而我们所关心的就是这个“刺激”及其所对应得“反应”,也就是程序的输入和输出。所以说,黑盒测试主要是看程序的功能是否成功地实现了,而对于这些功能是怎样实现的则毫不关心。

2.2测试用例

对于测试用例的选择,首先,不需要多说的,我们肯定都想用最少的测试用例达到我们的测试要求。而要达到这点并不容易,应为程序的输入分散在一个大的空间中,而我们要做的是在这大的空间中选择几个点,使得尽可能的保证程序是正确的,减少会有BUG被遗漏的情况出现。

要做到这个,首先就要引入等价类的概念。等价类对于我们来说已经并不陌生了。就拿本学期在形式语言与自动机中所学的来说,在对自动机的化简中,处于相同等价类的状态是完全等价的,可以将它们合并为一个状态,对于相同的输入有着同样的反应结果。而对于测试用例,我们需要根据输入的规约划分等价类,每个等价类中选取一个测试用例,使得最后的测试用例能够覆盖到所有等价类即可,这样就能最大程度的保证对于所有满足要求的数据都能正常的达到预期结果。例如对数据正负的划分,奇数偶数的划分,整数小数的划分等等。

划分了等价类后,如何对测试用例进行选择?课程中给出了两个方案

  • 笛卡尔全覆盖:即对于不同维度的等价类进行排列组合,使得每个组合中都有一组数据被选到。例如:数据分别从三个不同的维度划分为正数和负数、奇数和偶数、整数和小数这几个等价类,那么我们所取得测试用例包含2×2×2=8即可,例如正数+奇数+整数便为其中的一个组合。
  • 覆盖每个取值:也就是把所有等价类放在一起,每个等价类所涉及到的数据都最少在测试用例中出现过一次。例如还是对于上面那个例子,一共有六个等价类,那么我们取10,-3.5和5即可实现对所有等价类的全覆盖。

对于这两种选择的方案,其优缺点是显而易见的,就测试的完备性来说,前一个方案更好;而对于实现代价来说,后一个方案更好。这就需要根据我们的需求进行选择了。个人认为,对于等价类划分很多,采取笛卡尔全覆盖会出现数量庞大的组合是,采取第二个方案更优;而对于等价类划分较少,能轻易列举其组合的时候,第一个方案更优,更为完备。

3.白盒测试及其测试用例的选择

3.1白盒测试

理解了黑盒测试,那白盒测试就很容易猜到是什么意思了。用同样的方法进行解释,将整个程序看做一个透明的盒子,盒子有着洞口,而且我们能看到盒子内部错综复杂的路径,从盒子的入口放进小球后,小球会经过盒子内部的某一条路径,从另一个出口出来。我们要关注的,就是小球在盒子内部走过的路径,也就是程序内部具体的实现过程。

黑盒测试虽然能够检测程序的功能能够正常实现,但我们却不能够知道这个功能是否是在歪打误撞,负负得正的情况下实现的。如果真的是这样,虽然测试会幸运通过,但却会给程序留下隐患,很难保证会不会引起巨大的后果。这就需要通过白盒测试去发现这些隐患。

3.2测试用例

同样的,对于白盒测试我们仍然希望通过最少的测试用例满足我们的需求。对于在黑盒用例中提到的某些选择方法在白盒测试用也可以使用,这里就不过多赘述。着重说一下两者不同的地方。

对于测试用例的选择范围上,两者是不同的。对于黑盒测试来说,其测试用例是在规约所划出来的数据范围内进行选择;而白盒测试则要根据程序内部的实现路径对数据做出选择,其选择范围是要比黑盒测试小的。

那么如何在这个范围内进行选择呢?同样是要进行等价类划分,不同的是划分是要对路径进行划分。将程序的实现路径划分为不同的等价类,如一个循环为等价类,选择语句的不同分支等等,对于同一个等价类我们只需要选择一条基本路径作为代表,最终的测试用例至少覆盖这些路径一次即可。

在这里我们提到了“覆盖”,而对代码的覆盖度就是衡量我们测试结果的一个重要标准。我们主要从三个方面来看覆盖度:

  • 语句覆盖:及对于程序中的每条语句,都有最少某一个测试用例在执行过程中执行到过该语句。即保证在测试结束后,每一条语句被执行过最少一次。
  • 分支覆盖:对于程序中所存在的条件选择语句,其所可能出现的情况都在测试用例中出现过。也就是说,我们要根据程序中的选择语句的条件,选择合适的数据分别选中不同的分支,使每个情况都会出现。
  • 路径覆盖:覆盖程序中所有分支路径的可能组合。即将程序试做图,A点到B点有三条边,B点到C点有两条边,那么我们就要测试2×3=6条边,即采用笛卡尔乘积。

对于这三种覆盖来说,其可靠度是递增的,但同样的,其难度也是递增的,尤其是路径覆盖,完全的路径覆盖是不可能实现的,因为其要测试的数据量是庞大的。所以我们只需要在保证语句覆盖的基础上实现分支覆盖,并尽可能多地完成路径覆盖即可。

总结

掌握对程序测试的方法将对我们的编程有着极大的帮助,在这里再额外补充一些方法以及一些可能需要注意的点:

  1. 测试时要注意边界值。在内部满足的情况下,边界值仍可能出错。例如第一次实验中计算回归角的问题,对于我初次推出的函数,其能很好地满足四种象限的情况,但对于坐标轴的情况会计算出错。
  2. 程序测试要边写边进行,尽量不要一口气写完后测试。大一编程课时老师也曾说过,没人能保证一次就能把程序编写对而不出错,所以要慢慢来,边写边检查改错。如果我们一口气写完再检查,可能会堆积了大量的BUG,同时,各个模块间的相互调用可能又导致更复杂的错误,难以对程序进行修改。所以要养成良好的测试习惯。
  3. 学会利用测试工具,例如java编程中的Junit。
  4. 养成良好的编程习惯,例如给程序加注释、合理地给变量命名等,这样我们在修改代码时将会更加清晰明了,节约大量的时间。
  5. 当某个测试用例结果出错,但又认为程序不存在BUG时,要注意自己选择的测试用例是否符合规范,是否本身的规定就出现了错误。
  6. 最后,测试的过程中不要怕麻烦,编写好代码后并不代表大功告成,测试同样是编写程序的一个重要步骤。要尽可能地去找茬挑错,尽可能地使程序完善,这才是一个合格的编程人员应做得到的事情。
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

麻了巴卡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值