您的位置:首页 > 其它

10个软件测试的基本概念

2006-10-20 17:25 399 查看
1)手工软件测试 VS. 自动化软件测试

我们可能会经常见到这样的软件测试职位招聘面试题:描述一下自动化测试与手工测试的优点。对于此,我答案可能并不是太全面,归纳一下主要有以下几点:自动化测试速度快,正确,精确,效率高,并且是有测试知识的累积(Skill-Building)。速度快的理由是勿允置疑的--你可能很快能自动化测试上百条测试,而一个手工测试者一天能运行200条测试cases就已经是相当不错的成绩了。正确性方面意味着自动化测试不会犯象手工测试一样的主观错误,比如错误的记下了测试的结果。精确方面的含义则指自动化测试每次都能按同样的方式去运行,而不同的人测试即使是同样的case都或多或少的有所不同。效率高方面的含义可以这样理解,可以按排自动化测试整日整夜的运行,而我们可以在白天(不要想着去加夜班

,人就应该只在8小时内工作

)集中精力去执行那些必须要有手工来完成的测试cases。最后,Skill-Building 应该可以包括两个方面,首先,你可以用自动测试的方式把你的测试技巧存储下来。其次,写自动测试的过程也同样会提高你的测试水平,这样你就不会象手工测试那样经常有mind-numbingly boring。

自动化测试不会代替全部的手工测试,他们应该用在令人生厌的,重复的测试上面,并不是所有的测试都要用上他们。自动化测试的实现意味着在金钱和时间上要有极大的投入。人们常常会说,自动测试能让你做出更加彻底的测试而不是说自动化测试能节约你的投资和时间,因为事实上,自动化测试经常做不到后一点。

2)BVT and DRT

BVT与DRT的术语对任何一个软件测试工程师都是重要的。BVT-Build Verification Tests,DRT-Develper Regression Tests。BVTs 是在一个新的版本完成了全部的开发工作之后的,所要进行的一种测试。BVTs的测试cases应该考虑的重点是:新版本是否能被安装并且能被测试团队拿去进行测试。DRTs是在开发阶段,当一段新代码在check into 之前所要立即进行的一种测试。DRTs的测试cases应该关注新的代码是否破坏了既有的功能。

从BVT和DRT产生的时间顺序上来看,我们就可以很清楚的看出他们的不同。首先开发人员完成了一段新代码,在把新代码放到source/version contrl system-通常会是一个CVS系统之前,开发人员会产生一个基于新代码的系统版本。然后开发人员会运行一个DRT测试。如果这个系统版本能过了DRT,那么开发人员就会把新代码放到中心build system。在未来的一天或者更长(具体的时间要依赖于build的产生频率),Build Team会建立一个包含了新代码的版本。随后Build Team会运行BVT 测。如果新版本能通过BVT 测试,那么它就会进入到测试注程中去(released to test)。如果new build都能通过上述测试的话,那也意味着告诉测试团队一条明确的信息,这个新版本是可安装的也是可测的,现在可以开始测试了。

通常,BVTs与DRTs都由自动化测试的cases组成(在一个开发周期很紧的项目中,这是明智的选择)并且这些测试cases是可以相互交迭的,可能会有相同的部分。换言之,BVTs与DRTs的测试cases是整个测试cases集合中的子集。它们是测试团队建立的测试集的一部分,此外还会有的测试子集是DTR(daily test run),WTR(weekly test run),MTR(milestone test run),FTP(full test pass)。

3)软件测试 Vs. 软件分析

这两个词汇我们可以先从语义学上加以区分,软件测试是以软件测试case为体现的实体,测试cases仅有通过和失败两种结果-----没有其它的可能。软件分析是用于得到系统在测试条件下所反映出的各种信息的一种活动。假设你要进行某个图书数据库的性能测试。该数据库可以通过图书名得到所有相关图书的信息。当你运行这个系统并且用一些数据作为查询条件。比如你输入"football",那运行结果是有3本相关的图书,并且该搜索耗时1.5秒。我们说这个进程不是软件测试,而是软件分析。在这个例子上,一个软件测试应该是要指定具体的耗时时间值,如果搜索耗时在这个时间以内则是测试结果为通过,否则是为失败。

