《构建之法》第十三章 软件测试

摘至 邹欣《构建之法》一书,以作学习之用

基本名词解释及分类

团队统一思想要从基本名词解释开始。

  • Bug:软件的缺陷

  • Test Case:测试用例,测试用例描述了一个完整的测试过程,包括测试环境、输入、期望的结果等

  • Test Suite:测试用例集,即一组相关的测试用例

Bug可以分解为:症状(Symptom)、程序错误(Fault)、根本原因(Root Cause)。

  • 症状:即从用户的角度看,软件出了什么问题
    例如,输入(3211)时,程序出错退出。

  • 程序错误:即从代码的角度看,代码的什么错误导致了软件的问题
    例如,代码在输入为某种情况下访问了非法的内存地址——0X0000000C。

  • 根本原因:错误根源,即导致代码错误的根本原因
    例如,代码对于 id1==id2 的情况没有做正确判断,从而引用了未赋初值的变量,出现了以上的情况

下面是一个关于 Bug的万丈例子

  • 症状:用户宝盖,一个 Windows 应用程序优势会在启动时 错,继而不能运行

  • 程序错误:有时候一个子窗口的 handle 为空,导致程序访问了非法内存地址,此为代码错误

  • 根本原因:代码并没有确保创建子窗口发生在调用子窗口之前,因此子窗口的 handle 变量有时会在访问时处于未赋值状态(为空),导致出现上面提到的代码错误


按测试设计的方法分类

测试设计有两类方法:黑箱(Black Box)和白箱(White Box)。

这是每个接触过软件测试的人都会给出的答案,但这只是整个软件测试的入门知识。所谓黑箱/白箱,是指软件测试设计的方法,不是软件测试的方法!注意“设计”二字。

  • 黑箱:指的是在设计测试的过程中,把软件系统当作一个“黑箱”,无法了解或使用系统的内部结构及知识。一个更准确的说法是行为测试设计(Be-havioral Test Design),即从软件的行为,而不是从内部结构出发来设计测试

  • 白箱:指的是在设计测试的过程中,设计者可以“看到”软件系统的内部结构,并使用软件的内部结构和知识来选择测试数据及具体的测试方法。“白箱”并不是一个精确的说法,因为把箱子涂成白色,同样也看不见箱子里的东西。有人建议用“玻璃箱”来表示。

在实际工作中,我们不应画地为牢,严格只用某一种测试设计方法。我们对系统的了解当然是越多越好。所谓“灰箱”的提法,正反映了这一点。有些测试专家甚至希望我们忘记全部的“箱子”及其颜色。

进一步说,我们并不是要禁止懂得程序内部结构的人员来进行黑箱测试设计,只不过是在设计时有意不考虑软件的内部结构。例如,在测试程序内部基本模块时(单元测试),通常要求由对程序结构非常了解的程序员来设计,这是因为内部模块的“行为”和程序的外部功能并没有直接的关系,而且对内部基本模块的“行为”通常没有明确的定义。另一个例子是软件的“易用性测试”,在设计此类测试时,没必要纠缠于程序的内部结构,而是应着重于软件的界面和行为。但是软件易用性测试也需要很多专业知识。这也从一个侧面表明“黑箱”和“白箱”没有简单的难度高低之分。测试用例写出来之后,大家可以忘了它们是从哪种颜色的箱子里出来的,使用就行了。


按测试的目的分类

1.功能测试
所列的测试类别中,测试的范围由小到大,测试者也由内到外——从程序开发人员(单元测试)到测试人员,到一般用户(Alpha/Beta测试)。


按测试的时机和作用分类

在开发软件的过程中,不少测试起着“烽火台”的作用,它们告诉我们软件开发的流程是否顺畅,这些测试如下表所示。


各种测试方法

单元测试(Unit Test)

请参看第2章“单元测试”,一节并思考以下问题:

  • 有时单元测试 了错,再运行一次就好了,于是后来大家就不想花时间改错,多运行几次,有一次通过就行了;

  • 单元测试中的好多错都与环境有关,在别人的机器上都运行不成功;

  • 单元测试耗费的时间要比写代码的时间还多,把代码覆盖率提高到90%以上太难了;

  • 单元测试中我们还要测试效能和压力,花了很多时间;

  • 我们都这么费劲地测了,那还要测试人员干什么/p>


代码覆盖率测试(Code Coverage Analysis)

前面单元测试中提到了代码覆盖率,简单来说代码被执行过,就是被“覆盖过”。如果一段程序运行一组测试用例之后,100%的代码被执行了,是不是意味着再也不用写新的测试用例了呢案是否定的。这是因为——

  • 不同的代码是否执行,有很多种组合。一行代码被执行过,没有出现问题,并不表明这一行代码在所有可能条件的组合下都能正确无误地运行。

  • 代码覆盖不能测出未完成的代码(所缺少的逻辑)导致的错误。比如:

    • 没有检查过程调用的返回值;
    • 没有释放资源。
  • 代码覆盖不能测出效能问题。

  • 代码覆盖不能测出时序问题,即由时序导致的程序错误(例如:线程之间的同步)。

