一、前言
随着软件系统规模的持续增大,业务复杂度的逐渐增加,软件测试所面临的挑战也随之提升。而软件测试工作复杂度的直接体现就是测试用例编写、维护、执行、管理、协作等方面。所以编写易读、易维护和易管理的测试用例可以有效的降低测试工作的复杂度。
在软件测试工作中,测试用例是其最为重要的基础。一个良好的测试用例可以帮助测试人员更容易阅读,理解,修改并管理它,从而提高测试工作的质量和效率。要编写一个好的测试用例,首先需要对业务需求和验收标准进行深入的分析,并确定业务需求和验收条件的正确性和合理性。然后对其进行测试分析,并完成整体测试用例的设计和编写,其中常见的包括功能测试用例,端到端测试用例,异常测试用例等等。
在分析和设计用例的过程中,可以通过类似启发式测试策略模型 HTSM/MFQ需求分析这类方法来进行设计,并通过等价类、边界值,场景法、错误推测、决策表,正交(PairWise) 等方法来设计测试用例。其中的难点如何让测试用例尽可能的覆盖到验收标准,从而完成验收功能的高覆盖测试率。并且还要尽可能找到业务需求,技术架构等系统相关的各种限制,通过分析限制可以得到更多的测试用例,其中也包含各种异常测试。对于设计好的测试用例需要进行分类并管理,然后根据不同的分类进行分段/分层测试(端到端测试,功能测试,集成测试,单元测试)。即横向与纵向
对于不同类别、不同测试阶段来说,由于一个测试用例可能既属于回归测试,又属于冒烟测试由或开发自测甚至是自动化用例,所以这种情况下就需要一个良好的测试管理系统或者管理方法来对大量的分类后的测试用例进行管理。
编写和管理测试用例是测试用例工作中工作量最大也最为繁琐的部分。其质量的高低直接影响到测试工作是不是能高效和顺利的进行并完成。所以结合产品的类型和团队的情况,选择适合自己团队的用例编写和管理方式,从而事半功倍。
「测试用例设计」是每一名测试人员必备的基本功,测试用例是测试思维的直接体现,测试用例的好坏直接影响到测试的有效性,测试用例的重要性不言而喻,但是往往很多测试人员其实都忽视了这一点,但是想要设计好一份有效且合格的测试用例也不是一件容易的事。
那么问题来了,你认为一份有效且合格的测试用例应该是怎样的?或者说具备哪些条件?该考虑哪些因素?
衡量一份测试用例的好坏,不应该从能发现缺陷的数量去衡量,更多应该从用例集合的完备性(覆盖率)角度去考量,即测试用例是否能够覆盖等价类、边界值、常见错误、场景、因果关系、组合等为维度去考量。当然这是测试用例最基础通用的现状。
测试活动由于受限于时间成本而测试穷举的局限性,只能采用基于风险、优先级、成本等情况综合考量设计。那么如何通过科学有效的方法论去选择更有效、更合理、覆盖范围更精准的测试用例集合。即,就是有所侧重的去选择测试范围、颗粒度、优先级,以寻求质量风险和时间成本之间的平衡。
二、测试用例分类
-
验收用例
验收测试用例的核心就是验收条件(AC),对于明确清晰并且细化到足够程度的验收条件,可以直接转换为或者作为测试用例来使用。但是往往很多情况下测试用例没有细化,甚至不够明确和清晰,存在歧义,从而导致很难设计出足够的用例来映射到所有验收条件,称之为 AC Mapping。
其次对于整个软件系统来讲,由于很多验收条件都是一些分散的点,而如何通过分析业务需求和验收条件等来设计测试用例,保证测试用例对于系统功能或者端对端场景的全覆盖(即 Function/E2E Coverage)。
(Function/System Limitation)它的核心是如何通过分析验收条件,业务流程,技术架构等信息,发现某个功能或者系统级别的限制,只要突破这个条件限制,那么你可以认为它们是开始在做探索性测试,无论验收测试用例还是探索性测试用例,都可以使用各种基础的测试用例方法来分析和设计测试用例,比如等价类、边界值、因果图、错误推测法、场景法等。
-
探索性用例
探索式测试是一种软件测试风格,它强调独立测试人员的个人自由和职责,最大程度的发挥测试人员的主观能动性,为持续优化其工作的价值,将测试过程学习、测试设计、测试执行、测试结果分析,作为相互支持的活动。所以对测试人员的能力有较高要求。
在整个项目过程中并行地执行。而传统软件测试过程中严格的“先设计,后执行”。而探索性讲究的测试人员通过边测试、边设计、边了解被测系统,同时在了解过程中对关于软件系统的更多信息通过综合的整理和分析,创造出更多的测试用例。
对于测试用例本身,需要使用代码化的思维来进行编写,维护和管理,其目标就是易读,易维护,易执行和易管理。而目前测试用例几乎都是通过自然语言描述的,自然语言的多样性、二义性以及手工和自动化用例的转化和统一都成了管理维护过程中的“绊脚石”。从而可能会让用例设计和编写者以外的手动测试执行人员或者自动化测试及开发或产品人员产生误解,从而错误的理解测试用例,最终得到错误的测试过程及结果。
当测试用例的数量随着迭代和系统复杂度的提升之后,比如几千甚至上万或者更多的时候,维护和管理的问题也随之困难起来,其中包括如何统一管理自动化测试和手动测试用例,从而减少对于重叠/冗余测试用例的维护和管理。为了解决这些问题,需要用使用一些特定的方法来解决这些遇到的共性问题。
比如使用代码式思维来编写测试用例、用 DSL 语言来描述测试步骤以及测试数据分离等,还可以基于接口或者规则自动生成用例,又或者是根据业务特性和数据建模智能生成和管理用例。当然这些都依赖于当前团队所具备的基础建设能力和团队面临的现状来决定的。
三、测试用例的编写和管理
编写和管理测试用例一直是一件十分繁琐又很难降低成本的工作,为了尽可能降低其成本,测试用例需要具有以下特性:易阅读,易维护,易执行,易管理。而难点也比较突出:
-
其中包括语言的歧义性和多样性导致的不易阅读和理解;
-
强依赖于人员的执行力
-
手动测试和自动化测试用例很难统一管理和统一执行;
-
测试用例数量庞大难以管理
-
工具 /平台的易用性
如果测试用例管理库/系统不易用,其测试用例的复用性也不会高,则会导致测试用例不易维护,从而会极大的增加了其管理成本。所以测试用例的编写可以尝试以代码思维来描述,比如高内聚,低耦合,易复用,清晰的模块划分等逐步去解决上述问题。
例如:单元测试遵循的FIRST原则
[F]ast: 快速
[I]solated: 隔离
[R]epeatable: 可重复执行
[S]elf-validating: 自我验证
[T]imely&Thorough: 及时,全面
1.测试用例编写
测试用例的表现形式直接影响了它的可读性、维护性、管理性、协作性。因为一套不易读,冗长繁琐且没有统一规范的测试用例会直接导致测试用例难以阅读、维护、团队协作。其次还会直接影响到测试人员执行和验证结果的正确性。
所以,下面看几个案例:
这是一种常规的测试用例编写方法,通过描述操作和执行系统的步骤来描述测试用例。其优点是非常直观,而缺点是过于繁复。如果操作和执行步骤经常更改的情况下,其维护成本就非常高。所以它适合一些比较稳定,业务需求和执行步骤变更较少的项目。
*/
# 常规案例1:"注册一个邮箱账号成功"
Precondition:
1.用户准备申请一个邮箱<jiqialin@163.com>账号
Step:
1.在登录首页,点击创建新账号按钮
2.跳转至注册页
3.填写邮箱<>,输入两次密码一致
4.点击提交按钮
Expectation:
1.登录成功
2.跳转页面至设备首页
# 常规案例2:"注册一个邮箱账号失败"
Precondition:
1.用户准备申请一个邮箱<jiqialin@163.com>账号
Step:
1.在登录首页,点击创建新账号按钮
2.跳转至注册页
3.填写邮箱<>,输入两次密码一致
4.点击提交按钮
Expectation:
1.登录失败,异常提示"该邮箱已注册"</pre>
/*
在行为驱动开发(BDD)出现后,越来越多的测试用例通过用户/系统行为GWT来编写。其优点是相对于方法一,它非常简练。所以在修改和维护时成本较低。但是它有一个前提,就是测试执行人员必须了解功能细节的前提下,才能通过行为描述来进行测试。所以这种方法写出的测试用例多数用于自动化测试。
*/
# 系统或用户行为: "注册一个邮箱账号"
Given: 用户准备申请一个邮箱<jiqialin@163.com>账号
When: 在登录首页,点击创建新账号按钮
Then:跳转至注册页
When: 填写邮箱<>
When: 输入两次密码<>一致
Then: 按钮亮起可点击
When:点击提交按钮
Then:登录成功并跳转页面至设备首页</pre>
/*
方法一和方法二都存在不同程度的重复,不易复用。所以改善或者解决这两个问题,从而进一步增强测试用例的可维护性,降低新增用例和维护已有用例的成本,需要使用代码思维来进行测试用例编写。
其核心是尽可能抽象出通用的操作步骤或者系统行为的领域特定语言(DSL),然后通过参数化的方式来进行测试数据传递,从而复用领域特定语言。下面是通过本方法重写方法一和方法二后的实例,它主要体现了众多代码思维中的其中一种,即逻辑与数据分离。
*/
# 代码思维方式: "注册一个邮箱账号"
# 1.常规实例
Precondition:
1.用户准备申请一个邮箱<jiqialin@163.com>账号
Step:
1.点击创建新账号按钮
2.跳转至注册页
3.填写邮箱<>,输入两次密码一致
4.点击提交按钮
Expectation:
1.toast提示"登录成功"
2.跳转页面至设备首页
数据集:
|用户|结果|描述
|小A |成功|他是未注册用户
|小B |失败|他是已注册用户
# 2.行为实例
Given:用户准备申请一个邮箱<jiqialin@163.com>账号
When:用户完成新账号注册流程
Then:注册创建<结果>
数据集:
|用户|结果|描述
|小A |失败|密码输入不一致
|小A |失败|密码格式不正确
|小A |成功|他是未注册用户
|小B |失败|他是已注册用户</pre>
2.测试用例管理
测试用例管理是一项繁琐的工作,所以需要系统化的进行管理。目前业界存在几种经典方法:分别是文件管理、工具/平台管理、代码活文档和系统活文档。其实与编写用例一样,没有一种用例管理方法是“银弹”,没有那种方法能适合所有不同的团队和不同的项目或者阶段。所以必须先了解它们各自的特点,再根据自己团队和项目实际情况,选择适合的方式才是最佳测试实践。
案例1:文件管理(Excel/Xmind/Yaml/Json)
一般是中小型项目或者中小公司中比较常见的测试用例管理方法。其优势是简单易用,而劣势是需要自己对测试用例模版进行定制,并且当测试用例过多的时候管理成本会急剧增加。其次对于本地文件模式,则很难让多人进行协作编写,虽然目前有很多在线文档可以进行维护,但是依然存在这些问题 。
案例2:工具/平台管理(Jira Zephyr/TestRail/Redmie/Testlink/PingCode 自研......)
目前这种一般是中大型公司或项目中最为常用的管理方法。它的优势是管理系统提供了强大的管理和协作功能,比如协作编写用例,协作执行用例,测试步骤管理,截图管理,测试迭代管理以及丰富的测试用例和测试结果报表等。
但是它有一定的学习曲线,虽然基本上都是界面操作,但相对比较繁琐,维护成本依然高居不下。其次这种系统一般需要一个独立服务器来部署和运行,如 TestLink/TestRail;或者需要花高额成本购买 License。所以相对成本比较高。so
案例3:代码活文档
适合于有足够软件技术工程实践的团队和个人,因为它需要使用到代码版本管理工具(git/gitlab),集成开发环境(IDE),自动化测试框架(RF/HR/Junt5),CI/CD持续流水线等相关Devops实践才能高效的编写,维护,执行,管理测试用例并监测过程日志及报告。
下面看下 Cucumber 的一个示例:Feature 文件就是一套测试用例,可以通过Jenkins 生成测试用例活文档(Test Scenario Living Documentation),统一展示手工用例和自动化用的测试结果。
-
优势
是可以同时管理自动化测试用例和手动测试用例,并且更容易跟踪测试用例和测试数据的更改。
-
劣势
是需要测试工程师有足够的工程技术能力来实现。
案例4:工具平台结合活文档方式
将代码活文档和系统管理结合,通过测试管理工具平台编写和管理测试用例,然后会自动生成代码模式的测试用例。也可以只编写代码模式的测试用例,然后自动同步到测试管理文档中。然后自自动化测试在持续集成流水线执行,通过流水线进行展示并同步到测试管理平台中。
手动测试人员执行了手动测试后,将测试结果/覆盖率通过测试管理平台或者在测试代码中进行记录,并最终汇总到测试管理数据分析系统进行统一展示,从而实现了让不同人员可以一起协作分析,设计,管理,和执行测试用例的工作。
案例5: AI 智能测试
在敏捷开发的流程中,其实很早已经有关于“去用例化”的讨论了。
之前在参加QECON测试峰会的时候,看到字节和阿里有做一些实践,比如字节的智能测试4.0就是结合流量回放和精准测试体系做的一套系统,通过回放线上流量基于某些规则自动生成用例执行并输出测试报告进行分析,全程几乎无人工干预。阿里则是基于场景建模的全流程场景自动化,配合全链路压测做的无人值守的平台。看似美好,实际所需要的基础能力是一般公司很难具备的,光训练的数据模型的体量就难以想象,你懂我意思吧。
总结
测试用例是测试工作的根本,不管是手动测试还是自动化测试的测试,都十分依赖于测试用例的质量。只有充分的做好测试分析、设计、编写、管理才能产出一套合格甚至优秀完备的测试用例集合。从保证测试工作可以高效正确的进行,为产出高质量软件保驾护航。
网友评论