技术开发 频道

RUP测试过程实践

  如何划分测试用例的粒度?

  我们是不太可能在一个测试用例包含所有测试需求的,因为众多的功能以及不同的路径组合将使这样一个测试用例像巨无霸一般,完全不具有可操作性。——除非您的软件所包含的功能真的又少又简单,不过如果真的有这么一个软件,恐怕也没有测试和发布的必要了。

  当然,这也并不是要您走向另一个极端,为需求中定义的每个特性或功能都提供一个甚至多个测试用例。这里的关键,是要寻找一个合适的度。 笔者推荐的方法是:关注有效功能。

  有效功能:就是指在被测应用所涉及的实际业务中,当用户在手工状态下进行工作时,整个业务流程中对用户来说,具有实际意义那些功能。这个功能的特征是当我们把这个功能单独从计算机软件还原到用户的原始手工状态时,它的完成可以作为用户实际业务的一个阶段性结束的标志,而不是一旦从这个业务流程中独立出来就失去了意义。而该业务完成后,可以为其他用户或业务提供所需要的信息。

  这里区分“有效功能”的关键有如下两个:

  1. 这个功能是可以还原到用户原始的手工业务流程中去的。我们的计算机和软件,都是为了帮助用户解决手工业务中一些烦琐和低效的问题,而提出的一些忠实于原始工作方法或略有变通的解决方案,并不是要改变用户全部的业务流程。所以,应该从用户实际业务的角度来判断功能是否有效。

  2. 这个功能是否可以标志着用户实际业务的一个阶段性结束?并且这项业务完成之后,被完成的业务实体是否可以交付给其他用户或业务以供完成下面的工作? 为了方便理解,我们可以先看一下下面的例子。拿我们常见的财务软件来说,当添加一张会计凭证时,通常是需要填写会计科目,在使用计算机完成工作时,我们可以利用软件的功能,从很多备选科目中选择一个自己需要的科目,或者通过科目代码来输入科目。这项功能很有可能会作为一个特性要求出现在软件需求规格说明书中,那么这个科目的选择或输入是不是一个有效功能呢?让我们试着用上面规则来衡量一下。首先,这个功能在用户手工业务处理过程中是存在的,不同的是这项功能是在用户填写凭证时,在自己的大脑中完成的——用户会根据需要,在自己记忆的科目中选择合适的填写上去,这项功能节省了用户在记忆大量会计科目时付出的额外劳动。我们可以认为这个功能是为用户原来的工作提供了一种简便的、变通的方法。那么这项功能的完成对于用户来说意味着什么呢?我们从上面的描述中可以看到,用户希望软件提供的是可以添加一张完整的凭证这样的功能,而不仅仅是方便填写会计科目。填写会计科目只是用户在添加凭证时的一个步骤,单独把这个功能提取出来对用户来说没有任何实际意义。对于业务流程下游的用户,需要的也不仅仅只是一个会计科目的信息,而是一张包含了会计科目以及其他会计信息的完整的会计凭证,否则就无法进行下面的工作。这样看来,这个功能并不是一个有效的功能,我们可以把它最为需要测试的特性在测试需求中进行描述,却不应该作为一个单独的测试用例出现在我们的测试用例集中。而我们在测试用例中真正关注的,应该是添加会计凭证这个具有实际意义的功能。另外,我们还需要关注如何将多个相互之间存在依赖关系的功能区分为单个的有效功能。例如,现在有 A、B、C三个功能,其中B功能的开始必须依赖于A功能的完成,而且A功能如果出现不同的完成状态,B功能也会做出不同的反应;C功能对B功能的依赖也是如此。那么这时候,我们是否应当将三个相互依赖的功能包含在一个测试用例中呢?这样的做法也不是不可以,但是我们也可以先判断一下,这三个功能是否都是有效功能(您可以使用前面提到的方法来试着评判一下)?如果A、B、C都是独立的有效功能,那么我们可以从上面的描述中发现,它们之间存在的依赖性,可以理解为是一种状态或者说数据的依赖性。后一个功能关心的,是前一个功能最终提供给它的是什么样的“输入”,而不是前一个功能到底作了些什么。这样看来,我们完全可以将它们分别包含在几个独立的测试用例中,而在每个测试用例的开始,把不同的输入作为不同前置条件来描述。

  测试用例是否应该包含所有的细节?

  这是在网络上听到诉苦最多的又一个热点问题:公司要求按照一个严格的规范来开展测试工作,必须书写所有的测试用例文档,要求文档的书写一定要具体,并在执行测试时要参考测试用例文档来进行。如果测试用例文档写的过于简略,则会被领导斥为偷懒。但是,如果文档中的对操作步骤描述的过于具体,像下面这样:

  01.  在“用户名”项中输入“user”;

  02.  在“密码”项中输入“password”;

  03.  点击“确定”按钮。 这样的描述方式表面看起来可操作性似乎是增强了,任何人拿到这个文档都可以充当测试人员,检查一下这个功能是否存在缺陷。但是我们不要忘记,在开发过程中,变更的存在是必然的。一旦需求、设计或者应用程序中的某些细节发生了变化,比如“用户名”变成了“操作员”,“密码”变成了“口令”,“确定”变成了“登录”,或者输入项所接受的数据类型发生了变化,那么同这部分内容相关的所有的测试用例都需要修改。否则,我们凭什么可以保证这些描述不同的测试用例说的是同一样东西?如果我们只有这么一个测试用例,也许一切都不是问题,但是对于一个业务复杂、功能完整的系统,如果按照这样的方法描述测试用例,最终要么产生大量的测试用例文档,要么产生过长的单个文档。无论是那一种,如果发生了类似于上面说的变化,维护文档都将变成一次地狱式的体验。这也是为什么在网络上频频出现的这个问题,而且每次出现都会受到测试同行们的关注的原因。那么这个问题应该任何解决呢?测试用例是不是把所有的流程写出来就可以了呢?如何在减少测试用例文档中包含过多琐碎的细节的同时保证测试用例的可操作性呢?又有什么方法可以提高我们维护测试用例文档的效率呢?笔者的建议是:关注“测试思想”而不是关注操作步骤。要理解这个问题,首先要弄明白测试用例的作用。就像用例一样,测试用例并不是用来描述具体的实现的,而是着重描述处理问题的思路——对于一项明确的测试内容进行测试的思路。作为测试用例的设计人员,如何理解基本流和备选流?如何深入分析并找到所有需要覆盖的路径和需要检查的特性?我们在测试用例中应该用容易理解的自然语言清晰的来描述我们将要如何进行测试,而不是简单的把在应用程序上如何操作的烦琐的步骤记录下来。把测试用例设计当成填写具体操作步骤的表格是人们对测试用例最大的误解。传统的测试用例文档编写有两种方式。一种是填写操作步骤列表:将在软件上进行的操作步骤一步一步详细的记录下来,包括所有被操作的项目和相应的值。另一种是填写测试矩阵:将被操作项作为矩阵中的一个字段,而矩阵中的一条条记录,则是这些字段的值。网络上对于这两种方式孰优孰劣的争论,将大家错误的引导向了两个极端:要么采用 A,要么采用B。而大家却忽视了一点,对于工作方法的争论,本质上同工具的争论并不是一回事(例如曾经的VC、BCB之挣)。如果不同的方法各有优势,我们完全可以通过变通的方法,把优势的部分组合在一起来使用。 操作步骤列表的优势在于对基本流和备选流进行分析后,它可以清晰的描述您的测试思路。而测试矩阵则更适合于用来存放测试数据,特别是那些需要人工赋予一个确定的值的特性。下面,我们来看一个例子,当然,这个例子同样是杜撰的。需求名称:用户登录安全验证需求描述:用户登录安全验证是为了保证所有登录到系统中的用户,都是由系统管理员预先在系统中设定的。使用系统中不存在的用户名,或者用户名输入正确,但密码输入错误情况,都无法登录到系统中。当用户使用了不存在的用户名或错误的密码时,系统应分别给出适当的提示。如果用户连续三次无法使用正确的用户名和密码登录到系统,则系统应给出适当的提示,并退出当前程序。如果用户使用正确的用户名和密码登录到系统,则退出界面,转到系统主界面。对于用户登录界面和程序主界面,请参考相应的 UI设计文档。

0
相关文章