起步于系统工程师,迈进入测试工程师,从起初的C/S系统到互联网时代的B/S系统,从事过电信增值业务、软交换、烟草OA、公安技侦和电子商务等行业的软件测试开发和管理多年,愿与大家共同分享共同交流,关注软件项目管理、测试团队管理、软件流程控制和软件性能测试及自动化测试技术。互联网时代,技术推动进步,欢迎人才推荐:jonas.wangl@alibaba-inc.com

发布新日志

  • 高手过招的乐趣---测试用例预演[收藏]

    2009-11-30 13:58:47

      摘要:高手过招,手中无需用剑,只要轻描淡写地以口代手,三两句话便高下立判,胜者胜得痛快,输者也输得潇洒。然而,除了在武侠小说之内,恐怕很难有地方让你感受到这种“会当凌绝顶”的痛快。本文根据作者在测试工作中的体会,提出了一种被称为“测试用例预演”的方法,用模拟的测试用例执行发现程序中潜在的问题,这种方法究竟有何神奇呢?请见内文。
      武侠小说中的高手大抵有三个层次,第一个级别是“静若处子,动如脱兔,身负成名绝技”的高手,印象中这一个级别的基本是杀手或是性情豪爽的江湖侠客,这种人一旦遇到,打杀的场面最为宏伟,刀枪之声不绝,各出奇招,直到一方倒地或是被制;第二个级别是“落叶飞花,片叶支花均可伤人”的高手,这个级别的高手相遇,少了宏伟的场面,却在看似不经意的凝重中展开残酷的厮杀,胜负只在一念之间;第三个级别的高手寥寥无几,多是成名已久、文武双修的名宿,已至“手中无刀,心中无刀”的最高境界,这种高手若是过招,全不闻金戈之声,全无杀伐之意,轻描淡写的以口代手,三两句话便高下立判,赢的赢得痛快,输的输得潇洒,在武侠中看到此,常不免心潮澎湃,艳羡不已,巴不得自己也能有这个机会一尝绝顶高手之间的这种至高默契。可惜身为开发或是测试工程师,又出生在这个真实的世界,恐怕实在是不太会有机会领会这种至高的境界。
      所幸,我们虽不能飞进武侠小说尝试这种生活,却能在我们的测试工作中体会到这种乐趣。真耶?假耶?且与我一起,探究个究竟。
      回到我们的题目“高手过招的乐趣 —— 测试用例预演”,这里我要提出的是一种可以让你体会到高手过招乐趣的方法:“测试用例预演”。且慢试图在头脑中搜索你对这种方法的印象,因为这是我自创的名词(申明:如果很不幸你通过其他途径确实听到或是见过这种描述,请一定告知本人,本人会慎重考虑,至少到目前为止,我还能有把握地说这是我首先命名和以正式文档描述的一种方法)。之所以把这种算不上十分复杂的方法写下来,是因为本人在实际的工作中发现该方法确实能起到比较大的作用,而且更重要的是,那种高手过招的感觉,很希望能和更多有高手梦的朋友能够感受得到。
      测试用例预演是一种非正式的测试用例执行方法,概括说来,这种方法是无需通过测试用例的真正执行(静态或是动态执行),而只需要开发人员和测试人员之间的口头交流,就能发现被测系统中存在的问题。设想一下,无需动手(测试执行),通过以口代手(开发和测试人员之间的口头交流),就能实现我们的目标(发现缺陷),这不是高手过招是什么?
    l   测试用例预演的一般步骤是:
      测试工程师与开发工程师以某种方式坐在一起,进入交流状态,这个过程中需要尽可能避免干扰,比较好的时机是坐在一起进餐的时候;
      测试工程师根据测试用例进行提问,甚至可以临时扩展测试用例,但要注意三点:
        1). 不要偏离测试用例太远,以免偏离实际的业务;
        2).可以考虑一些在测试用例中没有明确写明的异常情况处理;
        3).提问的方式是“如果我这么操作,你的系统会如何反应?”;
      开发工程师根据测试工程师的问题,做出应答,对每个问题都只需要回答系统的响应即可,不需要描述具体的实现方法;
      测试工程师仔细聆听开发工程师的回答,需要对开发工程师的答复敏锐反应,不放过任何一个开发人员的迟疑,对拿不准的问题应该记录并需要马上验证;
      双方继续预演直到预期的预演时间结束或是有一方感到疲倦;
      记录预演过程中发现的问题到缺陷跟踪库。
      当然,要说明的是,参与交流的开发和测试工程师不是比武双方,真正的敌人只有一个:系统的缺陷,这点务必要牢记,以免弄错了对手,伤了和气。
      测试用例预演不是一种复杂的方法,但根据我的经验,要想在实际工作中应用这种方法并取得较好的效果,必须了解这种方法的适用范围,遵循一定的使用方法,并需要注意一定的技巧。这里我以FAQ的方式提供秘笈一部,各位请留意:
      Q:测试用例预演可以取代测试执行吗?
      A:这个问题是我捏造出来的,我想大概不会有人真的这么认为:),不过在这个问题的回答中,我希望能尽可能准确地描述测试用例预演方法的适用范围:如前面所提到的,测试用例预演是一种“虚拟”的测试用例执行方法,因为主要是通过口头交互的形式,也就限制了该方法适用的深度,一般来说,针对业务逻辑的较为直观的用例可以采用这样的方法,尤其是那些涉及大量用户复杂交互的用例,采用这种方法非常有效,测试工程师模拟用户或是设备提出各种可能的正常异常情况,很容易发现程序处理中的漏洞。但是,对于那些需要涉及大量地层处理的用例,测试工程师一般不太可能对其机制了解得十分清晰,因此采用这种方式也很难发现问题。
      Q:测试用例预演可以在哪些场合下使用?
      A:测试用例预演的应用场合没有特殊要求,但至少要保证是一个适合双人沟通的场合,没有过多的被打扰,双方都处在能积极思考的状态,这样就可以了。根据我的经验,一起就餐、双方暂时没有明确的工作内容,或是在对设计进行非正式评审的时候是一个比较好的时机,但还要充分考虑双方的喜好,譬如,有人不喜欢在吃饭的时候展开讨论。总之,一个适合双人沟通的场合是最低要求。
      Q:测试用例预演方法可以用在其他地方吗?
      A:中子炮刚发明的时候,科学家们狂热地将中子炮对准任何可以找到的东西;按照这种趋势,测试用例预演方法也必须要考虑是否可以应用在其他地方:)实际上,预演这种方法在评审或是思维游戏的过程中一直都是被广泛应用的,测试用例预演只不过将预演这种方法用到了以往需要真正执行的领域中,除了在测试执行环节,设计评审过程中我们也可以采用这种方法针对设计进行审查,关键在于提问的技巧:“如果我们这么做,你的设计将会怎样反应?”。
      Q:好像我用测试用例预演方法很难达到预期的目标?
      A:测试用例预演方法并非不需要前提条件,至少要保证以下条件才能使测试用例预演发挥较大的作用:
      开发工程师具有良好的配合意识;
      测试工程师对产品具有良好的熟悉程度;
      提问者的提问必须从“如果我这样做,程序会怎样反应”开始;
      参与预演的开发工程师对用于预演的用例涉及的模块要非常熟悉;
      其中,测试工程师对产品具有良好的熟悉程度是非常必要的,测试用例预演的主要对象是针对业务逻辑的用例,这就要求测试工程师熟悉产品,熟悉业务。所谓“棋逢对手”,至少要能和开发工程师是一个级别上的。另外,参与预演的开发工程师必须对用于预演的用例涉及的模块很熟悉,如果参与预演的开发工程师是模块的开发者自然没有问题,如果不是,就要求开发工程师必须能够准确了解模块的行为和实现。
      Q:测试用例预演发现的问题需要记入缺陷库吗?
      A:答案是肯定的,测试用例预演是一种“虚拟”的测试执行,预演过程中发现的问题同样要被记录、跟踪。当然,为了标识测试用例的发现阶段,可以专门在缺陷管理系统中增设一个“预演”阶段,统计预演在缺陷发现方面提供的效果。
      Q:如果开发人员不配合,怎么办?
      A:这个问题……我只能说具体问题具体分析了。关键是弄清楚开发人员为什么不配合,可能是开发人员个性羞涩,不喜欢这样面对面的交流方式;也可能是开发人员觉得这种方式浪费时间;又或者是开发人员对测试人员抱有不信任的态度。不管怎样,发挥你的个人所长,让开发人员放下顾虑和成见,认识到这种做法能给他和项目带来的好处,自然可以解决这个问题。
      Q:还有哪些在测试用例预演过程中应该主要的问题?
      A:当然还有一些需要注意的问题,沟通的技巧、对对方反馈的及时分析等等,这些都可以在实际运用测试用例预演方法的过程中逐渐体会。我总结的几点需要注意的问题包括:
      对每一个开发人员的犹豫都不能放过,一个犹豫很可能就是一个缺陷隐藏的地方;
      如果可能,最好能和开发人员一起,确定那些不确定的问题,以防开发人员一时马虎放过了本来存在的问题;
      预演的方式不适合在正式评审会议上应用,因为预演主要是两个人之间的协同思考,在正式评审会议上容易浪费其他人的时间;
      预演时要注意记录,头脑风暴产生的火花如果不及时记录的话,很可能会在短时间后被遗忘。

      文章出处:csdn.net 作者:关河 发布时间:2005-11-20  

    【作者简介】 姓名:关河,真名:段念,测试时代成员;有数年软件测试经验,先后历任软件测试工程师、软件测试组长、软件测试经理等职。对软件测试技术、软件测试管理,以及相关的质量体系和流程都有较为深入的了解和认识,除测试管理外,目前专注于软件性能测试、白盒测试、开源测试软件方向。

  • 回归测试的风险

    2008-11-19 17:21:54

        假设设置一个场景:   “但是,它仅仅是一个很小很小的改动!我们怎么会预先想到它会造成这么大的问题?”

        怎么会,确实!没有回归到的功能点可以造成很大的问题。

        回归(向后追溯)是软件系统的现实生活。即使之前是很好地工作的,但是不能确保它会在最近的“很小”的改变后也能工作。是的,模块设计和充分的系统架构可以减少这种问题的出现,但是不能完全消除。

        回归测试是永远都需要的。但是我们在非常有限的时间里测试一个“很小”的改动,我们怎么进行充分的回归测试呢?我们怎么知道查找哪些方面?我们怎么减少出现问题的风险?

        回归的问题

        回归的问题根源是软件系统的内在复杂性。随着系统的复杂性的增加,更改产生难以预见的影响的可能性也增加了。即使开发人员使用最新的技术也不可避免。

        随着系统构建的时间越长回归的问题也会增多。在几年后,可能已经被更改了很多次,通常是由那些原本不在开发组中的人来修改的。即使这些人努力理解底层的设计和结构,更改与原本设计主题思想非常匹配也是很难做到的。这样的更改越多,系统变得越复杂直到变得非常脆弱。

        脆弱的软件就像脆弱的金属。被弯曲和扭转了这么多次以致你对它做的任何事都可能导致它的破裂。当一个软件系统变得脆弱,人们实际上会很害怕改变它。他们知道他们做的任何事情都可能导致更多的问题。易脆(不可维护)是旧的软件系统被替换的主要原因之一。

        即使现在我们用自动化来回归主干流程,但也不能回归到很小的点,只能检查出不会有大的问题,小的问题还是要我们去回归测试的

        回归测试的困难

        因为任何系统都需要回归,所以回归测试非常重要。但是谁有时间对每一个小的更改都完全地重新测试系统呢?对一个只是1周多点的开发,我们肯定不能承受1个月的完全重新测试整个系统。我们有一个星期的时间测试就很幸运了;更通常的情况是,只允许几天的时间。

        既然完全的重测不可能,我们必须决定如何使用很好的时间来进行测试。但是我们怎么知道怎么做呢?我们怎么预见这些不可预见的问题呢?(就像老板要求你把这些会出现的意外情况做个列表一样可笑!)

        现实中,我们总是有测试压力,即使当测试一个新的系统时。总是不够时间去完成所有应该完成的测试,因此我们必须充分利用可用的时间,用最好的方法去测试。我们在这种情况下我们必须使用“基于风险的测试方法” 。

        基于风险的测试

        基于风险的测试的本质是我们评估系统不同部分蕴含的风险,并专注于我们的测试在那些最高风险的地方。这个方法可能让系统的某些部分缺乏充分的测试,甚至完全不测,但是它保证了这样做的风险是最低的。

        “风险”对于测试与风险对于其他任何情况是一样的。为了评估风险,我们必须认识到它有两个截然不同的方面:可能性和影响。

          -“可能性”是可能出错的机会。不考虑影响程度,仅仅考虑出现问题的机会有多大。

          -“影响”是确实出错后造成的影响程度。不考虑可能性,仅仅考虑出现的问题的情况会有多糟糕。

           使用这些风险信息,我们可能选择这样分配我们的测试:

          - 50%的测试专注于新改的模块

          - 30%的测试放在与新改模块相连的模块

          - 15%的测试放在与新改模块相关的模块

          - 5%的测试时间放在与新改模板不太相关的模块

        使用基于风险的测试策略不能保证没有回归。但是会显著地减少对一个大系统进行的小更改的风险。现在我们就是采用自动化做全网回归测试来检查是否有重大问题,从运行的效果来看,成效应该说很不错的,几次发现了A类故障的问题,都是在非正式环境下扼杀掉,不然就可想而知了。。。

        我们如何把回归测试做的很全面,很到位,其实就现在用自动化来跑的话还不是很智能,因为中间会有很多因素影响到自动化回归的功能和回归范围。这个问题还在思考中。

  • 浅谈并发测试

    2008-11-19 15:24:06

       这样说的并发测试不是性能测试中的并发量来测试,这里只是对某些功能进行并发测试,从业web页面测试的人对这个功能并发测试肯定不陌生了。

       (1)一般情况下,一个页面的功能,比如新增、修改和删除等操作,做并发测试很简单,只要我们同时用一个帐号登录,打开2个IE,一边操作完成,一边在原来的状态再去操作,检查点就是坚持页面是否异常,数据库是否异常。我们可以把这样的简单的并发测试叫同步操作并发测试

       (2)一些特殊的审批流程中的操作并发检查,就不是一般的功能同步检查了,因为一个流程审批往往会有很多环节,那么我们如何去检查呢?

       其实方法是一样的,只不过我们要准备大量的数据去检查页面和数据库是否系会异常,如数据库状态为0和3的状态是可以关闭的,那么我们要准备0和3两种状态下与1、2、4、5(假设有5种状态)之间的操作异步并发检查,也是开2个IE,只不过另一个IE操作与前一个页面状态不一致,我们可以把这样的并发测试叫为异步操作并发测试

      并发测试在黑盒子测试是很重要的,如果不进行测试验证往往会给用户留下功能操作的漏洞

  • 遗传算法在黑盒测试中的应用

    2008-11-04 21:24:56

        摘 要:提出了一种利用遗传算法帮助测试人员在较短时间内完成软件模块的黑盒测试,并给出测试结果
    和好的测试用例的方法。
     
      关键词: 遗传算法 测试用例 耦合度在软件测试中,黑盒测试主要是针对模块进行的功能测试。最
    普遍的方法是以软件的功能说明书为基础将软件的输入划分为若干个等价类,多次运行该软件来检验软
    件对于不同的等价类是否能满足要求。但是在实际应用中,有的模块太大或输入参数太多,等价类划分
    后需要进行的测试工作可能是一个极大的任务。这时,如何选择最优的测试用例就成为测试人员的一个
    重要任务。
     
      遗传算法是模仿生物遗传和进化机制的一种最优化方法,它把类似于遗传基因的一些行为,如交叉
    重组、变异、选择和淘汰等引入到算法求解的改进过程中。遗传算法的特点之一是,它同时保留着若干
    局部最优解,通过交叉重组或者解的变异来寻求更好的解。与贪婪算法相比,遗传算法更可能找到全局
    最优解,而贪婪算法则容易限于局部最优而达不到全局最优。
     
      如果能够将遗传算法有效地运用于黑盒测试中,帮助测试人员选择最优的测试用例,那么将给测试
    工作带来极大的帮助。
      1 应用方法在设计具体的算法之前,我们先介绍遗传算法的基本算法,其算法框架如下1:
      第一步,初始化:选取p个候选解作为初始解,把其中最好的解作为暂定(最优)解。
     
      第二步,解的改进:若满足终止条件,输出暂定解,算法终止。否则,进行以下的运算:
      (1)解的交叉重组:从p个解中选出两个或两个以上的解进行交叉重组,得到新解,重复该运算
    若干次。
     
      (2)解的变异:在候选解中随机加进一些变异,产生新解。
     
      (3)局部搜索:对新产生的解用局部搜索法进行改良。若能得到比候选解更好的解,更新候选解

     
      (4)从全部解中按一定的准则选出p个解作为下一代的候选解,更新暂定解。
     
      转第二步。
     
      了解了遗传算法的算法框架后,进一步要做的就是在软件的黑盒测试中,如何将不同的等价类转变
    为遗传算法的候选解, 如何设定解的优劣标准,如何设置合适的终止条件。
     
      我们假定一个软件模块的输入参数有5个:A、B、C、D、E,经过合理的等价类划分后,每个
    参数又有5个不同的等价类:A1~A5,……,E1~E5。我们采用一个广义的遗传算法候选解概
    念,一般的遗传算法往往将候选解形式定为二进制的数据串,比如:111010、010001等等
    ,而在不同等价类输入作为候选解时我们将候选解形式定为(按照上面假定为基础):A3B1C2D
    4E5、A2B2C4D1E3等等。这样我们解决了候选解的问题,在解的优劣标准以及终止条件的
    设定问题上,我们需要借助工具作为标准。
     
      软件测试的目的是提高软件的可靠性,终止条件当然是软件达到了测试的目的及要求。而解的优劣
    标准正好与软件质量相反,即软件失效几率越大,这个测试用例(一个输入的解)越优。文献2中
    结合北大的青鸟黑盒测试环境提出了一种基于测试执行的失效数据模型JBFDM(Jade Bird
    failure data model)。利用该模型我们可以做到2:
      (1)提供一致的失效数据建模、收集及管理的可靠性度量过程,从而支持可靠性度量;
      (2)利用测试及软件现场收集的数据来评价测试计划、操作概图及测试方法的有效性。
    软件测试的目的是发现错误,在黑盒测试中,错误表现的形式是软件失效。但是由于软件错误并不是软
    件失效的充分条件,换句话说,并不是所有错误都会在测试或运行时暴露,所以黑盒测试的目的就是尽
    可能的通过运行测试用例使软件失效而发现错误。在我们对测试用例的评价时,用以下的数据表示测试
    用例的优劣:A=P+λ/M+μ×F。
     
      其中A表示遗传算法中的适应度Adaptation,P表示该测试用例在实际中发生的几率P
    robability,M表示平均失效时间(MTTF),F表示失效等级。因为测试是针对使用的
    ,所以发生几率高的测试用例适应度高就不难理解了;而M——平均失效时间越长,该测试用例应该不
    容易发现软件的错误,所以A越低;F则表示某些特殊情况发生使软件严重失效(比如造成死机、损坏
    仪器等等),中国IT室验实此时该测试用例以及其后代
    必须被重点关注,所以此时A越大。λ、μ是相应于各个具体的被测试软件模块而定的系数。在实际应
    用中,由于软件失效的可能性不是特别大,所以遗传结果往往是发生几率高的测试用例后代较多。所以
    我们应该针对具体被测试软件设计准确的发生概率产生算法。具体算法框架如图1所示。
      
      对于该算法的说明如下:
      *1。每一个输入参数往往有一个几率(可以事先定义),可以简单相加来求得该测试用例的概率。
    但是在输入参数有较强相关性时,此方法并不能准确求得某个测试用例的发生概率,一个解决办法是设
    置输入参数的相关耦合度。在遗传算法的交叉、变异时其同时进行的几率与相关耦合度成正比,即对于
    相关耦合度高的输入参数,它们同时进行交叉、变异的几率高,反之则低。
     
      *2。检验是否满足测试要求时,需要先设置一个计数器。每运行一个新的测试用例,测试计数器加
    一。当发现第一次失效或故障时,计数器加二。若产生的遗传后代又使软件发生失效,则计数器加22
    。同理递推,当遗传算法产生的测试用例连续n次使软件失效,则计数器加2n。同时,记录所有的测
    试情况(此工作由外围的测试环境完成,比如北大的青鸟黑盒测试环境)。如果出现严重错误则终止测
    试,进行对程序的检查。如果连续k代测试用例的遗传后代都运行良好,计数器的值加2k。k的值由
    具体被测试软件的等价类数量、输入参数个数等决定。当测试计数器的值达到所有黑盒测试用例等价类
    的数值时(对于我们上面所举的例子,该值为55=3125),结束测试。当生成的孙子代、子代与
    父母代三代完全相同时,算法也必须结束,因为此时测试不会有新的结果。所以我们还要设置一个结束
    条件。而且该条件强于计数器条件。
     
      *3。每一组测试用例可以生成多个测试用例,根据适应度函数大小决定留下哪些测试用例组成新的
    测试用例组。
     
      从上面的算法框图和说明可以看出,如果某测试用例使软件的运行发生了问题(即某个软件错误发
    作),它的后代也同样受困于该软件错误,算法很快能发现这些最佳测试用例并给出结果。测试人员就
    可以将它们交给开发人员解决这些问题。若软件本身确实质量优良,这些测试用例及其不同的后代无法
    发现失效,算法也能尽快结束,而不是完成所有测试用例(虽然从理论上,我们希望测试尽可能运行所
    有测试用例)。
     
      2 效果
      上节的算法,相对于运行所有测试用例,并没有比较明显的优点。尤其对于测试来说,算法并没有
    加速运行测试用例,好象还降低了运行速度。其实算法本身的确不是用来加速运行测试用例的,其目的
    是找到一组最佳测试用例。因为实际上对于很多模块运行所有测试用例或哪怕是所有等价类都是几乎不
    可能的。
     
      以上一节举的例子做说明,其输入等价类大致有55=3125。如果一个模块有10个输入、每
    个输入有10种等价类,那么输入等价类为1010。按运行一个等价类需要1分钟计算(很多循环运
    行模块可能不止1分钟),需要几个月才能运行一遍所有等价类。这时,运用遗传算法的优势就体现出
    来了。
     
      综上所述,本文提出了一种利用遗传算法寻求最佳测试用例的测试方法原理。它能在较短时间内完
    成软件模块的黑盒测试并给出测试结果和好的测试用例。利用该算法原理,可以在测试集成环境中做一
    些设置或修改测试集成环境,这样可以大大提高测试工作的效率。
Open Toolbar