爆肝3周,开源一套通用测试Skills框架:支持Web/App/接口统一技能调用

简介: 本文介绍一款通用测试Skills框架,通过“Skill抽象+注册中心+动态调度”三层设计,实现Web/App/接口三端技能统一调用。告别重复编码与工具绑定,一套YAML用例驱动多端执行,大幅提升资产复用率与团队协作效率。

目录

一、测试团队越做越累,不是人不够,是技能太散
二、本质不是缺框架,是缺“统一调用层”
三、核心机制拆解:Skill抽象 + 注册中心 + 动态调度
四、典型案例对比:同一个场景,三种终端,一套写法
五、工程落地启示:你的测试资产不该绑定在某种工具上
六、问你的团队一个问题

一、测试团队越做越累,不是人不够,是技能太散
上个月,我帮一个中型电商团队做技术评审。
他们有三个测试小组: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抽象 + 注册中心 + 动态调度
先看架构图。

c954e8e6-cd98-4052-b2c3-eba54f3e849b.png

拆解三个核心机制。

机制一:Skill定义规范 - 让每个技能自描述

一个Skill的最小定义:

@register_skill("click")
def skill_click(selector: str, timeout: int = 5, **context):
"""点击指定元素,支持Web/App统一selector"""
driver = context["driver"] # 由调度器注入

# driver可能是Playwright的Page,也可能是Appium的WebElement
driver.click(selector, timeout=timeout)

但这样还不够。每个底层驱动的API不同。
所以真正的Skill实现是一个适配器:

class ClickSkill(BaseSkill):
name = "click"
parameters = {"selector": str, "timeout": int}

def execute(self, params, context):
    driver = context["driver"]
    if driver.__class__.__name__.startswith("Playwright"):
        driver.locator(params["selector"]).click(timeout=params["timeout"])
    elif driver.__class__.__name__.startswith("Appium"):
        driver.find_element(AppiumBy.XPATH, params["selector"]).click()
    # 接口层不支持click,调用会报错

关键点: 技能内部知道当前driver是什么类型,自己做适配。
调用方完全不用管。

机制二:注册中心 - 技能的市场

所有技能启动时注册到中心。
注册表维护一个字典:skill_name -> SkillClass。

调度器收到调用请求后,去注册表找技能,实例化,调用execute。

好处:
新增技能不需要修改调度器代码。
团队可以共享技能库,比如login_with_retry、wait_for_toast。

机制三:动态调度 - 一套DSL跑通所有端

调度器接受两种输入:

YAML/JSON序列:适合关键字驱动
Python链式调用:适合代码风格
一个YAML用例示例:

name: 跨端下单流程
skills:
-name:navigate
params:{url:"https://xxx.com"}
-name:click
params:{selector:"#add-to-cart"}
-name:wait_for_element
params:{selector:".cart-badge",timeout:5}
-name:http_post
params:{url:"/api/checkout",data:{"item_id":123}}
-name:assert_status_code
params:{expected:200}
这个用例可以在Web环境跑(navigate, click),也可以在纯接口环境跑(http_post, assert_status_code)。
调度器会根据当前注册的技能集合,跳过不可用的技能(如click在接口环境自动跳过并报警)。

核心设计哲学:
技能是原子能力,用例是技能的有序组合。
底层驱动可以换,技能可以增删,但用例结构不变。

四、典型案例对比:同一个场景,三种终端,一套写法
拿“登录并校验”这个场景举例。

传统方式:三套代码

Web端:

page.goto("/login")
page.fill("#username", "test")
page.fill("#password", "pass")
page.click("button")
page.wait_for_selector(".welcome")
assert page.text_content(".welcome") == "欢迎"
App端(类似,但API不同):

driver.find_element(By.ID, "username").send_keys("test")
driver.find_element(By.ID, "password").send_keys("pass")
driver.find_element(By.ID, "login_btn").click()
wait = WebDriverWait(driver, 5)
wait.until(EC.visibility_of_element_located((By.CLASS_NAME, "welcome")))
assert driver.find_element(By.CLASS_NAME, "welcome").text == "欢迎"
接口端:

resp = requests.post("/login", json={"user": "test", "pwd": "pass"})
assert resp.status_code == 200
assert "欢迎" in resp.text
Skills框架方式:一套用例

skills:
-name:navigate
params:{url:"/login"}
-name:input_text
params:{selector:"#username",text:"test"}
-name:input_text
params:{selector:"#password",text:"pass"}
-name:click
params:{selector:"button"}
-name:wait_for_element
params:{selector:".welcome",timeout:5}
-name:assert_text
params:{selector:".welcome",expected:"欢迎"}
把这个YAML丢给调度器,设置driver_type=web,跑Web。
设置driver_type=app,跑App(只要selector能被Appium解析)。
设置driver_type=api,框架会自动将input_text和click转换为HTTP请求(如果实现了对应映射)。

实际上,接口环境不需要填表单,所以我们会为接口场景单独写一个更简洁的技能序列。但关键在于:
测试人员不需要记住三套API,只需要记住技能名字和参数。

可以被截图传播的观点句:

测试框架的复杂度,应该由框架本身承担,而不是让每个用例编写者重复学习。

技能统一,才是真正的资产复用。否则你只是在不同的端里重复造轮子。

