1. 为什么大家都在搭接口自动化测试框架,以及你需要它解决什么问题
先说一个扎心的现实:接口自动化测试,真正难的从来不是“发一个请求”,而是“怎么组织一堆请求”。很多团队都经历过这个阶段——用工具录了几十个接口用例,开始跑起来很爽,可一旦接口字段变动、需要批量传参、要接入CI,脚本就变成了无人敢碰的定时炸弹。你让我讲“5分钟教会你搭建接口自动化测试框架”,这个标题有点标题党,但如果用成熟的技术栈和一份能直接抄作业的骨架,让一个有点Python基础的人,在几分钟内跑通第一个完整用例并看到报告,这是完全做得到的。
先说这个概念到底在解决什么问题。接口自动化测试,本质上是把“人工用工具点接口、看返回”这件事,变成“脚本自动发请求、自动校验结果、自动输出报告”。它的价值有三层:第一层是回归保障,改一次代码,几百个接口用例几分钟跑完,不用人肉熬夜点;第二层是接口契约校验,前后端联调前就能发现字段不一致、类型不对、必填项缺失这类低级问题;第三层是数据准备和清理,很多业务场景依赖接口造数,自动化脚本比手工在界面上点快得多。
适合谁来看这篇文章?如果你是刚接触接口测试的测试人员,或者后端开发想给自己写的接口加一层自检保护,再或者测试Leader想搭一套进CI的基础框架,这篇内容都很合适。我会把技术选型的理由、目录结构设计的逻辑、关键代码的实现、以及我自己踩过的坑,全部过一遍。不画大饼,直接给能用的东西。
下面这套方案,我给它起了个内部代号叫“最小可用框架”:Python + requests + pytest + allure。这套组合不是唯一答案,但它是目前试错成本最低、社区资料最多、上手最快的组合。后面我会解释为什么这么选,以及什么情况下你可以把部分组件换掉。
2. 框架技术选型:为什么是Python + requests + pytest + allure
2.1 不要被“框架”两个字吓住,它本质上就是四个组件的分工
很多初学者一听到“框架”就以为是什么高深的东西,其实你每天用的东西就是框架。我把这套接口自动化测试框架拆开,它就是几个人各司其职:
- requests:负责发HTTP请求、收响应。它是整个框架的“手”。
- pytest:负责组织和执行测试用例,支持断言、前置后置、参数化、跳过、异常收集。它是“大脑和骨架”。
- allure:负责把执行结果渲染成漂亮的HTML报告。它是“脸面”。
- Python自身:负责把上面几个串起来,以及写各种工具函数。它是“身体”。
换个更直白的类比。你去饭店点餐,requests是传菜员,把菜单送到后厨又把菜端回来;pytest是餐厅的排班经理,决定什么时候上哪道菜、上几桌,菜不合标准怎么处理;allure是摆盘师,把菜装得像样;Python是整家饭店的场地和水电。它们各干各的活,但配合起来就是完整的餐厅。
2.2 为什么不用其他组合,这是对比过后的选择
有人会问,Java + HttpClient + TestNG + Allure不也能做吗?Java生态里还有RestAssured。为什么我这里不推荐入门就上Java?一个很现实的原因:成本。Java需要配置环境、管理依赖、写更啰嗦的代码结构,明明一句话能发请求,Java写上几行还得处理各种checked exception。不是Java不好,而是对于“尽快跑通方案、让业务先运转起来”的阶段,Python的简洁度是压倒性优势。
那requests和最近很火的httpx怎么选?httpx支持异步、HTTP/2,看起来更现代。但我仍然建议入门用requests,原因有三个:第一,requests的API足够稳定,团队里随便谁接手都能维护;第二,网上几乎所有接口调试脚本的示例都是requests,遇到问题更容易搜到答案;第三,它对urllib3的封装已经把连接池、重试、证书验证这些麻烦事处理好了,你不需要关心底层细节。
pytest和unittest怎么选?unittest是Python标准库自带,不用额外安装,听起来挺省事。但用上之后你会发现,它的断言写法啰嗦、参数化能力弱、插件生态基本等于没有。pytest的fixture机制、parametrize参数化、conftest共享配置、各种插件,几乎就是为测试框架量身定做的。另外,pytest兼容unittest写的用例,你团队里如果有旧代码,迁移成本也没有想象中高。
至于测试报告,pytest本身只输出命令行文本结果,想要让领导看得舒服,必须接一个报告工具。Allure确实有点重量级,它需要本地装一个命令行工具,但它生成的报告确实是最专业的。如果你实在不想接Allure,退而求其次可以用pytest-html,生成一个单文件HTML报告,不依赖额外环境,适合个人项目或小团队。我的建议是:给团队用的框架直接上Allure,一步到位。
3. 五分钟快速搭建:完整的目录结构与核心配置
3.1 装好这些依赖,你的环境就准备好了
先不要急着一上来就写代码,我习惯先把依赖装干净。用虚拟环境是必须的,别把依赖装到全局Python里,否则过几个月你就会陷入版本冲突的深渊。下面这几行命令,就是整个框架唯一一次敲的命令。
# 创建并激活虚拟环境(Windows系统去掉source前缀) python -m venv venv source venv/bin/activate # Windows: venv\Scripts\activate # 安装核心依赖 pip install requests pytest allure-pytest pyyaml # 验证安装 pytest --version我解释一下为什么装 pyyaml。配置文件有很多种选型:ini、json、yaml、toml。我选yaml是看中它的可读性——支持注释、缩进结构清晰、写层级数据不用像json那样打一堆花括号引号。测试配置通常包含环境地址、账号信息、超时时间这些,用yaml存,团队成员打开就能看懂。
装完了验证一下pytest能跑,再进行下一步。注意allure-pytest只是pytest的插件,真正生成报告的allure命令行工具需要另外装。在Mac上可以用brew install allure,Windows上需要下载allure压缩包解压后配置环境变量。这块是新手最容易卡住的地方,如果pytest能跑但一直生成不了报告,九成是allure命令没装好或没进PATH。
3.2 目录结构:一个能让团队少吵架的布局方案
我见过很多项目的测试代码,最大的问题是“所有文件都堆在根目录”。跑起来没问题,可一旦脚本多了,改一个公共函数要满屏找,新人接手更是无从下手。我推荐的最小结构是这样:
api_test_framework/ ├── config/ │ ├── config.yaml # 环境配置、账号配置 │ └── config_reader.py # 读取配置的工具模块 ├── core/ │ ├── request_client.py # 封装的请求客户端 │ └── assert_utils.py # 断言工具 ├── testcases/ │ ├── test_login.py # 登录相关用例 │ ├── test_user.py # 用户模块用例 │ └── conftest.py # pytest夹具定义 ├── utils/ │ ├── data_loader.py # 读取测试数据的工具 │ └── log_utils.py # 日志工具 ├── data/ │ ├── login_cases.yaml # 登录接口测试数据 │ └── user_cases.yaml # 用户接口测试数据 ├── reports/ # 测试报告输出目录 ├── requirements.txt └── pytest.ini每个目录的角色很清晰:config放全局配置,core放所有用例共用的底层能力,testcases放具体用例,utils放杂七杂八的小工具,data放测试数据。这样做的最大好处是——当用例数量从几十涨到几百上千时,你不会因为找不到文件而抓狂。
3.3 pytest.ini:一份配置搞定发现规则和标记
pytest的配置有很多种放法,可以放在pyproject.toml,也可以放pytest.ini。我习惯用pytest.ini,因为简单直接,不需要了解toml的复杂语法。
[pytest] testpaths = testcases python_files = test_*.py python_classes = Test* python_functions = test_* addopts = -v -s --alluredir=./reports/allure-results --clean-alluredir markers = smoke: 冒烟测试用例 regression: 回归测试用例关键点在addopts,这是pytest启动时默认附加的参数。-v表示显示详细执行过程,-s表示显示print内容,--alluredir指定Allure原始结果存放路径,--clean-alluredir每次执行前清理上次结果,防止报告数据叠加。
3.4 核心:请求客户端封装,50行代码让所有用例受益
如果框架里只能挑一个“必须自己写”的模块,那就是请求客户端的封装。requests库本身已经很简洁了,但如果你在每个用例里直接调requests.get或者requests.post,一旦需要改动统一逻辑——比如加日志、加鉴权、加超时重试——你就得改所有用例。
我把请求封装成一个类,核心逻辑是:统一读取配置、自动添加请求头和鉴权信息、记录请求与响应日志、统一处理超时和异常。直接看代码:
# core/request_client.py import requests import logging from config.config_reader import get_config logger = logging.getLogger("api_test") class RequestClient: def __init__(self): config = get_config() self.base_url = config["env"]["base_url"] self.timeout = config["env"]["timeout"] self.session = requests.Session() # 公共请求头 self.session.headers.update({ "Content-Type": "application/json;charset=UTF-8", "User-Agent": "api-test-framework/1.0" }) def request(self, method, path, **kwargs): url = self.base_url + path if "timeout" not in kwargs: kwargs["timeout"] = self.timeout logger.info(f"请求: {method.upper()} {url}") logger.info(f"参数: {kwargs}") response = self.session.request(method, url, **kwargs) logger.info(f"响应状态码: {response.status_code}") logger.info(f"响应内容: {response.text[:500]}") return response def get(self, path, **kwargs): return self.request("get", path, **kwargs) def post(self, path, **kwargs): return self.request("post", path, **kwargs) def put(self, path, **kwargs): return self.request("put", path, **kwargs) def delete(self, path, **kwargs): return self.request("delete", path, **kwargs)注意两个细节。第一,用requests.Session()而不是直接requests.get,是为了让多个请求复用同一个TCP连接,性能更好,还能自动管理cookies。第二,日志会截断响应体到500个字符,防止某些疯狂返回大对象的接口把日志文件撑爆。
4. 深入接口测试的核心细节:用例编写、断言、数据驱动与Token处理
4.1 一个规范的接口用例,必须包含哪些东西
新手容易犯的错就是把“能通”当“测过”。一个规范的接口测试用例,至少要覆盖以下这些方面:
- 接口路径和请求方法是否与接口文档一致。
- 请求参数:必填参数、选填参数、参数类型、参数边界值。
- 请求头:Content-Type、鉴权字段、自定义头。
- 预期结果:状态码、响应体关键字段、业务码。
- 异常场景:参数缺失、参数类型错误、未鉴权、不存在资源。
举个例子,登录接口的正向用例不只是验证返回200,还要验证响应体里的token字段非空、用户状态码为0。反向用例要覆盖密码错误返回特定错误码、账号不存在返回特定提示。这些才是自动化用例存在的意义。
4.2 pytest断言的最佳实践:断言单个字段,而不是解析完整个响应瞎比较
pytest里断言用assert,但怎么断言很有讲究。我见过有人把整个响应体JSON转成字符串,然后断言某个字符串在不在里面,比如assert "success" in response.text。这种断言太脆弱了,接口返回里某个列表字段多一个空格、顺序变化,都会导致误报。
更好的做法是精确断言字段。先把响应体解析成dict,然后逐个断言关键字段:
def test_login_success(request_client): resp = request_client.post("/api/v1/login", json={ "username": "test_user", "password": "123456" }) assert resp.status_code == 200 data = resp.json() assert data["code"] == 0 assert "token" in data["data"] assert len(data["data"]["token"]) > 20这里其实有个底层原因值得说。HTTP状态码只代表传输层和URL层的状态,200不代表业务成功,很多接口业务失败也返回200,只有响应体里的业务码能代表真实结果。所以断言必须两层都做:状态码断言保证“请求通路正常”,业务码断言保证“业务逻辑正常”。
4.3 数据驱动:把测试数据从代码里剥离开
现在用例是写死了用户名密码,那如果要测10组不同账号登录,是不是要复制10遍test函数?当然不是。pytest的parametrize就是干这个的。
更规范的做法是把测试数据放在yaml文件里,然后用parametrize读进来。这样测试人员和开发人员改数据不用碰代码,也不会因为改数据改坏逻辑。
# data/login_cases.yaml test_login_success: - username: "test_user" password: "123456" expect_code: 0 - username: "admin" password: "admin@123" expect_code: 0 test_login_fail: - username: "test_user" password: "wrong" expect_code: 1001 expect_msg: "用户名或密码错误" - username: "not_exist" password: "123456" expect_code: 1002 expect_msg: "用户不存在"读取yaml的工具代码也很短:
# utils/data_loader.py import yaml import os def load_yaml(file_path): with open(file_path, encoding="utf-8") as f: return yaml.safe_load(f)然后在测试文件里这样用:
@pytest.mark.parametrize("case", load_yaml("data/login_cases.yaml")["test_login_success"]) def test_login_success(request_client, case): resp = request_client.post("/api/v1/login", json={ "username": case["username"], "password": case["password"] }) assert resp.status_code == 200 assert resp.json()["code"] == case["expect_code"]这套数据驱动的价值,我在实际项目里体会特别深。之前有一个支付接口,联调环境有几十组商户号,每个商户号的各种限额组合都不一样。如果每组数据写一个用例函数,测试文件会膨胀到几千行。改成yaml数据驱动后,测试文件只有几十行,真正干活的数据文件撑到几百行,但那个文件谁都能维护,不用写代码。
4.4 Token处理:从登录接口拿到鉴权信息,并让所有用例自动带上去
接口自动化绕不开登录鉴权。方案有很多:有的项目用session cookie,有的用JWT token,有的用签名。这里我讲最常见的token模式。
核心思路是:写一个fixture,它先调登录接口拿到token,然后注入到RequestClient里,后续所有用例自动带上这个token。这在pytest里实现起来非常优雅。
# testcases/conftest.py import pytest from core.request_client import RequestClient from config.config_reader import get_config @pytest.fixture(scope="session") def request_client(): client = RequestClient() config = get_config() # 执行登录,获取token resp = client.post("/api/v1/login", json={ "username": config["env"]["username"], "password": config["env"]["password"] }) data = resp.json() assert data["code"] == 0 token = data["data"]["token"] client.session.headers.update({"Authorization": f"Bearer {token}"}) return client这里有个非常重要的细节:fixture的scope="session"。意思是整个测试会话只执行一次登录,所有测试用例共用一个client和同一个token。如果写成默认的scope="function",每个用例都会登录一次,几百个用例就要登录几百次,不仅慢,还可能把服务端登录接口打成限流状态。当然,如果你的测试环境token有效期只有几分钟,session级别的fixture可能中途token过期,那就要改成更复杂的自动刷新机制,或者每次动态获取。这个问题我后面在常见问题里详细说。
5. 完整实操过程:从零跑通登录到依赖接口的多接口串联
5.1 搭建过程中的关键命令:初始化、执行、生成报告
我按照实际操作顺序,把整个流程走一遍。假设你已经在项目根目录建好了上面的目录结构,并且写好了config/config.yaml。
第一步,准备配置文件config.yaml:
env: base_url: "http://127.0.0.1:8080" timeout: 10 username: "test_user" password: "123456"第二步,运行一条最简单的测试用例。先只写一个用例,验证环境通不通。
pytest testcases/test_login.py -v如果你看到输出里有一个绿色的小点,说明第一个用例已经跑通了。这时候框架的“骨架”已经立起来了。
第三步,生成Allure报告。
pytest allure serve reports/allure-resultsallure serve会自动起一个本地web服务,然后在浏览器打开报告页面。你可以看到每个用例的通过失败状态、请求耗时、失败时的响应内容、步骤日志。
5.2 多接口串联实战:下单流程中的依赖处理
实际业务里很少有单个接口就能搞定的场景,更多的是“登录后创建订单→支付订单→查询订单状态”这种链式调用。接口自动化如何把这种链路串起来?
我的做法是:在用例里直接调用前序接口,把关键字段提取出来,传给后续接口。看一个典型的场景:
def test_full_order_flow(request_client): # 第一步:创建订单 create_resp = request_client.post("/api/v1/order/create", json={ "product_id": 1001, "quantity": 2 }) assert create_resp.status_code == 200 order_id = create_resp.json()["data"]["order_id"] assert order_id is not None # 第二步:支付订单 pay_resp = request_client.post("/api/v1/order/pay", json={ "order_id": order_id, "pay_method": "balance" }) assert pay_resp.status_code == 200 assert pay_resp.json()["data"]["pay_status"] == "success" # 第三步:查询订单状态 query_resp = request_client.get(f"/api/v1/order/{order_id}") assert query_resp.status_code == 200 assert query_resp.json()["data"]["status"] == "paid"这段代码最核心的地方在于order_id的传递。创建订单接口返回的order_id,是后面支付和查询的前置条件。如果你不把它提取出来传下去,后面的接口根本没法测。这就是接口测试中“数据传递”的核心技巧。
5.3 数据清理与测试隔离:别让你的测试数据污染环境
链路用例跑完,会留下一个已支付状态的订单在环境里。下次再跑一遍同样的用例时,如果创建订单的接口对同一商品有限购逻辑,第二次创建可能就会失败。这种问题非常隐蔽,排查起来也费劲。
解决方案是“测试后清理”。pytest的fixture支持yield语法,测试结束后可以执行清理代码:
@pytest.fixture(scope="function") def clean_order(request_client): order_ids = [] yield order_ids for order_id in order_ids: request_client.post(f"/api/v1/order/{order_id}/cancel")在用例里这样用:
def test_create_order(request_client, clean_order): resp = request_client.post("/api/v1/order/create", json={ "product_id": 1001, "quantity": 2 }) order_id = resp.json()["data"]["order_id"] clean_order.append(order_id) # 用例结束后自动取消这套机制的底层逻辑是:把“测试产生的副作用”在测试结束后回滚掉,保证每个用例互不干扰,能够独立重复执行。不要小看这一点,测试用例可重复执行,是自动化框架可用性的底线。
6. 常见问题与排查技巧实录
6.1 用例跑通了,但Allure报告里看不到任何数据,是哪里出了问题
这是新手遇到最多的问题,而且非常打击人。明明pytest终端显示执行成功,但执行allure serve时报错“没有找到结果文件”,或者报告是空的。
排查思路按顺序走:检查运行命令时有没有带--alluredir参数;检查reports/allure-results目录下有没有生成json文件;检查allure命令是否能正常执行(allure --version);确认allure和jdk版本兼容。很多人装了allure命令行工具,但没装Java环境,allure直接起不来。
另一种常见情况是每次跑完用例后,上一次的报告数据还残留,页面显示的是旧数据。所以addopts里的--clean-alluredir参数是有必要保留的,它会在每次执行前把旧结果清掉。
6.2 测试环境账号密码改了,用例大量失败,怎么处理
这是框架可维护性的第一道坎。如果你把账号密码写死在测试代码里,那账号一换,你就得全局搜索替换,还会漏。这种问题最好的解法是把配置放到config.yaml里。
更极端一点,有些公司测试环境的密码有特殊字符,比如带@和#的。yaml格式对特殊字符的处理比较容易出坑,如果密码是用双引号包起来的字符串,基本没问题。但如果密码本身包含双引号,那就需要转义。我只建议:配置文件里的密码统一用单引号或双引号包起来,不要写裸字符串。
6.3 接口返回的字段会动态变化,比如时间戳、随机数,怎么断言
断言写得太死是接口自动化的大坑。比如你断言了响应里的某个时间字段等于"2025-01-01 12:00:00",但服务器每次返回的都是当前时间,那这个用例必然第二次跑就失败。
正确思路是断言“字段存在”和“字段格式正确”,而不是断言“等于某个固定值”。用Python的datetime模块解析时间字符串,验证能不能解析成功;或者用正则匹配UUID格式。拿时间字段举例:
from datetime import datetime def test_get_time(request_client): resp = request_client.get("/api/v1/system/time") assert resp.status_code == 200 time_str = resp.json()["data"]["current_time"] # 断言是合法的ISO时间格式 datetime.fromisoformat(time_str)这种做法本质上是在做“非精确断言”。接口测试中要区分哪些字段是稳定结果,哪些是动态结果。稳定的字段做精确断言,动态字段做格式或范围断言,这样用例才不会三天两头被误报轰炸。
6.4 Token有效期很短,session级fixture登录一次后面全失效
很多公司为了安全,token有效期只设30分钟甚至15分钟。如果测试执行时间长,后面的用例全部401无权限。这个问题有三种解法:
- 方案一:在RequestClient里写一个自动判断逻辑,每次请求如果返回401,就重新登录并重试一次。这种方法最省事,但要在请求封装里加状态判断和重试机制。
- 方案二:把token过期时间当配置,执行到一定时间后刷新token。实现上复杂一些,需要维护一个时间戳。
- 方案三:把需要鉴权的用例和不需要鉴权的用例分开执行,先跑不依赖登录的用例,再跑登录后的用例,压缩用例执行时长。
我目前项目里用的是方案一,在request方法里判断状态码:
def request(self, method, path, **kwargs): url = self.base_url + path response = self.session.request(method, url, **kwargs) if response.status_code == 401: self._refresh_token() response = self.session.request(method, url, **kwargs) return response核心思路是:把“刷新登录态”变成请求客户端内部的自愈能力,业务用例完全不用感知token过期这件事。这样做的代价是,如果401是因为账号被封、密码改了,重试一次也会继续失败,但能多赚一次排查机会。
6.5 用例执行顺序随机导致数据依赖失败,有没有办法控制
pytest默认按照文件名的ASCII码顺序执行用例。如果你有多个测试文件,test_login.py会排在test_order.py前面,顺序本身是固定的。但如果你在同一个文件里写了相互依赖的用例,pytest默认不会保证定义顺序就是执行顺序,因为有参数化、跳过等情况。
我的建议是:不要把用例之间的依赖建立在“执行顺序”上,而是把前置步骤写进用例里。比如创建订单的用例,它需要的登录状态由fixture解决,它需要的商品数据由前置接口创建,而不是依赖另一个用例先跑。这样即使pytest乱序执行,每个用例也都能独立跑通。
7. 给框架加一点工程化血肉:日志、异常处理与CI集成
7.1 日志到底怎么配才够用
没有日志的自动化测试,出了问题等于抓瞎。请求发没发出去、返回了什么、断言为什么失败,这些都是排查的第一手资料。我推荐用Python标准库logging,配置好格式和时间滚动。规格上建议:一个用例跑完,日志至少能看到完整的请求URL、请求体、响应体、耗时、是否有异常。
# utils/log_utils.py import logging import os def setup_logging(): log_dir = "logs" os.makedirs(log_dir, exist_ok=True) logging.basicConfig( level=logging.INFO, format="%(asctime)s - %(levelname)s - %(name)s - %(message)s", handlers=[ logging.FileHandler("logs/api_test.log", encoding="utf-8"), logging.StreamHandler() ] )7.2 把框架接进CI,让每次提交都自动跑接口回归
框架搭好以后,如果只是本地手动跑,价值少了一半。真正让自动化发挥威力的是接进持续集成。不管是Jenkins、GitLab CI还是Github Action,本质上就是一条命令执行测试,然后发布报告。
以GitLab CI为例,你只需要在项目根目录放一个.gitlab-ci.yml:
stages: - test api-test: stage: test script: - pip install -r requirements.txt - pytest --alluredir=./reports/allure-results artifacts: paths: - reports/allure-results这样每次提交代码,流水线自动跑一遍全部接口用例,如果有失败的用例,MR直接合并不了。这才是接口自动化测试框架真正进入“工程化”的标志。
7.3 测试数据管理:环境隔离的几个做法
最后说测试数据。接口测试依赖的后台数据讲究隔离:开发环境、测试环境、预发布环境的数据应该互不干扰。config.yaml里每个环境配一套base_url和账号密码,执行时通过环境变量切换。
export TEST_ENV=dev pytest在config_reader里读取环境变量来选择配置:
import os import yaml def get_config(): env = os.getenv("TEST_ENV", "dev") with open("config/config.yaml", encoding="utf-8") as f: data = yaml.safe_load(f) return data["envs"][env]这套方案能避免一个过年加班场景:测试同事在dev环境跑得正欢,运维突然把dev库改了,第二天全部用例红成一片,谁也说不清是代码问题还是环境问题。
8. 最后再分享几个让我少踩很多坑的习惯
这框架我用过几个真实项目之后,最深的一个体会是:接口自动化框架的复杂度,永远不会来自第一个用例,而是来自第100个用例时的可维护性。所以我有个不成文的规矩——任何公共代码三层以上在用,就值得封装成工具函数;任何测试数据三个以上用例在用,就值得挪到数据文件里。很多团队做自动化失败,不是因为技术不会,而是因为刚开始写得很随意,后面被重构成本压垮,于是弃坑。
有一个小技巧我想特别提一下:assert断言的错误信息一定写清楚,让失败的人打开报告不用猜是哪个字段出了问题。
assert data["code"] == 0, f"业务码异常, 期望0, 实际{data['code']}"这个习惯看似不起眼,但在几百条用例的结果报告里,一条清晰的失败信息能省掉同事半小时排查时间。这也是我在实际工作中被队友感谢最多的一处细节。
另外,提醒一句:别想着把所有接口都自动化,自动化覆盖的是稳定接口和核心链路。那些还在频繁改动的接口,写了自动化就是给自己找罪受——改一次代码改一次脚本,还不如手工点。接口自动化的正确打开方式,是先把最核心的、最稳定的链路覆盖住,跑稳了,再慢慢扩充。框架本身5分钟能跑通,但用好它,需要的是持续的热情和冷静的判断。
这套“最小可用框架”跑起来以后,你完全可以沿着这些方向继续玩深一点:接入mock服务解决第三方依赖、做接口性能测试的基线对比、结合线上流量做录制回放。底子打好了,往上叠什么都是顺理成章的事。