Python 从 0 到 CI:我和 AI 合作搭起整套接口自动化框架

sand · 2026年11月11日 · 219 次阅读

背景:某心理测评 SaaS 平台,公司就我一个测试。业务端很多:运营管理端、学校端、教委端、家长 App、小程序、测评仪,加起来六七个终端。我从零开始,和一个 AI 编程助手合作,把接口自动化框架从目录搭到了 Jenkins 每日定时回归。这篇文章只讲这个过程:每一阶段人干什么、AI 干什么、我们怎么配合、踩了什么坑。所有账号、域名、表名均已脱敏。


阶段一:立骨架——架构人定,AI 填肉

我没让 AI「帮我搭一套框架」,因为试过,效果很差:它给的架构又大又全,风格和我的想法不搭,返工比重写还累。

所以我先自己动手:定下三层架构(工具层 / 接口封装层 / 用例层)、定下断言风格、定下 fixture 命名规范(工厂 xxx_factory / 回收器 xxx_recycler)、定下「造数必须带唯一时间戳」的铁律,然后手写一个模块的 demo。

拿着这个 demo,AI 才开始干活——不是让它自由发挥,是让它「照这个风格写」。效果天差地别。

心得一:AI 在约束内很可靠,在空白处很飘。你给的模板越具体,返工越少。

骨架定了之后,我还做了一件后来证明最关键的事:写了一份给 AI 看的协作规范文件,和代码一起入库。里面写着分层铁律、硬规则(违反即返工)、写新模块的标准工作流、环境已知坑。任何一次 AI 会话开写前都要先读它。

效果立竿见影:以前每换一个会话都要重新交代一遍框架约定,现在一份文件搞定。更妙的是约束是持久的——后来 AI 想顺手改个清理 SQL 条件,会先撞上文件里「为什么要这么写」的说明。

心得二:把「标准」写进文件里,比在聊天框里反复叮嘱可靠一百倍。

阶段二:啃下登录——两个坑,人和 AI 各踩一个

登录链路是框架的地基,我们栽了两个跟头。

坑一:滑块验证码。 平台登录有滑块,AI 帮我用 opencv 写识别,识别成功率很高,但提交一直失败。排查到最后是拖动距离的换算问题:滑块起点本身有个固定初始偏移,且距离和位移的映射不是 1:1。标定公式后一次通过:

# 关键:总位移 = 初始偏移 + 缺口位移,两个参数都要标定
distance = initial_offset + gap_offset * scale_factor

坑二:单会话顶号。 平台有个限制:同账号在新设备登录,旧会话 token 立刻失效(错误码 0905)。AI 最初把登录写成了 function 级 fixture——每个用例都重新登录一次,单跑没问题,全量跑就批量失败,而且毫无规律:同一批用例这轮挂那轮好。

排查很久才发现:用例 A 登录拿的新 token,把用例 B 正在用的同账号 token 顶掉了。解法是把所有 token fixture 改成 session 级,整个测试进程只登录一次,登录返回的业务信息缓存复用:

@pytest.fixture(scope='session')
def get_web_token():
    response = login.web_login(terminal='ADMIN')
    yield extract_token(response, scene='ADMIN 管理端登录')

心得三:token fixture 的作用域不是技术偏好,是业务约束决定的。而这类「业务约束」AI 不知道,只有人知道——这是整个合作里反复出现的主题。

阶段三:流水线化——swagger 是地图,探针是实地考察

登录通了之后,怎么让 AI 批量写模块?我们摸索出一套固定流水线,后来的每个模块都走这条线:

  1. 甩 swagger JSON 给 AI → 它解析出接口清单(一个模块 7~10 个接口)
  2. AI 写临时探针脚本实测(用完即删)→ 摸清 swagger 没写的东西:真正的必填项、真实错误码、无文档行为
  3. AI 落地四件套:接口封装 → 数据工厂 → fixture(工厂 + 回收器)→ 用例
  4. 我跑回归 + 验证环境零残留

探针这步是流水线的灵魂。因为踩过坑:swagger 没标「创建必须带机构 ID」,AI 直接写用例必挂;有的接口在 swagger 里根本不存在,AI 会自信地编一个出来。先探后写解决了一切。

探针还带来一个意外收获:后端行为怪异的地方(不校验必填、异常直接 500),我们不修不改,写成「当前行为基线」用例——后端哪天改了,用例自己会暴露。这成了我们的缺陷管理方式之一。