通过上面的阐述,我们还可以知道,软件分析与软件测试在软件测试活动中应该是相辅相成的(go hand in hand ),我们必须要从分析中得到测试所需的诸多细节。当我们在进行软件测试的时候,你有时必须要做一下前期分析以得到你测试cases中的初始值或者是极限值。

4)代码测试覆盖(率)

代码测试覆盖作为软件测试活动中重要的测试指标,它通常用来衡量你测试的效果?换句话讲,代码测试覆盖不是一种直接用来测试程序的方法,而是通过代码测试覆盖分析这一流程来得知被测试系统(SUT-system under test)哪些部分被测试到了。举例来说,你有10,000条测试cases,当我们假定SUT有250,000语句,并且这些测试能覆盖到200,000条语句。如果我们运行完了所有的这些cases,那么可以说这些测试的代码测试覆盖(率)=200,000/250,000=80%。在实际的测试团队中,很多团队都会相当自信他们的测试组件(test suites-一个suite是包含多个独立测试cases的集合),但是通过代码测试覆盖分析,就可以知道通常一个test suites只能达到60%-70%的覆盖率。

所以把代码测试覆盖是作为测试效果评定的最基本指标之一,也就不足为奇了。

代码测试覆盖可以用在不同的数量级别上去分析。如,你能把代码测试覆盖放在语句级别-检查出test suite覆盖了SUT's code的百分比。你还能在语句块(block)的级别上去分析-检查出test suite 覆盖了SUT's code在{和}的语句块,就象C/C++,C# java语言中定义的那样。你还能把代码测试覆盖放在函数(function/method)的级别上-检查在SUT中有多少在(function/method)被测试到了。

代码测试覆盖是一个简单的概念,但困难在实施上。比如我在下面要列出的几种作法:1)在SUT的源码中插入作为记录进入和退出执行的special code。这种方法听起来不错,但手工做非常耗时。而程序地插入这些special code非常难--因为这从本质上讲是完成一个语言解析器。2)建一个服务去监测CPU运行这些测试用例时的事件。---非常,非常难。3)虽然我更倾向于找到一种轻量级,可定制的代码测试覆盖分析工具,但去购买一个商业的tool,显得更为实际。你可能会在下面的站点找到你需要的信息:

http://www-128.ibm.com/developerworks/cn/java/j-cobertura/

http://msdn.microsoft.com/msdnmag/issues/04/04/CodeCoverageAnalysis/.

2006-10-20(to be continued...)

还是接着覆盖率这个话题,我要继续下去,中午的时候我突然听到同事Gerry对我说:代码覆盖率检查是一种低效的检查测试的方法,高覆盖率只是表示执行了很多的代码,并不意味着这些代码被很好地 执行。事实是不是这样?
2006-11-2(to be continued...)
显然我们要证明“Gerry的论断”?

接下来我想到了白盒测试中的几种方法,语句覆盖,判定(分支)覆盖,条件覆盖,判定/条件覆盖,多重条件覆盖。这些概念也是代码覆盖率检查的衡量标准我对这些概念的理解是:
语句覆盖是只考虑到设计的cases走到每条语句,它保证每条语句将被执行一次即可。但如果考虑到程序有判定的情况,则语句覆盖的cases并不能走完实际执行中的每一条判定分支。因而它是最弱的一种。
判定覆盖则是保证每个判定的分支都会被执行一次,但对判定中的每个条件分支却不能保证。如if(A>1 And B=0), 判定覆盖的cases则只能保证遍历整个判定的两种可能路径-条件真/假,不能保证到判定中 每个条件所有可能的路径,如在本例中A<1 And B=0 或A>1 And B<0 这些判定条件中的可能路径将会被判定为假的情形代替。
条件覆盖则是要考虑到每个判定中的每个条件的可能路径。在if(A>1 And B=0)中,条件覆盖的测试cases应该是:

A>1 And B=0 A=2 And B=0

