☰
从脚本到工程体系:用 Claude Code + GLM-5 搭建企业级 AI 接口自动化测试平台(TaoToken 统一 Key 接入篇)
2026/9/25 11:56:23 网站建设 项目流程

1. 从能跑到能扛:接口自动化测试的工程化断层

很多团队都经历过这个阶段:用 Claude Code 一句话生成几个 pytest 脚本,跑通了登录、下单、查询,看着终端里的绿色 PASS 挺开心。可一旦接口数量从 20 个涨到 200 个,环境从 dev 扩到 stg、prod,问题就全冒出来了——base_url 硬编码在用例里、测试数据互相污染、失败重试靠手动、报告只有一份 HTML 没人看。这时候你会发现,缺的不是“生成脚本的能力”,而是把脚本组织成工程体系的能力。

这篇要解决的就是这个断层。核心思路是:让 Claude Code 负责生成符合规范的用例骨架,让 GLM-5 负责补全断言和边界条件,而所有模型调用统一走 TaoToken 的 Key 和 API 通道,避免在多个平台之间来回切换 Key、对账、限流。适合谁?适合已经能写 pytest、但项目一变大就失控的测试开发同学,也适合想把 AI 生成能力真正嵌进 CI 流水线的工程团队。

我试过把 Key 散落在各个脚本里,后来发现统一入口才是省心的关键。下面从配置骨架开始,一步步搭出可复制的目录分层、config.toml、settings.json,最后跑一次接口回归验证整条链路。

2. TaoToken 前置:统一 Key 与 API 通道

在动手写配置之前,先把“模型调用”这件事收口。企业级测试平台里,AI 能力通常出现在三个位置:生成用例骨架、补全断言、失败归因分析。如果每个位置各接一个平台的 Key,运维成本会指数级上升。TaoToken 在这里扮演的是统一入口——一个 Key 覆盖 Claude Code 和 GLM-5 的调用,API 地址固定,计费和限流集中管理。

你需要先拿到 Key。访问官网 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= 注册后,进入控制台创建 API Key。控制台地址是 https://taotoken.net/console?utm_source=taotoken_aicg_blog_end&utm_content=console&utm_campaign=rewrite ,Key 管理页在 https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api-keys&utm_campaign=rewrite 。创建时建议按用途命名,比如pytest-gen、assert-fill,方便后续在日志里区分调用来源。

API 基础地址统一用 https://taotoken.net/api ,注意这个地址不带任何查询参数,直接作为 base_url 写进配置即可。模型对话调试可以在 https://taotoken.net/models?utm_source=taotoken_aicg_blog_end&utm_content=models&utm_campaign=rewrite 里先验证 GLM-5 是否可用,确认返回正常再写进工程配置。如果你后续要做长期编码或 Agent 任务,可以了解 Coding Plan:https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding-plan&utm_campaign=rewrite 。

注意:Key 只放在环境变量或本地配置文件里,不要提交到 Git。下面所有配置示例都用占位符sk-xxxx,你替换成自己的即可。

3. 可复制配置:config.toml 与 settings.json 骨架

工程化的第一步是把“环境相关”和“模型相关”的配置从代码里抽出来。我采用双文件策略:config.toml管测试环境和执行策略,settings.json管 AI 通道和模型参数。这样 CI 里只需要替换环境变量,不用改代码。

3.1 目录分层示例

先看整体结构,后面所有配置都基于这个分层:

api-test-platform/ ├── config/ │ ├── config.toml # 环境与执行策略 │ └── settings.json # AI 通道与模型参数 ├── common/ │ ├── config_loader.py # 配置加载器 │ ├── base_request.py # 统一请求封装 │ └── data_factory.py # 测试数据工厂 ├── tests/ │ ├── conftest.py # 全局 fixture │ ├── smoke/ │ │ └── test_health.py │ └── regression/ │ └── test_order_flow.py ├── scripts/ │ └── coverage_calc.py ├── reports/ └── pytest.ini

这个分层的核心原则是:config/只放配置,common/只放可复用能力,tests/只放用例,scripts/只放辅助脚本。Claude Code 生成用例时,只要约束它往tests/下写,就不会污染其他层。