五、工程落地启示:你的测试资产不该绑定在某种工具上
这个框架开源后,我已经在三个团队落地。
总结三条最直接的经验。

启示一:把现有测试脚本拆成“技能库”和“用例层”

不要一次性重写所有用例。
先从最常用的10个操作开始,注册成技能。
然后让用例通过技能调用来重构。
三个月后,你的用例文件会减少70%的重复代码。

启示二:技能可以跨项目共享

我们在框架里内置了一个远程技能仓库。
团队A写的captcha_solver技能,团队B可以直接拉下来用。
不需要复制代码,不需要知道内部实现。

这对中大型团队的价值极大:
你不再需要每个项目都配一个“自动化专家”。

启示三:新人培训周期从两周压缩到两天

新人只需要学会技能列表和YAML写法。
不需要先学Playwright API,再学Appium,再学Requests。
他们可以在第一天就写出能跑的用例,第二天理解技能背后的原理。

对在校生来说:
你现在不需要纠结“学Web自动化还是App自动化”。
你应该学的是“如何抽象测试技能”。这个能力在任何端都通用。

对初级工程师来说:
试着把你平时写的Playwright脚本,重构为技能+用例的形式。
你会发现自己开始从“写代码的人”变成“设计框架的人”。

对中级工程师来说:
这个框架展示了如何用“注册中心+适配器”模式解耦测试工具。
你可以把它推广到你的团队,或者自己实现一个更轻量的版本。

六、问你的团队一个问题
去你团队的自动化代码仓库里,随便找一个跨端的场景(比如用户从注册到下单)。

统计一下:
为了支持Web、App、接口三种环境,你的代码里重复实现了多少遍“等待元素出现”“输入文本”“点击按钮”?

然后问自己:
如果明天要换掉其中一个底层框架(比如从Playwright换成Cypress),你要改多少处代码?

如果答案是“超过10处”,
那么这个框架就值得你花一天时间研究。

相关文章
|
17天前
|
人工智能 自然语言处理 文字识别
阿里云百炼Qwen3.7-Max简介:能力、优势、支持订阅计划参考
Qwen3.7-Max是阿里云百炼面向智能体时代推出的新一代旗舰模型,对标GPT-5.5、Claude Opus 4.7等闭源旗舰。该模型支持百万级token上下文窗口,具备顶级推理能力、多模态搜索与视觉理解增强、流式输出低延迟响应等核心优势,覆盖编程、办公、长周期自主执行等复杂场景。同时支持OpenAI接口兼容,便于系统快速迁移。用户可通过Token Plan团队或节省计划等订阅方式灵活调用,适合企业级高要求场景使用。
6320 30
阿里云百炼Qwen3.7-Max简介:能力、优势、支持订阅计划参考
|
2天前
|
数据采集 人工智能 前端开发
让 Coding Agent 从黑盒到透明:阿里云 Agent 观测审计数据采集实践
AI Agent 规模化落地带来执行黑盒、行为难追溯、成本难度量三大难题。阿里云基于 OTel 标准,面向 Coding Agent、个人通用助理和框架型 Agent,推出 LoongSuite Pilot、插件及探针等无侵入采集方案,让 Agent 实现可看见、可分析、可审计、可治理。
583 135
|
12天前
|
存储 定位技术 数据库
CodeGraph 如何让 Claude Code减少 7 成工具调用?
CodeGraph 为 Coding Agent 提供本地代码知识图谱,把函数、类、调用链和框架路由提前整理成“项目地图”,减少盲目搜索和文件读取。它不是新 Agent,而是上下文基础设施,让 Agent 更快找到正确代码路径,平均减少 7 成工具调用。
1244 3
|
9天前
|
人工智能 安全 定位技术
CodeGraph深度解析 让Claude Code工具调用直降七成的核心原理与实操教程
如今以Claude Code为代表的AI编程智能体已经成为开发者日常编码、项目重构、漏洞修复的必备工具。但在长期使用过程中,几乎所有开发者都会遇到同一个明显痛点:AI虽然具备强大的代码生成与分析能力,却常常陷入盲目探索的循环中。
1092 1
|
19天前
|
人工智能 自然语言处理 供应链
|
9天前
|
人工智能 弹性计算 安全
阿里云618活动时间、活动入口、优惠活动详细解读
2026年阿里云618创新加速季已全面开启,作为年度力度最大的云产品促销活动,本次大促覆盖轻量应用服务器、ECS云服务器、GPU云服务器、数据库、AI算力、安全服务、CDN等全品类产品,推出5亿元算力补贴、新用户限时秒杀、普惠满减、企业专享、免费试用、云大使返佣等多重福利,个人开发者、中小企业、AI团队均可享受专属低价。本文将系统梳理2026年阿里云618活动的完整时间节点、官方参与入口、各类优惠细则、使用规则、热门产品推荐及实操代码,帮助用户精准参与、高效省钱,以最低成本完成上云部署。
875 5
|
8天前
|
人工智能 自然语言处理 安全
Vibe Coding 实战:别盲目跟风,先分清 vibe coding 适合什么场景
本文系统总结vibe coding实战经验:明确其适用场景(原型、小工具、标准化模块),剖析5步落地流程(场景判定→结构化提示词→目录初始化→分模块生成→自动化校验),指出四大常见误区,并推荐适配工具Trae。强调“场景匹配+规则前置”是提效关键,避免盲目套用。
729 1