对于QA来说,测试用例就是我们的源码库。测试用例的重要性自然也是不言而喻的,相信每一个QA都曾在“写不完”的测试用例文档里挣扎过,也可能至今还有着——到底什么样的测试用例才是是好的测试用例——这样的疑问。
今天想从实用的角度总结一下测试用例的设计方法,本文是理论篇,内容包括什么是测试用例,为什么需要测试用例,以及常用的测试用例设计方法;后续还会有实用篇向大家分享,我在平常的工作中是怎么写测试用例的。
1. 什么是测试用例
软件测试员做些什么: 发现软件缺陷 (而不是简单得验证功能是否实现) ; 尽可能早地找出软件缺陷; 并确保其得以修复。 ——Ron Patton 《软件测试》
测试用例(Test Case),就是为了验证某个需求是否实现、是否存在缺陷,在测试执行之前设计的一套详细的测试方案。测试用例通常由测试标题、前置条件、测试数据、测试步骤、预期结果等组成。
下面的示例是“豆瓣PC端登陆功能”的测试用例:
测试用例示例
敏捷开发团队中,测试用例的设计和执行通常都是一个人,这时,对测试用例文档通常没有严格的格式要求,清晰准确即可!
2. 为什么我们需要测试用例
- 如果我们不使用测试用例,难道就没办法检查出缺陷吗?
- 可以不编写测试用例直接进行测试,但这样是有风险的,不能够保证全面覆盖。除此之外,测试用例还可以:
· 体现QA了解需求的过程
敏捷开发团队中,QA通常是从IPM阶段开始接触到新的需求,此时用户故事的需求描述、Acceptance Criteria、原型图等都已基本完成。QA在编写用例的过程中,将仔细梳理整体业务流程、充分思考产品需求的细节,找出需求是否存在不合理、有矛盾、不明确等问题,从而推动BA/UX完成更加详细的设计。
· 帮助QA理清测试思路及测试过程
测试用例的编写,实际上是把需求转换为一种可操作步骤的行为。QA也没有那么强大的大脑能够把所有的操作步骤都记在脑海里,写下来不仅能帮我们记住,写下来的这个过程也是梳理测试思路的过程。特别是,当你将当前需求的用例都罗列出来时,也能很清晰规划之后的测试顺序。
· 规划测试数据的准备
我们可以看到,在测试实践中,测试数据是与测试步骤分离的。在测试执行前,按照测试用例准备一组或若干组测试数据,特别是一些需要其他人协助准备的测试数据,这十分有助于高效的测试执行工作。
· 记录测试所覆盖的测试内容,同时反应测试进度
依照测试用例执行测试,并及时记录每一个测试用例的测试结果,这样项目成员都能够清楚地了解到目前已经完成了哪些测试,这些测试覆盖了哪些需求。那么在一些突发情况下,比如你被调离或离职,别人也能迅速了解测试覆盖内容及测试进度。
· 为后续的测试提供可参考的依据
新加入的功能可能会影响已有功能,新的需求是对原来的功能进行优化,新版本要上线等,项目进行过程中有这很多情况,都需要QA进行回归测试,有了测试用例,回归测试就能按部就班进行。
· 是分析缺陷的标准
测试用例并不是一写完就再也不用更新了。通过记录的缺陷数据,与测试用例进行对比,分析是否存在漏测情况,即当前测试用例是否能够覆盖该缺陷,若未能覆盖,说明当前测试用例集不完善,应补充相应测试用例;若已有相应测试用例,则表明测试执行过程中存在问题。
简单来讲,测试用例能够帮助我们在测试执行前澄清需求、梳理测试过程,并提前规划好测试数据;在测试执行中作为清单使用,记录测试覆盖的内容、反应测试进度;测试执行后也能作为回归测试等的参考,能与缺陷记录结合分析,来不断完善测试用例本身。
3. 常见的测试用例设计方法
常用的4种测试用例设计方法
测试用例的设计方法有很多,但在实践中,最常用也是最有用的方法就是上图所示的这四种方法,下面我会详细介绍这些方法。
3.1 等价类划分法
有这样一条测试基本原则:穷尽测试是不可能的。即使是看起来规模很小的软件产品,其输入数据的组合或逻辑路径也几乎是无穷的,也就是说,想对测试对象进行完全的检查和覆盖,基本上是不可能的。
- 既然无法用穷举法来测试,那我们是否能从大量可能出现的数据中,选取一部分进行测试?可以随机选择任意一个值么?*
- 当然不能是随意值!但是如果我们使用合适的数据选择方法,可以达到与穷举法相同的测试效果!
我们可以依照数据的特性,将所有的测试数据分为若干个类,每一类的代表性数据在测试中的作用等价于这一类中的其他值,也就是说,如果某一类中的一个例子发现了错误A,这一等价类中的其他例子也能发现这个错误A;反之,如果某一类中的一个例子没有发现错误,则这一类中的其他例子也不会查出错误。这种划分数据的方法被称为等价类划分方法,划分等价类时遵循以下3个标准:
· 完备性:划分的子集合的并集是整个集合;
· 无冗余性:子集互不相交;
· 等价性:属于同一等价类的测试数据,映射到”相同的执行路径"。
通过这种选择适当的数据子集来代表整个数据集的方法,既降低了测试的数目,又实现了“合理的”覆盖。
注意:软件不仅要能接收合理的数据,也要能经受意外的考验。因此在划分等价类的时候不仅要考虑合理的、有意义的输入数据构成的集合,还要考虑不合理的或无意义的输入数据所构成的集合。我们将前者称为有效等价类,它能验证需求是否实现,后者则为无效等价类,能检验是否会出现异常。无效等价类至少应有一个,也可能有多个,视具体情况而定。
EXAMPLE 需求:要求用户输入年份,年份限定在1980年~2020年,由4位数字表示。
使用等价类划分法,首先确定有效等价类:4位数字字符且年份为1990~2020,然后确定无效等价类:如输入的类型和长度不合理,年份超出范围等,具体如下表所示:
设计测试用例,覆盖所有的有效等价类和无效等价类:
3.2 边界值
从过往的经验来看,大量的错误发生在输入或输出范围的边界上,而不是在输入输出范围的内部。因此针对各种边界情况设计测试用例,有很大的概率可以查出更多的错误。
这种对输入或输出的边界值进行测试的方法就是边界值法。边界值法多用于对数据进行测试,在数据测试的时候,除了要关注边界值还要关注默认值,空白,空值,零值和无。除上述常规数据外,非常规的数据还要关注非法值、错误值、不正确值和垃圾数据,即所有可能的无效等价类数据。
具体应用边界值法时,应当选取正好等于,刚刚大于或刚刚小于边界的值作为测试数据,而不是选取等价类中的典型值或任意值作为测试数据。要特别说明的是,使用边界值法不仅只考虑输入数据,也应该考虑输出数据。
EXAMPLE 需求:豆瓣用户可在首页搜索框内输入关键词搜索感兴趣的内容。如在豆瓣搜索“星际穿越”。
使用边界值法设计测试用例,覆盖输入数据和输出数据:
· 关键词(输入数据):
- 为空
- 关键词长度为1(最小长度)
- 关键词长度为60(最大长度)
- 关键词长度为61
· 搜索结果(输出数据)
- 搜索结果为空
- 有一个搜索结果
- 有20个搜索结果(一次最多展示20条数据)
- 有21个搜索结果(通过更多按钮查看)
3.3 场景法/流程分析法
上面介绍的这两种方法对于单点测试是十分有效的,例如用户想使用Amazon买东西,搜索输入框的测试我们可以运用边界值法。但是搜索可能只是用户使用Amazon的第一步,Ta还可能点击某商品查看详情、将商品加入购物车、从购物车中进行结算或者使用直接购买功能结算,用户的操作会触发事件,不同事件触发的顺序不同,会形成不同的事件结果。
根据场景来设计测试用例的方法我们称之为场景法,也称为流程分析法。使用场景法的第一步自然是画出业务流程图,通常我们能从BA/UX处获取到流程图,如果没有,那就需要自己去梳理了。场景法一般包含基本流、备用流和异常流,基本流表示通过业务流程时输入都正确,能达到目标;备选流表示通过业务流程时输入错误(或者操作错误)导致流程存在反复,但是经过纠正后仍能达到能达到目标;异常流是指通过业务流程时输入错误(或者操作错误)产生异常终止流程 。
画流程图可以先从基本流开始,也就是先确定Happy Path,然后补充备选流,最后还要考虑异常场景来确定异常流。有了流程图,就可以从中选取测试路径来构造测试用例。
EXAMPLE 需求:”豆瓣评分“微信小程序支持用户使用微信登陆,并在登陆时获取用户的手机号码。
上图左为已开发完成的微信登陆功能截图,右图为根据要求画出的业务流程图,图中实际上只包括了基本流和备选流,异常流留给大家自己补充。根据流程图设计的测试用例的过程较为简单,我在这里也不再赘述。
3.4 错误推断法
在测试程序时,人们可以根据经验或直觉推测程序中可能存在的各种错误,从而有针对性地编写检查这些错误的测试用例的方法,这种方法被称为错误推断法。
错误推断法没有固定的形式,依靠的是经验和直觉,很多时候,我们都会不知不觉的使用到。
错误推测法和目前非常流行的“探索式测试方法”的基本思想和理念是不谋而合的,这类方法在目前的敏捷开发模式下的投入产出比很高,因此被广泛应用。但是,这个方法的缺点也显而易见,那就是难以系统化,并且过度依赖个人能力。
因此,对于像我这样的新人QA来讲,就要多多实践,可以准备一份清单,将自己遇到过的错误记录下来,也可以向有经验的QA请教,不断丰富自己的经验。
4. 总结
文中介绍了4种最常用的测试用例设计方法,希望能够对你的工作有所帮助。测试用例的设计方法其实还有很多种,具体大家可以去看《软件测试》或《软件测试的艺术》等书籍,我在这里就不再赘述了。
值得注意的是,本文介绍的这4种测试用例设计方法,通常都不会单独使用。在“实践篇”中,我会有具体的例子,详细讲解,我们在实际工作中应该怎么综合运用这些方法。