A>1 And B<>0 ...

A<1 And B=0 ...

A<1 And B<>0 ...

判定/条件覆盖,考虑到在上面的程序中再增加一个分支语句,形如下面的语句:
if(A>1 And B=0)
.....
if (C>0)
...
写出条件覆盖的测试cases:

A>1 And B=0 C>0

A>1 And B<>0 C<0

A<1 And B=0 C>0

A<1 And B<>0 C<0

很容易看出条件覆盖测试的cases并没有考虑到前后两个判定语句的组合情况
那么如果我既考虑到每个判定中的每一个条件的的可能路径又考虑到每个判定的可能情况,那它就是判定/条件覆盖。
那例子中的判定/条件覆盖测试cases是:

A>1 ,B=0, C>0

A>1,B=0,C<0

A>1,B<>0,C>0

A>1,B<>0,C<0

A<1,B=0,C>0

A<1,B=0,C<0

A<1,B<>0,C>0

A<1,B<>0,C<0

现在看上去象是所有的可能路径都已覆盖到了,但是如果考虑到短路与的作用那么A<1时,B=0或者是B<>0的路径都不会被走到,事实就是这样。所以判定/条件覆盖并不能发现逻辑表达中的错误。(不知道这在软件测试中如何解决?好象看过有人提出的多重条件覆盖,但是不能理解。

) 但至少有一点我们应该能认同:程序中不同的逻辑路径的数量可能达到一个天文数字,所以穷举测试路径是现实测试中很可能是做不到的。(所以我们要求在测试cases的设计的时候用到等价划分的方法以达到"合理测试"的目的。可能我又要在我的blog中理一下我这方面的心得了!

)

好了该回到Gerry的论断上去了?---高覆盖率只是表示执行了很多的代码,并不意味着这些代码被很好地 执行.
不过我们还是要先假设程序能被穷举测试路径,那情形又该如何呢?

穷举测试路径并不能保证程序的设计符合其设计规范。升序的程序写成了降序。

穷举测试路径不能发现程序缺少了哪些必需的路径。

穷举测试路径不能暴露敏感数据。如If (a/b >0 ),如果b=0则程序有除0错误.

(以上三点总结来自Myers,G.J的<软件测试的艺术>一书)

所以Gerry的论断是正确的。
2006-11-9(to be continued...)

5)压力测试 vs 负载测试

压力测试和负载测试确实有些不同。压力测试是强调减少你的被测系统(SUT)所占的资源,用一些标准的功能测试用例去测试它们(SUT)。这种测试不是出自于一些正常的条件下。比如一个多线程的程序能在正常的条件下工作的很好,但当我们减少cpu的利用率或者可用内存或是可用的磁盘空间。当减少这些常用的系统资源的时候,可能会导致你的SUT crash。这样的例子就意味着它是压力测试(我们通常可以用EatCpu,EatMem,EatDisk工具分别的加以实现 。)

负载测试强调SUT在一个很重的负载下,有时通过模拟多用户来达到这点要求。多用户可能意味着是人或者一些用程序实现的virtual users来充当。可以在基于web和网络程序的测试中找到这样的例子 ,在那儿往往需要有成千上万的用户同时点击来完成测试。负载测试有两方面的主要目的,1)得出在负载情形下SUT的性能指标2)在极端的负载下SUT是否仍有良好的表现。比如, 在一个web site的测试中,我们用负载测试来得到我们的系统可以处理多少个用户以及在极端的负载下,web site是给出下"too busy"提示给用户,还是会导致web server crash。

关于本文的作者:文军最早在Donews上发表作品,不过目前,他主要在CSDN。他现在主要从事软件测试自动化工作。他的主要作品有:基本于XML的数据驱动自动化测试框架及实现,启动-运行-监视Robot的工具,获取自动化cases执行实时图片的工具,实时监视IE crash的工具,实时获取windows系统中CPU/Memory中占用率的工具,分析-合并多个记录log的工具。
你可以通过邮件cwjattop@sina.com与他取得联系。

2006-12-4(to be continued...)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: