03 工具选择:什么工具框架值得用?
你好,我是柳胜。
工具选型评选会你应该不陌生,无论你是作为评审者,还是方案建议人。不过常常出现的场景就是,方案建议人讲了一通新工具A如何优秀强大,从问题分析到方案解决一应俱全。但参会专家并不是全都熟悉这个新工具,就会问出一堆类似“为什么你不用工具B”的问题。
结果也可想而知,懂A的不懂B,懂B的不懂C,懂C的不懂A,最后评审会咋决策?只好陷入一个依靠个人影响力来决策的模式。要破除这种死循环,就要找到一个量化模型。在我看来,量化数据才是团队有效交流的手段,也是团队达成共识的基础。
有了这样的模型,好处多多。评审阶段,可以更科学地预估某个工具的能力和风险;工具投入使用后,模型依旧能帮你持续观测,检验这个工具是否带来了预期价值。
今天我会带你一起推演出这个模型。学会推演方法,远比套用“模型”更重要。
自动化测试案例的成本
在开始量化评估之前,我们先回顾一下前面学过的ROI模型。
通过这个模型,我们得到一个重要结论:一个自动化测试案例的开发工作量,在给定条件下,什么经验的工程师用什么工具,需要多长时间完成,这是可以估算的定值。但维护工作量包含了多种可变因素,是自动化测试项目的风险所在。
今天我们聚焦公式里的分母,也就是开发成本d和维护成本m。
先说开发成本。在软件开发中,估算开发规模的传统方法有功能点和代码行,前沿的方法也有用AST抽象语法树。那如何估算开发一个自动化案例需要多大工作量呢?
首先我们要看一下自动化测试案例是如何产生的,目前在业界,主要有5种方式。
方法一:录制和回放方法
第一代的自动化测试工具大多基于录制回放,像最早的WinRunner就是录制桌面UI应用的。目前代表工具就是Selenium IDE。
要生成测试代码很简单,开启浏览器Selenium的插件,打开测试的网页,比如http://www.baidu.com,输入关键字“极客时间”,点击搜索,就会自动生成测试脚本了,如下图。
通过录制产生自动化脚本的这种方法,优点是速度快、零编码,对测试人员技术要求低。缺点是规模一旦扩大,维护工作量几乎无法承受,比如和CICD集成、自定制报告、多环境支持等等。
方法二:关键字驱动
不过,录制回放产生的脚本,还是面向过程的一个个函数,还需要测试人员有一定代码基础,才能扩展和维护这些函数。
那么,有没有办法,让没有代码经验的人也能编辑、维护脚本呢?关键字驱动方式应运而生了,它增加了页面控件对象的概念,调用对象的方法就是操作对象运行,在这种机制下,对象、对象的行为、输入的数据和描述信息,这些内容都能用一个表格的形式呈现。业务人员只需要编辑表格,就能修改运行逻辑了,这就叫做关键字驱动。
下面是一张关键字驱动表格,编程就是编辑表格里的关键字和对象。关键字是一组预定义好的指令,编辑完表格后,框架会驱动这个表格,执行设定好的命令,来完成自动化测试。
相比录制回放,关键字驱动框架的优势在于降低了测试开发人员的技术要求。而且测试开发人员对代码还有了更多的逻辑控制能力,比如增加循环结构、wait time、log输出,只要框架提供足够丰富的关键字就行。
但你也不难看出,编辑表格的人和维护关键字仓库的人,并不是同一拨人。前者是对业务了解的测试人员,后者是技术能力强的开发人员,这样开发维护起来会增加难度。
方法三:模块库开发
随着软件技术的发展,自动化测试人员的技术水平也在提高,要解决的问题也更加复杂。比如自动化测试的代码怎么能够有效地复用,有没有好的扩展能力等等。这个扩展能力是二维的,分为水平功能扩展和垂直层级扩展。
水平功能扩展指的是测试功能增多,自动化测试代码就借鉴了软件的模块设计思维,一个应用的测试场景可以切分成多个功能模块。比如订餐的流程可以分成登录模块、下单模块、快递模块,模块之间通过调用关系连接起来,组成测试场景。
而在技术层面上,又可以垂直切分出功能案例库和通用库。比如页面的组件可以形成复用库、page对象、button对象、link对象等等,把和开发技术耦合的技术层封装在复用库里,而和测试相关的业务功能实现在功能案例库里。
这样的设计,遵循了高内聚低耦合的软件设计思想,未来自动化测试规模扩展时也很方便。比方说增加一个支付功能,就可以把支付页面的对象写到复用库里,新创建一个支付测试案例,前面和下单模块衔接,后面和快递模块对接,就能跑起来了。
模块库开发的优点是可扩展、可复用,困难是需要架构工作和代码工作,对自动化测试开发人员的代码能力要求也比较高,接近开发工程师。
方法四:BDD混合框架
还有一种方法是BDD混合框架。BDD全称是Behavior Drive Development,行为驱动开发,它通过Gherkin语法定义测试场景。
Gherkin语法包含一套类自然语言的关键字:when、given、then,given描述条件,when描述行为,then描述结果。这样一个场景的3要素:上下文、动作和结果就说明白了。
所以,Gherkin语法描述出来的测试场景,能够同时被非技术和技术人员理解。客户、需求人员、开发人员和测试人员从BDD案例各取所需,需求人员得到用户手册,开发人员得到Use Case,测试人员得到测试案例。这些都有BDD框架支持生成代码,比如Cucumber。
BDD和关键字驱动框架的优缺点基本一样,不同的是,BDD不局限于测试框架,能够和软件流程集成在一起,也有相应的开发IDE插件,比如Eclipse plugin。
方法五:更高ROI的探索,自动化前沿技术
最后,我要说一下目前比较火,听起来也很酷的自动化前沿技术。
AI测试曾被寄予厚望,我们期待由它发展出一套自动化测试全栈解决方案,可以自动生成测试案例和代码,而且维护工作量为零。不能说这些全都是镜花水月,我相信目前AI只在一小部分测试领域里落地,比如图像识别的Applitools,可以用作图片验证;游戏领域里的监督学习,用来行为克隆等等。
我也曾看过一些AI根据规则自动生成测试案例的演示,但演示只是演示,它演示的方案需要的很多条件,现实还不具备,比如基于非常理想的数据模型等等。所以,我认为AI“落地”的定义是,它的形式是产品,而不是个人业余的项目或者一段开源代码。
相比AI测试,我更看好另外一种自动化生成测试的思路,就是基于规则化或可以模式化的业务场景,把案例的生成和代码生成一并自动化,形成一种可以量化的案例发现方案。我会在第5讲带你了解这个思路如何实现。
记住,测试工作是要能证明软件功能的成败,其方法论基石是确定论,而不是未知论。说得通俗一点,测试是在编网,虽然网会漏鱼,但我很确信只要投入人手和时间,就能把网编到什么程度,网住什么鱼。 而不是今天我捉到一条鱼,明天不知道鱼在哪里。这是我不认为AI能完全替代手工测试工作的原因。
好,业界已知的生成自动化测试方法,我们做了归类了解,接下来再分析不同类型的自动化测试开发成本和维护成本。
我给这个表格起一个名字,叫做案例DM分析表。D代表Development,M代表Mantainence。
工具的成本
前面探讨的给定了类型工具的情况下,案例的开发、维护成本如何衡量。但别忘了,成本计算时,还有个不小的成本:工具和框架的成本。这个在选型阶段没有考虑的话,会给后面埋下很多隐患,带来不少让人头疼的问题,比如下面这些。
1.当你的团队开始上手案例开发时,发现框架只支持JavaScript,Perl,但你的团队都是熟悉Python和Java。在这种情况下,是培训已有团队还是招聘新的人才,还是弃用方案而选择新的框架?
2.当你需要升级框架时,高版本对低版本的兼容性。它有可能让你的原有测试案例不能工作,最糟糕的是,会出现一些奇奇怪怪的问题,每一个问题的诊断过程是一场对你毅力和耐心的考验。
3.当你的案例在运行的时候,遇到一个框架抛出来的exception,网上搜不到解决方案,去社区论坛提问,也没人响应,自己去看源代码又陷入浩若烟海的context中去,那种无力感蔓延开来,直让你怀疑人生。
4.当你的案例规模扩展,新的API案例需要调用PATCH原语,但你已使用了一年的API框架不支持PATCH,更悲催的是,你发现这个API框架已经停止更新,凋零的社区、隐身的支持人员、破败的代码,都是对你的毒打。
进坑容易出坑难。我见证过一个自动化测试团队选型工具草率,导致在2年内更换了4个工具。每次换工具,都会重写一遍自动化测试案例,人收获了教训离开公司另谋高就,但公司浪费了2年的时间和资源,之后还要换一拨人乐此不疲地重复这样的故事。
可以说,选型合适的框架是自动化测试架构设计中一个重要的选择,它通过开发成本和维护成本两个因子影响自动化测试ROI,ROI低于1的时候,这个项目就要over了。
那什么是ROI好的框架呢?
首先,框架要满足我们的测试需求。比如,UI框架能有对象识别能力,API框架能有http原语封装,对xml和Json的支持,单元测试框架能有mock能力。
其次,框架应该有广泛的同行用户、持续的更新、成熟的社区和积极的客户响应,这些也能帮我们降低维护框架的成本,获得更好的ROI。
把这些因素量化,就能得到一个工具四维成熟度表,你可以把它作为原始模型,用到你的工作里。
小结
今天这一讲,我们从开发成本和维护成本的角度系统梳理了工具和框架的优劣势。根据脚本的生成方式的不同,可以划分出录制回放工具、关键字驱动工具、模块库开发工具、BDD混合工具和AI工具,针对自动化的不同类型和规模,脚本的开发和维护成本也会发生变化。
框架本身也会有维护成本,这里我们优先选择成熟主流的框架,会降低维护的成本。这里“成熟主流”,我们使用用户的数量、更新的频率、社区成熟度、开发语言与团队的适配度四个指标来对比度量。
我并没有给出一个精准计算工具框架ROI的公式,而是给出几个维度来帮你厘清工具和框架的选择思路。
记住,这里有两大原则:
1.按照团队的技术能力、项目的预期长短、将来扩展的规模大小,选择ROI最大的工具和框架;
2.当工具和框架带来的ROI无法升高时,就考虑按照原则1 重新评估,选择ROI更好的工具和框架。
所以,工具和框架的评估不是一劳永逸,而是在整个自动化测试生命周期内实时观测,如果有变要及时止损,让ROI持续提升。
思考题
在工作中,你的团队非常熟悉Python,所以选择某个支持Python框架。基于这样的原因做选择是不是遵循ROI原则?这样的选择会带来什么样的好处和坏处?
欢迎你在留言区跟我交流互动,也推荐你把这一讲分享给更多同事和朋友,说不定就能帮他通过下一次的工具选型评审会。
- swordman 👍(8) 💬(1)
几年前,我所在的研发团队,在移动端产品中,在Appium框架上实现了关键字驱动,只是我们没有用表格,用的是YAML脚本。正因为编辑脚本和维护关键字不是同一批人,沟通与维护工作量较大,导致后来测试用例没有形成规模,这个方案没有达到预期的效果。 老师提到的思考题,我觉得优点是团队可以用Python快速开发出测试用例,缺点是没有明确这个Python框架需要满足什么测试需求,比如selenium和appium都支持Python,可以满足UI层自动化测试需求;但如果项目中包含复杂的业务逻辑处理和算法处理,需要支持单元测试的Mock,可能这个Python框架,就不一定适合了。
2022-03-26 - chin 👍(5) 💬(2)
录制回放和关键字驱动目前仍然是使用最频繁的方法,模块化开发感觉是关键字驱动的更高的阶段,BDD不仅限于测试了。很期待第五讲了
2022-03-25 - 北冥 👍(2) 💬(2)
老师我有个疑问: “AI‘落地’的定义是,它的形式是产品,而不是个人业余的项目或者一段开源代码”。 意思是 AI 是专业定制化的解决某些问题,做不到可以提供普适性很强的共性解决方案的意思吗? 怎么理解 “它的形式是产品”呢
2022-06-25 - Evan 👍(0) 💬(1)
做测试三年,刚做测试开发一年。以个人发展的角度来说,更倾向于去学习不同语言的框架。 目前用过python+selenium和Python+request做UI及接口自动化(模块化),也在学习用JS框架的cypress做E2E的UI自动化。虽然只是刚刚开始接触JS,但是当自动化运行起来的瞬间,带来的成就感是无可比拟的,趁年轻应该多学习。
2022-07-06 - 随片 👍(0) 💬(1)
在一定程度上是遵循了ROI公式,但只在比较单一的方面。Python对于项目是否适用?该工具的更新是否活跃等都是需要考虑。对Python熟悉就选择Python框架,对于开发成本和维护成本都有减少,但也要根据总成本来确定。 我本身懂点Python,希望用Python进行api接口的自动化测试,完成接口自动化的同时,提高自己的Python熟练度,但是项目运行基本使用公司自研的工具(类jmeter),两者不兼容,对此也很烦躁。
2022-07-04 - 萧瑟 👍(0) 💬(1)
老师讲的太好了! 以前每次做自动化前,都不会考虑 ROI 什么的,团队熟悉什么语言,就用什么语言的框架,简单粗暴。
2022-05-05 - 清风明月 👍(0) 💬(1)
老师讲的很好,学到了很多! 现在就缺这种很实用,而且总结性很好的文章! 需要好好的看几遍,很期待接下来的课程!
2022-03-30 - 清风明月 👍(0) 💬(1)
老师讲的很好,学到了很多!
2022-03-30 - IT蜗壳-Tango 👍(0) 💬(1)
打卡
2022-03-25 - ifelse 👍(0) 💬(0)
学习打卡
2024-02-08 - Geek_palmlan 👍(0) 💬(0)
看到近期思寒分享的直播,大语言模型可以根据需求设计代码等文档自动输出业务模型的有向图,然后用工具根据有向图的定义自动生成抽象的测试用例套件(代码级别)的框架,然后测开人员填写替换为实际代码就可以运行,这个方向的发展老师觉得前景如何?
2023-09-06 - 鑫宝 👍(0) 💬(0)
根据 ROI 的公式 ROI = 单次运行成本* 运行次数 / 首次开发成本+维护成本 基于ROI 的原则进行选择, 使用python 那么首次开发成本和维护成本比较低。 大家都是python 的开发人员,遇到问题可以大家一起发散脑筋进行解决。 坏处是: 1. 如果后期切换了一个框架或者引入了新语言,大家都是不懂的。 2. 没有去调研其他语言在做这个项目的案例,或许其他语言在这方面做的更好。
2023-07-06 - 失 👍(0) 💬(0)
老师,有个问题和你讨论下,之前我做的自动化没这么细;假如有四个操作: 1、增加 2、查询 3、修改 4、删除 是写一个类,四个测试用例,还是写成一个流程测试用例?写成四个测试用例,那就是有依赖,如果增加失败了,后面的查询、删除就没有数据操作了,会失败;写成一个用例,就独立出来了,但是四个操作都要断言,链路就长了,如果独立起来,前置做了,就是麻烦,因为要恢复环境的,你一个用例测试添加,后置就要删除的步骤;假如测试用例是测试删除,前置就要做添加的操作,不就很多重复操作了么
2023-04-18