不能简单地以代码覆盖率来衡量代码中与用户界面相关的功能的优劣。


构建验证测试(Build Verification Test,BVT)

顾名思义,构建验证测试是指在一个构建完成之后,构建系统会自动运行一套测试,验证系统的基本功能。在大多数情况下,这些验证的步骤都是在自动构建成功后自动运行的,有些情况下也会手工运行,但是由于构建是自动生成的,我们也要努力让BVT自动运行。

问:一个系统有这么多功能点,什么是基本的功能,什么不是基本的功能/p>

在运行BVT之前,可以运行所有的单元测试,以保证系统的单元测试和程序员的单元测试版本一致。因为在不少情况下,开发人员修改了程序和单元测试,却忘了将修改过的单元测试同时签入源代码库中。

通过BVT的构建可以称为可测(Testable),意思是说团队可以用这一版本进行各种测试,因为它的基本功能都是可用的。反之,通不过BVT的构建称为“失败的构建”(Failed,Rejected)。

如果构建验证测试不能通过,那么自动测试框架会针对每一个失败的测试自动生成一个Bug(小强)。一般来说,这些Bug都有最高优先级,开发人员要首先处理。大家知道,维持每日构建,并产生一个可测的版本是软件开发过程中质量控制的基础。对于导致问题的小强,我们该怎么办案是——

  • 找到导致失败的原因,如果原因很简单,程序员可以立即修改并直接提交。

  • 找到导致失败的修改集,把此修改集剔出此版本(程序员必须修正Bug后再重新把代码提交到源代码库中)。

  • 程序员必须在下一个构建开始前修正该Bug。

方法1和2都可以使今天的构建成为“可测的”,但是有时各方面的修改互相依赖,不能在短时间内解决所有问题,那就只能采用方法3了。

问:有人提到一种“冒烟测试”,是怎么回事/p>

答:事实上这是一种基本验证测试,据说是从硬件设计行业流传过来的说法。当年设计电路板的时候,很多情况下,新的电路板一插上电源就冒起白烟,烧坏了。如果插上电源后没有冒烟,那就是通过了“冒烟测试”,可以进一步测试电路板的功能了。我们正在讨论的BVT也是一种冒烟测试。


验收测试(Acceptance Test)

测试团队拿到一个“可测”的构建之后,就会按照测试计划,测试各自负责的模块和功能,这个过程可能会产生总共10来个甚至100个以上的Bug,那么如何才能有效地测试软件,同时在这一阶段该怎样衡量构建的质量/p>

在MSF敏捷模式中,我们建议还是采用场景来规划测试工作。

在“基本场景”的基础上,把系统在理论上目前支持的所有场景都列出来,然后按功能分类测试,如果测试成功,就在此场景中标明“成功”,否则,就标明“失败”,并且用一个或几个“小强”/Bug来表示失败的情况。

当所有的测试人员都完成了对场景的测试后,我们自然就得出了下表

测试计划和测试总纲主要说明产品是什么,要做什么样的测试,时间安排如何,谁负责什么方面,各种资源在哪里,等等。我们不是为了写文档而写文档,写文档的目的是要解决问题。然而,到底这些文档会解决什么问题呢/p>

1.测试设计说明书(TDS)
正如开发人员有功能设计说明书,测试人员也要有测试设计说明书,告诉测试人员要如何设计测试。

A:我们在哪里可以找到模板了模板就好办了。

B:我们不要一味地依赖于模板,不要被模板淹没了。对于一个功能,或者相关联的一组功能,TDS主要要描述这些重要的内容:

  1)功能是什么。

  2)需要测试哪些方面没有预期的Bug比较多的地方(对于测试矩阵有没有需要修改的地方)/p>

  3)如何去测试(采用什么具体方法,如何做测试自动化,准备什么样的测试数据等)/p>

   4)功能如何与系统集成,如何测试这一方面/p>

  5)什么才叫测试好了(Exit Criteria)/p>

A:有些功能还没有写好,我怎么能知道这些功能的具体情况/p>

B:功能实现之前,应该就要根据功能的Spec写好TDS,并通过同事的复审。

2.测试用例(Test Case)
有了TDS,我们就可以按照TDS的描述,对每一个功能点进行实际的测试了。具体地说,测试用例描述了如何设置测试前的环境,如何操作,预期的结果是什么。一个功能的所有测试用例合称为这个功能的测试用例集(Test Suite)。

A:对于一个功能,用户可能的输入千差万别,我是不是得写成千上万个测试用例/p>