3.2 config.toml 完整骨架

# config/config.toml [default] env = "dev" timeout = 10 retry = 2 retry_delay = 3 [env.dev] base_url = "http://localhost:8000/api/v1" db_host = "localhost" db_name = "shop_dev" [env.staging] base_url = "https://staging-api.example.com/api/v1" db_host = "staging-db.internal" db_name = "shop_stg" [ai] provider = "taotoken" base_url = "https://taotoken.net/api" model_gen = "claude-code" model_assert = "glm-5" max_tokens = 4096 temperature = 0.2

这里把base_url按环境隔离,用例里通过 fixture 读取,绝不硬编码。[ai]段落里model_gen负责生成用例骨架,model_assert负责补全断言,两者都走同一个base_url。

3.3 settings.json 完整骨架

{ "ai_channel": { "base_url": "https://taotoken.net/api", "api_key_env": "TAOTOKEN_API_KEY", "timeout": 60, "max_retries": 3 }, "models": { "claude-code": { "endpoint": "/v1/messages", "role": "case_generator" }, "glm-5": { "endpoint": "/v1/chat/completions", "role": "assertion_filler" } }, "logging": { "level": "INFO", "file": "reports/ai_calls.log" } }

api_key_env指向环境变量名,而不是直接写 Key。运行时用os.getenv("TAOTOKEN_API_KEY")读取。这样在 CI 里只需要配置一个 Secret,本地开发用.env文件加载。

3.4 配置加载器

# common/config_loader.py import os import json import tomllib from pathlib import Path ROOT = Path(__file__).resolve().parent.parent def load_config(env: str | None = None) -> dict: with open(ROOT / "config" / "config.toml", "rb") as f: cfg = tomllib.load(f) env = env or os.getenv("TEST_ENV", cfg["default"]["env"]) merged = {**cfg["default"], **cfg["env"][env], "ai": cfg["ai"]} return merged def load_settings() -> dict: with open(ROOT / "config" / "settings.json", "r", encoding="utf-8") as f: return json.load(f)

tomllib是 Python 3.11 内置的,如果你用 3.10,换成tomli即可。加载器把默认配置和环境配置合并,用例里拿到的就是一份扁平化的字典。

4. 验证请求:一次接口回归的完整动作与预期输出

配置写好了,得跑一次真实回归来验证整条链路。这里用 Claude Code 生成一个订单流程的用例骨架,再用 GLM-5 补全断言,最后通过 TaoToken 通道调用。

4.1 生成用例骨架

在 Claude Code 里输入约束提示,让它按目录分层生成:

在 tests/regression/ 下生成 test_order_flow.py, 要求: 1. 使用 config fixture 获取 base_url,禁止硬编码 2. 使用 DataFactory 生成用户和商品数据 3. 包含创建订单、查询订单、取消订单三个步骤 4. 每个步骤留出 assert 占位,标注 # TODO: assert 5. 添加 allure 装饰器

生成的骨架大致如下:

# tests/regression/test_order_flow.py import allure import pytest from common.base_request import BaseRequest from common.data_factory import DataFactory @allure.feature("订单管理") class TestOrderFlow: @allure.story("创建并取消订单") def test_create_and_cancel_order(self, config): api = BaseRequest(config["base_url"]) user = DataFactory.user_payload() product = DataFactory.product_payload() resp_user = api.post("/auth/register", json=user) # TODO: assert resp_order = api.post("/orders", json={ "user_id": user["username"], "product_id": product["name"], "quantity": 1 }) # TODO: assert order_id = resp_order.json().get("order_id") resp_cancel = api.post(f"/orders/{order_id}/cancel") # TODO: assert

4.2 用 GLM-5 补全断言

把上面的骨架和接口文档片段一起发给 GLM-5,让它补全# TODO: assert部分。调用走 TaoToken 的/v1/chat/completions:

