通用开源测试框架Skills:Web/App/接口统一调用方案
先描述一个测试团队常见的痛点:团队规模扩大,效率反而下降。技术栈变得复杂,新成员上手周期拉长,跨端协作成本居高不下。很多人直觉认为是“人手不足”,但根源往往在另一个维度——技能抽象层级过低。
一、测试团队越做越累,不是人不够,是技能太散
上个月,为一家中型电商平台做技术评审。他们的测试团队按端分化:Web、App、接口三组。Web组使用Playwright,App组使用Appium,接口组使用Requests加Pytest。三个团队,三套代码仓库,三种定位符写法,三种等待策略。新成员入职,需先掌握三套体系。一个跨端用例,比如从Web端下单、App端确认收货,需要三组各自编写脚本,再借助消息队列串联。
他们问我:是否该裁撤一组人员,或者统一采购某个商业平台?我的判断很直接:问题不在人,在于你们没有对技能进行统一抽象。
每一端都在重复同类型操作:点击、输入、获取文本、等待条件、发送请求、断言响应。但每个框架都用各自语法表达这些“技能”。Web的“点击”是page.click(locator),App的“点击”是element.click(),接口的“请求”是requests.post(url, data)。本质上,它们都是“执行一个动作并验证结果”。可在代码中,每一层都在重复实现调度、重试、日志、断言。这不是技术债,这是架构债。
用了三周时间,从过去几年在多个项目中沉淀的经验里,提炼出一个通用测试Skills框架。核心目标很明确:一套技能描述,能同时驱动Web、App、接口;统一调用方式,统一技能注册,统一结果断言。代码已开源,下面详解其工作原理。
二、本质不是缺框架,是缺“统一调用层”
很多人一听到“统一框架”,第一反应就是再构建一个超级框架,把所有底层都包裹进去。那是错误的思路。正确的思路是:不要在底层统一,要在“技能调用层”统一。
什么是技能?技能是一个可命名的、有输入输出、有执行逻辑的最小测试单元。例如click(selector)是一个技能,input_text(selector, text)是一个技能,http_get(url)是一个技能,wait_for_element(selector, timeout)是一个技能,assert_text_contains(text)也是一个技能。
Web端需要这些技能,App端同样需要,接口端需要的只是其中一部分。关键在于:技能的调用方不关心技能背后是Playwright、Appium还是Requests,它只关心技能的名字和参数。这就好比你在编写业务代码时调用一个函数,你不管这个函数是用Go还是Python实现的。因此,需要的不是统一的执行引擎,而是统一的技能注册表加动态调度器。这个框架做的就是这件事。
三、核心机制拆解:Skill抽象 + 注册中心 + 动态调度
先看架构图。

拆解三个核心机制。
机制一:Skill定义规范——让每个技能自描述
一个Skill的最小定义,简单来说就是注册一个函数,比如@register_skill("click")。但仅此还不够,每个底层驱动的API不同。所以真正的Skill实现是一个适配器:技能内部能识别当前driver的类型,自行适配,调用方完全无需关心。
机制二:注册中心——技能的市场
所有技能在启动时注册到中心,注册表维护一个字典:skill_name -> SkillClass。调度器收到调用请求后,去注册表查找技能,实例化,调用execute。好处很明显:新增技能无需修改调度器代码,团队可以共享技能库,比如通用的login_with_retry、wait_for_toast。
机制三:动态调度——一套DSL跑通所有端
调度器支持两种输入:YAML/JSON序列(适合关键字驱动)和Python链式调用(适合代码风格)。一个YAML用例可以描述完整流程,例如导航、点击、等待、发请求、断言。这个用例可以在Web环境运行,也能在纯接口环境运行。调度器会根据当前注册的技能集合,自动跳过不可用的技能(比如click在接口环境会自动跳过并告警)。
核心设计哲学很清晰:技能是原子能力,用例是技能的有序组合。底层驱动可更换,技能可增删,但用例结构保持不变。
四、典型案例对比:同一个场景,三种终端,一套写法
拿“登录并校验”这个场景来说。传统方式下,Web端、App端、接口端需要三套完全不同的代码,API各异,维护成本极高。而在Skills框架下,只需一套用例:定义一个YAML序列,描述导航、输入、点击、等待、断言这些技能。把这个YAML提交给调度器,设置driver_type=web就跑Web,设置driver_type=app就跑App,设置driver_type=api则框架会自动将不适合接口环境的技能转换为HTTP请求(如果实现了对应映射)。
当然,接口环境不需要填写表单,通常我们会为接口场景单独编写一个更简洁的技能序列。但关键在于:测试人员无需记住三套API,只需记住技能名字和参数。这才是降本增效的真正路径。
五、工程落地启示:你的测试资产不该绑定在某种工具上
这个框架我在三个团队落地后,总结出三条最直接的实践经验。
启示一:把现有测试脚本拆成“技能库”和“用例层”
不要一次性重写所有用例。先从最常用的10个操作开始,注册成技能,然后让用例通过技能调用来重构。三个月后,你的用例文件会减少70%的重复代码。
启示二:技能可以跨项目共享
框架内置了一个远程技能仓库。团队A编写的captcha_solver技能,团队B可以直接拉取使用,无需复制代码,无需了解内部实现。这对中大型团队的价值极大:你不再需要每个项目都配备一个“自动化专家”。
启示三:新人培训周期从两周压缩到两天
新人只需学会技能列表和YAML写法,不需要先学Playwright API,再学Appium,再学Requests。他们可以在第一天就写出可运行的用例,第二天理解技能背后的原理。
对在校生来说,现在不需要纠结“学Web自动化还是App自动化”,应该学的是“如何抽象测试技能”,这个能力在任何端都通用。对初级工程师来说,试着把平时编写的Playwright脚本重构为技能加用例的形式,你会发现自己开始从“写代码的人”变成“设计框架的人”。对中级工程师来说,这个框架展示了如何用“注册中心+适配器”模式解耦测试工具,可以把它推广到团队,或者自己实现一个更轻量的版本。
六、问你的团队一个问题
去你们团队的自动化代码仓库里,随便找一个跨端的场景——比如用户从注册到下单。统计一下:为了支持Web、App、接口三种环境,你们的代码里重复实现了多少遍“等待元素出现”“输入文本”“点击按钮”?然后问自己:如果明天要换掉其中一个底层框架,比如从Playwright换成Cypress,你要修改多少处代码?
如果答案是“超过10处”,那么这个框架就值得你花一天时间研究。