qileilove

blog已经转移至github,大家请访问 http://qaseven.github.io/

如何写更好的自动化测试用例

抱歉, 文章的开头我需要先给这个[自动化测试用例]设一个范围. 自动化用例的形式有很多, 根据测试对象和测试环境的不同, 有各种script和自动化框架来支持你开发出各式各样的用例.
  而本文是基于Robot Framework, 一种keyword driven(关键字驱动)的自动化测试框架来讲的. 如果你是被题目给骗进来的, 那就说明我的第一个目的已经达到了, 哈哈!
  关于更多Robot Framework的信息请google.
  工作中我经常需要去review其他同事的自动化用例(是的,像软件代码那样被review). 我通常从4个方面来审查用例的质量:Readability, Maintainability, Reliability, Performance,
  而这4个方面可以具体到下面这些具体工作:
  Coding Style
  良好的规范可以极大的增强用例的可读性和可维护性. 当这些用例被转交给他人时, 也会因为相同的coding style增加对方的接受度.
  当一位"新人"参与用例编写时我会首先把注意力放到Coding Style上, 因为这也是最容易做到的. 为此我们定义了一些规范:
  a.好的命名规范
  文件名不能包含特殊符号并且遵照特定的格式. 不同作用域的变量采用不同的命名方式, 变量名描述的更有意义, 全局变量要在Variables表中定义..
  还有case的命名、keyword、case setup、teardown.
  b.documentation
  作为用例的补充信息documentation是必不可少的,如果测试用例本身或者背景太过复杂, 我们还可以给suite、test case、keyword分级加注释.
  c.tags
  给用例打上正确的标签.标签的应用非常的广泛和灵活既可以拿来做用例筛选、版本管理、统计、调度策略,还可以为一些测试策略如[基于风险的测试]提供方案.
  d....
  让case读起来像文档
  在考虑Coding Style时我们可以设置一些固定的规则,大家只要按照这个规则来做,实践几次之后Coding Style就会趋于统一. 而考虑将case写的如同文档一般则需要更多的主观能动性.
  为什么需要这样的mindset? 公司开始推行敏捷之后,测试也在不断的追求更敏捷的测试.敏捷强调 "快速进入, 不断迭代", 而文档在整个开发过程中不可避免的被弱化, 需求设计不断的更新,
  文档往往不能被很及时的更新. 那么怎样可以让测试人员如何快速的掌握某个功能或者产品的需求和当前状态呢? 答案是用例.
  a.简洁明了的documatation
  通过增加[用例注释]来增强用例的可读性是一个不错的办法.一个suite文件往往包含了一组测试用例,suite level的documation通常可以包含该组测试的背景信息、这组测试的目的、特殊的环境配置说明等.
  要控制documatation的长度,可以通过添加link来扩展更多信息.不要过多的描述测试的详细内容,用例本身应该对其有很好的描述.也不要因为文档而文档,将case名或者重复的信息放在上面.
  case level的documatation我们觉得一般情况下是不需要的, 因为case的结构本身应该足够清楚的描述.
  b.清晰的用例名
  用例文件名应该能简单描述文件内所有case的测试目的.我们建立一个目录来存储测试点相近的测试用例, 目录名可以更抽象, 然后我们给这个用例一致的命名规则.
  这样当在你浏览一组用例时,仅仅通过用例名就能大致了解里面的测试内容,也方便你寻找某个case. 应该更多的从用户角度来思考文件名,对比下面两个文件名:
  Suite Name1: creation handling after remove unnecessary fatal error.html
  Suite Name2: Avoid DSP restart by removing unnecessary fatal error when timeout happened during call creation.html
  c.条例清晰的case step
  case name
  case step
  keyword
  case的独立性
  通常一个test suite包含了一组相近的或者有关联的test case. 而每一个test case应该只测试一种场景,根据case复杂程度的不同场景同样可大可小,可以是某个功能的测试也可以是端到端的完整测试.(当然也有特殊的写法比如工作流测试和数据驱动.) case的独立性又有哪些需要关注的点呢?
  首先一个test suite内的test case在执行时不应该相互影响, 应该将通用的背景部分提取出来放到suite setup中, 允许我随机的跑某一个case或者乱序的跑这些case. 如果case的步骤有造成环境被破坏的风险,那应该在case teardown中将环境恢复,并且在case setup中做环境监察以及时的终止case. suite level和folder level同样要注意独立性的问题,在CRT中通常会将数百数千的case放在一起跑,robot并不会规定case执行的顺序所以从某种程度上来说它是随机的.独立性还体现在case fail时信息的抓取上,经过一个晚上大批case的执行之后,环境通常已被破坏, 希望通过保留现场来用作case失败问题定位是不现实的.
  所以每个case都应该准确的收集其开始和结束之间的信息.
  case的可迁移性
  case的可迁移性主要考虑:case对执行环境的依赖,case对外部设备的依赖,case对测试对象的依赖.
  a.避免依赖执行环境,你一直在个人PC上编写的用例并执行测试,但是不久之后你的用例就会被迁移到组内的测试执行服务器上,之后又被部署到持续集成服务器上,
  中途也有可能被其他同事下载到他的个人PC上来执行测试.所以在编写用例时我们要避免支持不同平台的不同库(windows,linux)和或者不同的脚本命令(CentOS,RedHat,MacOS)
  总之要像Java宣扬的那样"一处编译处处运行".
  b.在通信领域为了测试需要或者扩展测试覆盖,我们会引入一些外部设备如Spirent、Cisco的一些辅助测试设备,各种网络设备交换机、路由器,还有一些自行开发的模拟设备.
  外部设备会不断的升级或者更换,在编写用例时我们就需要考虑如何用一套case更好的兼容这些测试设备. 我有如下几点建议:
 i.首先将外部设备的操作从测试用例步骤中剥离出去,组织成组级别的库.
  ii.
  c.对测试对象的依赖,这里我考虑到的是如果测试对象是一个软件平台,软件平台通常需要适配多种的设备.而设备的硬件配置可能是多种多样的,CPU、内存、组件的性能和数量都可能不同.
  对测试对象的依赖不仅要考虑在不同设备上的可执行性,重点要考虑测试覆盖率,由于设备组件的增多你的用例可能无法覆盖到这些组件,或者捕捉不到某个性能瓶颈,这样测试结果的可靠性也大打折扣.
  case的可重用性
  自动化用例的开发通常是一项费时的工作,它需要的时间会是手动执行用例的10倍、20倍甚至更多. 我们通过搭建测试框架和封装资源库来实现最大范围的可重用性.
  这里我考虑用例的可重用性包括两块:逻辑层的抽象和业务层的重用.
  对一个产品或者功能进行自动化工作时,我们要考虑这些可用性:首先根据测试逻辑的不同对测试用例进行分类,根据逻辑的不同选择搭建有针对性的case框架,Work Flow, Data Driven等.
  建立公共的库,将业务的原子操作抽象出来,并且鼓励其他同事对库进行补充和调用,避免duplicated库开发.抽象的API通常需要足够的原子和灵活才会被大众所接受. 基于底层API编写的业务操作也具备可重用性,比方说测试场景(背景资源)的建立、工作流的操作组合、检查点都可以被复用. 层次分明的抽取时重用性的基础,提高可重用性可以减少开发时间,也方便日后的维护中的迭代修改.
  case的效率
  不同的case执行时间相距甚远,短则数秒长则数小时甚至数天,数秒钟的简单功能测试用例和稳定性测试耗时数天的用例本身是没有什么可比性的.但是我当我们放眼某一个或者某一组case时,我们需要重视效率.不论是敏捷还是持续集成都讲究快速的反馈,开发人员能在提交代码后快速的获得测试结果反馈,测试人员能在最短的时间内执行更大范围的测试覆盖,不仅能提高团队的工作效率也可增强团队的信心.
  在编写用例时我们应该注意哪些方面来提高用例的性能?
  对于单一的case我的注意点多放在一些细节上,例如:
  1.执行条件的检查,如果检查失败,则尽快退出执行.
  2.将执行环境搭建或者资源建立和清除 抽取到suite甚至folder level, 抽取时可能需要做一些组合, 但决不允许出现重复的建删操作.
  3.用例中不允许出现sleep,sleep通常紧接着hard code的时间,不仅效率低还会因为环境的切换使得执行失败.建议用"wait until ..."来代替.
  4.如有不可避免的sleep,我通常会再三确认其是否清楚它的必要性.
  对于批量的case,我们要如何才能获得更高的效率呢?
  1.首先我们考虑到可以并行的执行一组case来提高效率,并行方案总有着严苛的条件:
  2.为了获得更快的反馈,我们将软件质量分为0~10级,对应的把测试用例分为6~10级,从普通的功能测试开始测试复杂度逐级递增.
  不同的开发阶段或者是针对不同的测试目的我们就可以有选择的调用不同级别的用例.比方说我们调用6级的cases来测试新功能代码作为冒烟测试的用例集;软件人员修改了BUG,我可以根据BUG的复杂度选择7和8级的用例来验证,系统级测试时我们又会主要测试8和9级的用例.
  分级可以灵活调度用例,并给出更快的反馈,加速迭代过程.
  3.基于风险的测试
  基于风险的测试简单的说就是根据优先级来选择需要运行的测试,优先级根据两个最基本的维度:
  功能点发生错误的概率,以及发生错误后的严重性,根据两者分值的乘积来排序优先级.
  一般从用例失败率,bug统计,出错的代码段,更新的代码段来考虑调度.比方说根据BUG修改的代码段和功能区域来选择对应的测试.开发人员通常反对这种方式,只有100%的测试覆盖才能给他们足够的信心.
  以上是个人的一些积累,由于框架的限制一些建议不一定适用于你的实际工作. 如果你有什么建议欢迎留言. Thx!

posted on 2014-10-09 10:16 顺其自然EVO 阅读(613) 评论(0)  编辑  收藏 所属分类: 测试学习专栏


只有注册用户登录后才能发表评论。


网站导航:
 
<2014年10月>
2829301234
567891011
12131415161718
19202122232425
2627282930311
2345678

导航

统计

常用链接

留言簿(54)

随笔分类

随笔档案

文章分类

文章档案

搜索

最新评论

阅读排行榜

评论排行榜