原创,转载请注明来源。
来到公司一转眼半年时间了,经历大大小小的版本发布测试,从系统管理到报表再到账务管理以及即将到来的资产,也从一个会计小白转型为会计菜鸟,对于测试技术也逐渐有了自己的认识和理解,这篇心得主要还是谈谈对于测试用例的看法。
在测试理论中,有一种测试叫AD-hoc测试,也叫做探险式测试,属于随机测试,指的是完全根据业务常识进行测试,觉得哪里可能会出问题,就过去执行下试试,而且这个过程是不重复的,进公司后我大部分单子都是靠这种测试方法发现的,原因是其一我不熟悉会计方业务知识,只能跟着感觉走;其二就是我们的用例的可读性差、低效性,用例中的冗余、细节遗漏、以及层次扁平化导致用例的命中率不高。
前几天一直在写功能测试需求,之前也只是理论上接触过,并没有真的实践过,加上没有现成可用的模板,写的比较糟糕,快写完的时候,有些问题才慢慢想清楚,有些结构层次才逐渐理顺,下面是我最近一段的心得(鉴于马上就要开始新一轮的测试用例设计了,结合最近一段设计测试需求以及进公司近段时间的测试感受,对我们当前的测试用例设计,以及用例的执行,简单谈下我的想法)写下来一方面是指导自己,总结这一段的学习成果,另一方面希望能从中给其他人带来一点启发。
功能性测试范畴
功能性测试,我的理解,就是用来验证程序的功能是否正常,它的步骤可以非常的详细(这里的详细是指对此功能点步骤的描述详细,而并非对约束条件、数据如何流转描述的详细)比如我们的凭证手工录入就是一个功能点,它的功能测试需求从最基本的测试点来说就是只要可以完成凭证手工录入这个功能,录入完成后在页面上可以显示出这条凭证,整个过程中没有功能点出现问题即可。
功能测试需求,就应该是详细描述功能点的各个功能,使得测试用例设计者拿到这个需求后就可以做相应的测试用例设计。对新人来说,详细的步骤有很好的指导作用;对熟悉者来说,详细的步骤,可以选择跳过,也可用来保证思维的连贯。
拿【凭证编辑】举例,比如“凭证录入界面,提供删除分录,插入分录的功能”“提供选择科目辅助信息的功能”这些都应该属于功能测试需求,即用来验证功能是否正常的,在设计用例时这些功能点都可以作为是否需要覆盖的路径来考虑。
至于那些所谓的必输项、文本框取值范围、数据读写权限等等,诸如“凭证制单时至少填写一处摘要”“凭证分录金额必须为数值”、“验证财务月份是否锁定后还能制单”等等,这些都应该属于约束性测试范畴而并非功能测试范畴,我在本文的第二部分会进行详细说一下我的理解。
又诸如那些“验证分录中含有银行类会计科目时在进行银行账户选择时是否可以正确读取资金模块的账户信息”“制单完成后是否可以正常流转到凭证复核”等等,因为它们都是由多个不同的功能用例组成,依靠单一的用例无法完成,所以这些都属于系统性测试范畴。在本文的第三部分我会详细举例来说下我的理解。
对于我们当前TD中的用例,大致分为两种设计方法:
第一种是,把是把每个功能分离成不同用例比如:
凭证编辑-手工录入、凭证编辑-凭证处理、凭证编辑-删除凭证
(还可以分的再细一些,如【条件】按钮就应单独列出)
第二种是,把是把每个功能分离成同一用例的不同步骤比如:凭证复核,其中step1为单笔复核,step2为批量复核。
我个人觉得第一种做法可取性高些,原因是方面以后组合时调用,对于这点我会在后面详细说下我的看法。
一句话总结,功能测试用例设计只需要考虑所覆盖的功能点的功能完整,将每个功能分离成独立用例。
约束性测试范畴
这个名词也是某天在TD中写功能测试需求时无意中发现这个字段的,后来仔细想了一下也到网上查了一些资料,才了解其作用的。也就是我写的测试需求中的备选流(其实类型应该写成约束性需求)。
在Rational Unified Process定义中约束性需求一共有4类:
一、设计约束性需求——软件设计的限制
我个人理解,与软件易用性相关,比如会计习惯的金额应靠右显示。
二、实现约束性需求——软件构造的限制
我个人理解,如程序中某变量的类型,数据库中某字段长度等;那么对应的测试方法也就是我们常用的“边界值法”“等价划分法”。
三、接口约束性需求——软件与其它功能模块系统交互过程中的限制
我个人理解,就在我上面举的例子“验证财务月份是否锁定后还能制单”,它就涉及了两个功能点,即一个锁定财务月份,另一个制单,以及我们测试需求中的入口准则。
四、物理约束性需求——软件使用时的限制
我个人理解,也就是我们经常所做的“兼容测试”,以及硬件中的系统配置最低要求等;
设计约束性与实现约束性需求相关的问题一般多暴露在α测试阶段。在α测试阶段,即版本未提交给省公司用户测试的内部测试阶段,此时程序刚刚上线各个模块很不稳定而且软件设计时的约束条件还没有经过验证,此时使用设计约束性需求测试会发现很多问题,但是这些问题绝大多数都控制在程序前端,程序员改过以后就不会再出现问题了,所以一般在内部早期就解决了。
而在β测试阶段,暴露的多是由系统测试产生的功能性问题或者独立的功能性问题。在β测试阶段,即版本提交给省公司后,由用户提交的问题,多数为功能性测试需求与系统测试需求范畴,下面是我从TD中随机提取了10个β测试阶段(现场问题)进行了简单分析:
#############################################################################
*编码 *摘要
758 内部往来期初,需支持15位数字(包括小数点),目前只支持13位
1020 【资金管理】银行账户信息查询 查询出的实际结果与[导出]结果不一致
1109 "4.0系统输入内部往来余额时,点击内部往来总是出现:当前脚本发生错误提示。
1179 往来期初余额录入时,保存时报错
1275 转换工具同步管理部分凭证重复导入或未导入
1353 凭证转换平台,对比科目汇总数据导出excel格式文件中,差值列数据没有显示;
1541 [账户综合查询]网省管理单位查询不到账户信息
1709 自动转账功能,待选择的凭证模板编码排序与使用者习惯不符合,请修改
1904 江苏职工(徐州)健康服务中心,08年度有期初数据,但在江苏省电力公司国网下汇总查询时,无数据;
2347 科目汇总表查询--科目明细账界面中,按月度查询时,本月、本季、本年合计数汇总有误
#############################################################################
结果
设计约束性需求:1709
实现约束性需求:758、
功能测试需求:1020、1109、1179、1275、1353
系统测试需求:1541、1904、2347
分析
β测试阶段中,设计约束性需求与实现约束性需求分别只有一个问题。多数问题还是出现在功能测试与系统测试中。
所以我认为,在以后的执行用例过程中,约束性需求,尤其是设计约束与实现约束,在测试初期α阶段可以给予高等级的执行力度,到了测试中后期,甚至维护阶段,这些用例可以把执行频度放到几个月1次。然而我们当前的用例就存在这个问题,扁平化,重要的不重要的掺杂在一起,每次发布之前还都要执行一遍(就算没执行,写在一起也会严重降低可读性),那么必然会导致执行用例命中率低、让执行者对用例产生抵触情绪。
(近期监理反馈回来的问题有几个类似界面规范的问题,两个原因:1.是我们在α测试阶段给予的约束性规则测试强度不够,缺乏针对性测试;2.是研发中心资源紧张,开发任务重,)
建议:
1. 将功能点的同类的约束条件分类设计成测试用例
2. 在测试前期或功能刚刚提交阶段执行
一句话总结,用例层次化,约束性用例与功能性用例分离,区分测试阶段有选择的进行用例执行。
系统性测试范畴
这里说的系统性测试比较狭义,与测试理论中的系统测试不完全相同,更像是流程测试,姑且先这么定义吧,在我理解它至少应该和“一、功能测试需求”区分开(我们的用例要么没有分开要么不存在)。
在我理解,从某种意义上来讲,系统测试用例是不存在的,但是不能没有,也不能仅仅是几组测试数据就能体现的,用例应该具备引导作用,效果应达到即使不熟悉流程的人也应该可以一步步按说明完成,所以我认为系统测试用例应该是功能用例的组合。
我先举个例子
我们现在假设:F为功能测试用例标识,S为系统测试用例标识
取个制单时最短的路径来说:
S1凭证制单到记账=F1凭证编辑-添加+F2凭证复核-单笔复核+F3主管签字-单笔签字+F4凭证记账-单笔记账
可以看出,系统测试用例S与各功能测试用例F的关系是可变的,S1凭证制单到记账这则系统测试用例就是F1到F4功能用例的组合调用,而这些用来组合的元素之间应该是彼此独立的,在TD当中可以实现这个功能。(具体操作见结尾附图)
之所以这样设计,很大程度上来源于近期自动化测试的探索,因为为了更高效的利用自动化工具进行测试,我将每个模块的每个功能封装成一个独立方法,并定义了调用它是需要传递的参数,这样在以后的测试用例设计中,我就不需要每次都再重新录制某个脚本,取而代之的是通过调用顺序的不同产生不同的测试用例。
这样的话,由不同的功能测试用例组合而成的系统测试用例的连贯性会非常强,可能对于精通业务的测试者来说,一些流程如何走心里都有数,就算没有用例,也能很快的走下来,但执行的是否与当初设想的一致?功能点覆盖是否全面?是否所有条件都考虑到了?我想如果能有这个执行流来进行引导的话,即使中途去做一些别的要紧的事情,回来接着执行,只需要看下一步该执行哪个功能用例即可;而对于测试新手或新入职的员工,这些已经按照业务流设定好执行顺序的用例又具备了培训功能,无疑是不可多得的知识库。
另外一点,对于条件路径覆盖程度,在以前学习的测试理论中我们知道当一个系统用例条件分支比较多的时候,就会出现很多种组合。在一些条件较多的功能点,在没有工具介入的情况下将所有可能都覆盖会耗费大量的资源,比较难以实现。那么这就需要实际情况考虑进来,在不同阶段进行有选择的覆盖。我画个流程图(可能某些地方画的不准确)解释一下我的观点:
简单因果图法分析:
其中c与k是唯一性约束,即c与k不能同时为真或为假
而k与路径(ih)是必要性约束,即当k为真,(ih)也一定为真
可用路径有很多,我在此只列出几个最典型的:
最短路径覆盖:a-b-k-e-f
基本路径覆盖:a-b-c-d-e-f
全路径覆盖I:a-b-g-b-c-h-c-d-i-d-e-j-e-f
全路径覆盖II:a-b-g-b-k-i-h-k-e-j-f
分析
虽然整个流程的入口与出口是相同的,但由于路径的不同,从而导致设计出的案例的作用也就有所不同,比如全路径覆盖法情况比较极端也比较耗费时间,因为这种覆盖方法把所有的分支都走了一遍,可以安排在程序,而基本路径覆盖为最常用最基本的流程,也是几乎每次发布前都要进行验证的流程,那么它的执行频度就可以设定为高,而最短路径的作用,目前我是这么理解的可以看作是当其它某个用例,需要新生成一张已记账的凭证,记账后我要用到其中的数据或功能时,那么最短路径法生成的用例无疑是效率最高针对性最强的,举个例子:我们现在要验证一下凭证记账后,使用凭证查询功能来验证是否记账成功这个系统测试流程,那我们就可以这样设计:
S凭证记账后-凭证查询=S凭证制单到记账(最短路径法)+F凭证查询
那么用例执行者在执行用例的时候虽然执行的都是已经存在的旧用例组合,但是由于组合的不同而从中产生了新的用例,这只是一个简单的例子,我相信如果能把各个功能点的功能性测试用例写好,步骤写详细,然后让一些精通业务流程的咨询人员、测试人员,对这些功能用例进行组合调用,而不是再写很大一长串文字去重新专门写一个业务流用例,这样的话不但结构清晰分明,而且日后若有某个功能点发生需求变更,只需要更改对应的功能测试用例即可。
一句话总结,功能用例模块化,组合调用用例进行测试,以不变应万变。
———————————————————————————————————————
其它存在问题建议
TD用例名称过于笼统。
举个例子,这个是4.0系统管理用例中的一个截图:
会发现单看这些用例名,可读性差,很难区分出是哪个功能点的添加、删除、修改。
建议改为如下形式或其它易区分格式:
FMIS4.0-SYS-FT-03-04-01国家设置添加
FMIS4.0-SYS-FT-03-04-01国家设置删除
FMIS4.0-SYS-FT-03-04-01国家设置修改
FMIS4.0-SYS-FT-03-05-01货币设置添加
FMIS4.0-SYS-FT-03-05-02货币设置删除
FMIS4.0-SYS-FT-03-05-03货币设置修改