B:没必要,我们可以把纷繁的情况归纳到几个类型中。例如,用户登录时的情况,我们可以将其归为以下几类。

  1)正确输入(用户输入了合法并正确的用户名和密码),预期结果是用户能够正常登录

   a. 用户名又有多种情况(数字、字母、中文)
  
   b. 用户登录“记得我的账户和密码(Re-member Me)”功能可以正常使用

   c. 用户的密码是否隐式显示,或者在不同模块中转送(明文密码会导致诸多安全性问题)

  2)错误输入,预期结果是系统能给出相应的提示

   a. 用户名不存在

   b. 用户名含有不符合规定的字符(控制字符、脚本语句等)

   c. 用户名存在,但密码错误(具体测试时,可以输入空、超长字符串、大小写错误等)

设计测试用例有好几种方法,这些方法互相补充,帮助测试人员有效地生成测试用例。

  • 等价类划分
    不同的测试数据,如果只是重复触发了同样的处理逻辑,或者可能的错误,那么这些测试数据是等价的,它们属于同一等价类。我们要产生出不同等价类的输入,来有效地覆盖程序的各种可能出现问题的地方。

  • 边界值分析
    程序经常在处理数据的边界时出错,如果我们能产生测试数据,触发各种边界条件,就能有效地验证程序在这些地方是否正确。例如,如果程序期待一个“日期”类型,那我们可以构造包含下面各种边界条件的数据:一年的第一天,最后一天,平年的2月28日,闰年的2月29日,或者它们的前后一天,等等。

  • 常见错误
    根据经验推测程序通常容易出错的地方,从而更有效地第设计测试用例,例如空文件名,在期望数字的字段填入文字

3.错误 告(Bug Report)

在测试中,如果发现了问题,我们就得 告,在TFS的软件过程模型中,“Bug”是第二个工作项类型。在这一阶段,我们主要用Bug进行交流。

在第4章“两人合作与结对编程”的练习中,有些团队成员已经互相找过Bug,但是当时项目相对简单,对Bug的格式并未做严格要求。在一定规模的软件项目中,一份好的错误 告,至少要满足以下几点。

  • Bug的标题,要能简要说明问题

  • Bug的内容要写在描述中,包括:

    • 测试的环境和准备工作
    • 测试的步骤,清楚地列出每一步做了什么
    • 实际发生的结果
    • 根据Spec和用户的期望)应该发生的结果
  • 如有其他补充材料,例如相关联的Bug、输出文件、日志文件、调用堆栈的列表、截屏等,应保存在Bug对应的附件或链接中

  • 还可以设置Bug的严重程度(Severity)、功能区域等,这些都可以记录在不同的字段中

下面是列举的创建的一个Bug:

标题:挂了

内容:我今天在玩购物 的时候,发现移山 站挂了。

这个Bug对问题的描述太过笼统,开发人员根本无从下手。一个好的Bug 告应该是这样的:

标题:购物 站的某个具体页面(URL),在回复中提交大于100KB的文字时会出错

内容有以下几点:

环境

在Windows XP下,使用IE7。允许Cookie。购物 的版本是1.2.40。

重现步骤:

  (1)用[用户名,密码] 登录。这一用户在系统中是一般用户。

  (2)到某一产品页面(链接为:……)。

  (3)选中一个帖子,例如:帖子 为579。

  (4)回复帖子,在内容中粘贴100KB的文字内容(文本内容见附件)。

结果:

站出错,错误信息为:[略]

预期结果:

站能完成操作,或者提示用户文本内容过大。

测试人员还可以附上其他分析,团队应该鼓励测试人员追根溯源。如果看到测试人员发来这样的Bug 告,那么开发人员就能够重现这一问题,从而有效地分析和解决问题

4. 测试修复,关闭缺陷 告(Resolve,Test and Colse a Bug)
当开发人员修复了一个缺陷并嵌入代码后,一个新的构建就会包含这一个修复(Bug-Fix)。测试人员索要做的就是验证修复,并且搜寻有无类似的缺陷,验证修复会不会导致其他问题(回归,退化),了解修复的影响(只是修改一个简单的显示文字,还是动了内部算法),并且检查系统的一致性是否受到影响(例如:修改了默认的 /是/否/取消/选择次序,要检查整个产品中其他的对话框是否遵循同一模式)

在完成测试之后,测试人员可以关闭缺陷 告,同时在“历史(History)”一栏内说明验证是怎么做的。

当测试人员验证了一个Bug被正确修复了之后,还要考虑是否将这个Bug变成一个测试用例,保证以后的测试活动中会包括这个Bug描述的情况。这点非常重要。

5.测试 告(Test Report)

在一个阶段的测试结束之后,我们要 告各个功能测试的结果,这就是测试 告。只需简单地列出一些数字即可,例如:对于某一功能,我们要收集下列数据。

  • 有多少测试用例通过/p>

  • 多少测试用例失败/p>

  • 多少测试用例未完成/p>

  • 现多少测试用例之外的Bug/p>

所有功能的测试 告相加,就能得到整个项目的测试统计信息。这样的信息能帮助我们从宏观上了解还有多少事情没办完,各个功能相对的质量如何。

声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2015年9月1日
下一篇 2015年9月1日

相关推荐