流水线跑顺之后,AI 批量产出了十几个模块:班级、学生、审核、测评任务、报告、设备、租户、教委端、运营看板……全量回归 1200+ 用例。

心得四:AI 最擅长的是「给定格式的批量生产」,最危险的是「没验证过的自信」。用探针把它的自信钉在事实上。

阶段四:生产环境的数据纪律——两层清理体系

框架直接跑生产环境(小公司没有测试环境),造数必须可回收。这是 AI 最容易出乱子的地方,我们建了两层体系:

第一层:用例 teardown 自清理。 每个用例造的数据登记到回收器,用例结束统一删除。铁律是清理放 teardown 而不是用例主体——因为断言失败会跳过主体后半段,脏数据就漏了。

第二层:定期 SQL 兜底硬删。 teardown 总有失败被吞掉的时候,所以数据工厂统一「测试前缀 + 毫秒时间戳」命名,定期跑清理 SQL 按前缀批量兜底。

但第二层的匹配条件被现实教育了三次:

  • 批量导入用例造的学生是真实姓名,名字里没有测试前缀——LIKE 永远够不着
  • 有的接口不校验必填,造出来的数据主字段是 NULL,只有次要字段带前缀——单列匹配必漏
  • 全库扫描命中 1000 多个字符串列,AI 一度按表名映射清理语句说「全覆盖」,漏看命中列和删除条件的列不一致,被我一眼抓出

最后的清理 SQL 全部改成多列 OR 匹配,删除顺序与数据依赖顺序相反(先删关联记录再删主记录)。AI 也立了规矩:改完 SQL 必须逐列对齐扫描结果,对不完不许说「全覆盖」。

心得五:AI 犯的错有个共同点——对着自己的总结写总结时最容易飘。人的把关不能省,但把关要落在具体规则上(逐列对齐),而不是「你再检查一遍」。

阶段五:报告与断言——异步和无回执怎么办

测评链路有个经典难题:提交接口只返回成功码,不返回任何记录 ID;报告在服务端异步生成,快则 1 分钟慢则 10 分钟;库里还有历史存量数据不能清。无回执、异步、有存量,三连。

我们定下的方案是「基线差集 + 时间窗口」:

baseline = take_report_baseline(query_fn)   # 记录服务端最新 createTime
submit()                                     # 提交测评
record = wait_new_report(query_fn, baseline) # 轮询定位新增记录
assert_report_success(record)

三个设计原则都是踩坑踩出来的:基线锚点必须用服务端时间(客户端时钟会偏差);匹配锚点用创建时间而不是完成时间(完成时间可能因上轮超时撞车);时间窗口命中多条时用业务键二次过滤。

报告体系也升级成了 Allure 三级结构:Epic(端)→ Feature(模块)→ Story(用例),十几份测试文件按端分层归档,运营/学校/教委/测评业务一目了然。

阶段六:进 CI——每日两次定时回归 + 失败自动推送

最后一步是把框架挂上 Jenkins:每日 9 点、18 点两次定时跑冒烟,代码推送触发全量。加了一个最实用的小功能:失败用例自动解析推送到钉钉——把失败的 Story 名、用例名、错误首行拆出来发群里,我不用登 Jenkins 就知道哪里挂了。

至此闭环完成:需求评审(AI 梳理 PRD)→ 用例(AI 写初稿、人评审)→ 手工测试(人)→ 接口自动化(AI 落地流水线)→ CI 定时回归(Jenkins)→ 数据回收(两层清理)。

协作心得总结:这套合作里,人和 AI 各守什么

回头看,最值得分享的不是代码,是分工边界的形成过程:

环节 AI 干 人干
架构设计 不干(它设计的要返工) 定架构、写 demo
协作规范 执行 制定、验收
业务事实(表名、删除规则、业务口径) 不准自己探测 一句话喂给它
接口落地 探针、封装、工厂、fixture、用例 跑回归、验收零残留
数据清理 写 SQL、全库扫描 逐列对齐把关、执行
跑用例 禁止(会顶掉人正在用的 token) 人自己跑
缺陷判断(「环境干扰值被写死」这类) 识别不了 人的业务直觉

一句话:AI 是执行力拉满的新人,你是指定标准、验收成果、扛最后责任的师傅。 把标准写进文件、把事实喂给它、把机械活交给它、把判断留给自己。这套分工跑了一年多,13 个模块、1200+ 用例、每日两次 CI,稳定运行至今。


暫無回覆。
需要 登录 後方可回應,如果你還沒有帳號按這裡 注册。