# scripts/fill_assertions.py import os import json import requests from common.config_loader import load_settings def fill_assertions(code_snippet: str, api_doc: str) -> str: settings = load_settings() channel = settings["ai_channel"] key = os.getenv(channel["api_key_env"]) resp = requests.post( f"{channel['base_url']}/v1/chat/completions", headers={"Authorization": f"Bearer {key}"}, json={ "model": "glm-5", "messages": [ {"role": "system", "content": "你是接口测试断言专家,只输出补全后的代码。"}, {"role": "user", "content": f"接口文档:{api_doc}\n\n待补全代码:{code_snippet}"} ], "temperature": 0.2, "max_tokens": 4096 }, timeout=channel["timeout"] ) resp.raise_for_status() return resp.json()["choices"][0]["message"]["content"]

补全后的断言会变成类似:

resp_user = api.post("/auth/register", json=user) assert resp_user.status_code == 201, f"注册失败: {resp_user.text}" assert "user_id" in resp_user.json() resp_order = api.post("/orders", json={...}) assert resp_order.status_code == 201 assert resp_order.json()["status"] == "created" resp_cancel = api.post(f"/orders/{order_id}/cancel") assert resp_cancel.status_code == 200 assert resp_cancel.json()["status"] == "cancelled"

4.3 执行回归并查看预期输出

export TAOTOKEN_API_KEY="sk-xxxx" export TEST_ENV="dev" pytest tests/regression/test_order_flow.py -v --alluredir=reports/allure-results

预期输出:

tests/regression/test_order_flow.py::TestOrderFlow::test_create_and_cancel_order PASSED [100%] ========================= 1 passed in 2.34s =========================

如果断言失败,终端会打印resp_user.text的内容,方便定位是接口返回结构变了还是数据问题。Allure 结果目录里会生成对应的 JSON,后续可以用allure serve查看带步骤的报告。

5. 本篇常见错排查

5.1 401 Unauthorized

最常见的原因是环境变量没生效。检查echo $TAOTOKEN_API_KEY是否有值,以及settings.json里的api_key_env名称是否和实际环境变量一致。注意 Key 不要带引号,也不要在末尾留空格。

5.2 模型返回空内容

如果 GLM-5 返回的choices[0].message.content为空,先确认max_tokens是否设得太小。补全断言这种任务建议至少 2048。另外检查temperature是否过高导致输出不稳定,测试场景建议 0.2 以下。

5.3 base_url 拼接错误

BaseRequest里如果直接拼接config["base_url"] + path,要确保base_url末尾没有多余的/,path 开头有/。建议在BaseRequest.__init__里做一次rstrip("/")处理。

5.4 pytest 找不到 config fixture

configfixture 必须定义在conftest.py里,且conftest.py要在tests/根目录。如果放在子目录,只有该子目录的用例能用到。全局 fixture 统一放tests/conftest.py。

5.5 并行执行时数据冲突

用pytest-xdist并行时,多个 worker 可能生成相同的用户名。DataFactory里要加随机后缀,比如f"user_{fake.user_name()}_{random.randint(1000,9999)}",避免唯一约束冲突。

6. 把 AI 通道收口到工程体系里

走到这里,你已经有了可复制的config.toml、settings.json、目录分层,以及一次完整的回归验证动作。关键点不在于某个脚本多聪明,而在于所有 AI 调用都通过 TaoToken 的统一 Key 和 API 通道走,配置集中、日志集中、限流集中。后续要扩展失败归因、用例自愈,只需要在settings.json里加模型配置,不用动业务代码。

如果你在接入过程中遇到 Key 或通道问题,可以直接看接入文档:https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite 。需要管理多个项目的 Key,去 API Keys 页面:https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api-keys&utm_campaign=rewrite 。长期跑编码和 Agent 任务的话,Coding Plan 会更合适:https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding-plan&utm_campaign=rewrite 。Claude Code 相关的接入细节在 https://taotoken.net/claude-code?utm_source=taotoken_aicg_blog_end&utm_content=claude-code&utm_campaign=rewrite 。

最后留一个实用技巧:在conftest.py里加一个 session 级的 fixture,启动时打印当前环境和模型配置,跑 CI 时一眼就能看出用的是哪个通道,省去翻日志的时间。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询