☰
为什么人工测试发现的缺陷不多:用 Codex、ChatGPT 与 MASE 复盘协同开发中的测试盲区
2026/9/26 16:48:45 网站建设 项目流程

1. 为什么人工测试总在“漏”:从磨耳朵项目的缺陷分布说起

如果你带过 AI 协同开发的项目,大概率遇到过这种诡异现象:自动化测试全绿,Codex 生成的代码看起来逻辑自洽,ChatGPT 帮你把需求也捋得挺清楚,可一旦真机上手,用户三分钟就能挑出毛病。更反直觉的是,人工测试翻来覆去点,最后真正报上来的“传统功能缺陷”却没几个,大部分反馈其实是“这个按钮该加”“语速不对”“退出没退干净”。

我在复盘一个跨 macOS、Android、iOS、Windows 的语音朗读项目时,把这件事拆开看了一遍。项目在很短时间内堆出了 17 个可追踪的 OpenSpec 变更和 36 个纵向提交,涉及文件解析、系统 TTS、计时、进度、持久化、后台音频、跨平台界面、应用签名和离线神经语音 POC。按常理,这种变化密度下人工测试应该能挖出一堆边界值、状态机、输入校验问题,但实际归并下来,人工发现的问题高度集中在几类:声学体验、真机参数、真实进程生命周期,以及播放中拖动进度时的异步竞争。

这不是“AI 写代码很准”能解释的,也不是“有自动化就不需要人”。真正的原因是四类角色各自覆盖了不同的不确定性:ChatGPT 式对话负责把需求说清楚,Codex 把规格落实成代码和可执行证据,MASE 约束每次变化的过程,人负责判断真实世界里到底好不好用。人工测试漏检的根因,往往不是人不够仔细,而是自动化和人工的注意力边界没有对齐——自动化在机械可判断的层面把缺陷提前拦掉了,人工却还在重复点那些自动化已经覆盖的按钮,真正该盯的真实设备、真实进程、真实时序反而被稀释了。

这篇就按这个思路,把 Codex、ChatGPT、MASE 的协作链路拆开,给你一套可复制的协同测试配置骨架和验证动作,帮你定位自己团队里的测试盲区。

2. 前置:TaoToken 在协同链路里的位置

在讲具体配置之前,先把工具链的接入点说清楚。这套协同开发里,Codex 负责仓库级工程执行,ChatGPT 负责需求澄清和方案讨论,MASE 是过程框架,而模型调用这一层我用的是 TaoToken 做统一入口。它的官网是 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= ,API 地址是 https://taotoken.net/api ,注意 API 地址不带 UTM 参数。

为什么要在协同测试里单独提这一层?因为当你的验证动作需要反复调用模型做代码审查、根因假设生成、测试用例补全时,调用链的稳定性直接决定了门禁能不能跑通。如果模型调用本身不稳定,你会把“模型超时”误判成“测试失败”,进而污染整个缺陷归因。

TaoToken 在这里的角色是提供统一的模型访问入口,让你在 Codex 的工程流程、ChatGPT 的需求讨论、以及自动化门禁里的模型调用之间保持一致。它不替代编辑器,也不替代你的测试框架,只是把模型调用这一层收敛到一个可管理的入口。

接入前你需要准备的东西:

  • 一个可用的 API Key,在控制台生成:https://taotoken.net/console?utm_source=taotoken_aicg_blog_end&utm_content=console&utm_campaign=rewrite
  • 确认你要用的模型能力,可以先在模型对话里试:https://taotoken.net/models?utm_source=taotoken_aicg_blog_end&utm_content=models&utm_campaign=rewrite
  • 如果你要做长期编码或 Agent 类任务,看 Coding Plan:https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding-plan&utm_campaign=rewrite
  • API Key 管理页:https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api-keys&utm_campaign=rewrite
  • 接入文档:https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite

如果你用的是 Claude Code 这类 Anthropic 系工具,对应的接入说明在:https://taotoken.net/claudecode?utm_source=taotoken_aicg_blog_end&utm_content=claudecode&utm_campaign=rewrite

把这些入口先固定下来,后面配置门禁脚本时直接引用环境变量,不要硬编码。

3. 可复制配置:协同测试骨架

这一节给你一套可以直接抄的配置骨架。核心思路是:把“可机械判断”的部分全部交给自动化门禁,把“必须真实世界判断”的部分显式标记出来,交给人工,并且让两者在同一个候选版本上对齐。

3.1 目录与角色分工

先约定一个最小目录结构,让 Codex、ChatGPT、MASE 的产物各归其位:

project/ ├── specs/ # MASE/OpenSpec 变更边界 │ ├── active/ │ └── archive/ ├── tests/ │ ├── unit/ # 领域规则 │ ├── contract/ # 跨模块公共语义 │ ├── integration/ # 跨模块行为 │ └── e2e/ # 用户主流程 P0 ├── gates/ │ ├── candidate-bind.sh # 候选绑定验证 │ ├── real-app-e2e.sh # 真实签名 App E2E │ └── model-review.sh # 模型辅助审查 └── .env.local # 本地密钥,不入库

角色分工对应到目录:

角色负责产物对应目录
ChatGPT 式对话需求澄清、验收标准specs/active
Codex 工程执行代码、RED 证据、提交tests/、源码
MASE 规范Profile、门禁、根因、回滚gates/、specs
人工使用者真机体验、时序判断不落盘,但反馈进 specs

3.2 环境变量配置

把模型调用统一走 TaoToken,避免散落在各个脚本里:

# .env.local export TAOTOKEN_API_BASE="https://taotoken.net/api" export TAOTOKEN_API_KEY="sk-你的key" export TAOTOKEN_MODEL="你的默认模型"

注意 API 地址不要加 UTM,只有官网和 deep link 才带。加载方式:

set -a source .env.local set +a

3.3 候选绑定门禁脚本

这是整个骨架里最关键的一环。人工测试漏检的一大原因是:测的不是最终制品。源码测试通过,不代表签名 App 行为正确。所以每次人工验收前,先跑候选绑定:

#!/usr/bin/env bash # gates/candidate-bind.sh set -euo pipefail CANDIDATE_DIR="${1:-./dist}" EXPECTED_HASH_FILE="${2:-./dist/candidate.sha256}" echo "[1/4] 校验候选哈希" if [ ! -f "$EXPECTED_HASH_FILE" ]; then echo "缺少候选哈希文件,拒绝进入人工验收" exit 1 fi shasum -a 256 -c "$EXPECTED_HASH_FILE" echo "[2/4] 校验签名与权限" codesign --verify --deep --strict "$CANDIDATE_DIR/App.app" 2>/dev/null || { echo "签名校验失败" exit 1 } echo "[3/4] 校验版本号与 ABI" plutil -extract CFBundleShortVersionString raw "$CANDIDATE_DIR/App.app/Contents/Info.plist" echo "[4/4] 校验真实 UI 入口存在" test -f "$CANDIDATE_DIR/App.app/Contents/MacOS/App" || { echo "可执行入口缺失" exit 1 } echo "候选绑定通过,允许进入人工验收"

这个脚本的作用是:把“人工测的到底是哪个版本”这件事变成可验证的事实。没有这一步,用户反馈“错误依旧”时,你无法排除“装错版本”这个可能性。

3.4 真实进程生命周期 E2E

退出按钮没真正退出,是典型的“单元测试能过、真实进程不消失”的缺陷。配置一个真实 App 的进程退出门禁:

#!/usr/bin/env bash # gates/real-app-e2e.sh set -euo pipefail APP_PATH="${1:-./dist/App.app}" TIMEOUT_SECONDS=3 open "$APP_PATH" sleep 2 APP_PID=$(pgrep -f "$APP_PATH/Contents/MacOS/App" | head -n1) if [ -z "$APP_PID" ]; then echo "App 未启动" exit 1 fi osascript -e 'tell application "System Events" to click button "退出应用" of window 1 of process "App"' for i in $(seq 1 "$TIMEOUT_SECONDS"); do if ! kill -0 "$APP_PID" 2>/dev/null; then echo "进程已在 ${i}s 内退出" exit 0 fi sleep 1 done echo "进程在 ${TIMEOUT_SECONDS}s 内未退出,判定失败" kill -9 "$APP_PID" 2>/dev/null || true exit 1

这个门禁把“退出”这个用户语义,从“清理函数执行了”提升到“进程真的消失了”。人工测试的价值在这里被固化成了自动化,下次就不需要人再反复点。

3.5 模型辅助根因假设

MASE 要求先提出可证伪根因,再修复。这一步可以用模型辅助生成假设,但必须由人确认。配置一个审查脚本:

#!/usr/bin/env bash # gates/model-review.sh set -euo pipefail DIFF_FILE="${1:-./diff.patch}" PROMPT_FILE="${2:-./gates/review-prompt.txt}" if [ ! -f "$DIFF_FILE" ]; then echo "缺少 diff 文件" exit 1 fi curl -sS "$TAOTOKEN_API_BASE/v1/chat/completions" \ -H "Authorization: Bearer $TAOTOKEN_API_KEY" \ -H "Content-Type: application/json" \ -d "$(jq -n \ --arg model "$TAOTOKEN_MODEL" \ --arg prompt "$(cat "$PROMPT_FILE")" \ --arg diff "$(cat "$DIFF_FILE")" \ '{model: $model, messages: [{role: "user", content: ($prompt + "\n\n" + $diff)}]}')" \ | jq -r '.choices[0].message.content'

配套的 prompt 文件:

你是代码审查助手。请针对以下 diff,输出: 1. 可能被自动化测试遗漏的真实世界边界(进程、音频、时序、设备) 2. 每条边界的可证伪根因假设 3. 建议的确定性 RED 测试形态 不要输出泛泛而谈的建议,每条必须能对应到具体代码路径。

注意:模型输出的是假设,不是结论。人工要判断哪些假设值得变成 RED 测试。

4. 验证请求与成功结果

配置好之后,跑一遍完整链路,确认每个环节都能产出可验证的结果。

4.1 验证模型调用连通

先用最小请求确认 TaoToken 入口可用:

curl -sS "$TAOTOKEN_API_BASE/v1/chat/completions" \ -H "Authorization: Bearer $TAOTOKEN_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "'"$TAOTOKEN_MODEL"'", "messages": [{"role": "user", "content": "回复 OK 两个字母即可"}] }' | jq -r '.choices[0].message.content'

预期输出:

OK

如果这里失败,先排查密钥和网络,不要往下走。模型调用不通会把后面的门禁全部污染成假失败。

4.2 验证候选绑定

chmod +x gates/candidate-bind.sh ./gates/candidate-bind.sh ./dist ./dist/candidate.sha256

成功结果:

[1/4] 校验候选哈希 ./dist/App.app: OK [2/4] 校验签名与权限 [3/4] 校验版本号与 ABI 1.4.2 [4/4] 校验真实 UI 入口存在 候选绑定通过,允许进入人工验收

4.3 验证真实进程退出

chmod +x gates/real-app-e2e.sh ./gates/real-app-e2e.sh ./dist/App.app

成功结果:

进程已在 1s 内退出

如果输出“进程在 3s 内未退出”,说明退出握手仍有死锁,需要回到根因分析,而不是让用户再试一次。

4.4 验证模型辅助审查

git diff HEAD~1 > diff.patch chmod +x gates/model-review.sh ./gates/model-review.sh ./diff.patch ./gates/review-prompt.txt

预期输出是一组针对具体代码路径的边界假设,例如:

1. 拖动进度时同一次松手可能提交两个 seek 事件,第二个取消第一个批次, 导致旧语音仍 active,新语音启动时报 alreadyActive。 根因假设:controller 缺少 single-flight 合并。 建议 RED:向真实 Slider 发送一次拖动事件,断言只发起一次 stop。

拿到这个输出后,人工判断哪条假设值得变成确定性测试。这一步是 MASE 里“先红后绿”的入口。

5. 本篇常见错排查

5.1 模型调用返回 401 或 403

先确认 API Key 是否从控制台正确生成,以及环境变量是否真的加载进当前 shell。用echo $TAOTOKEN_API_KEY确认非空。如果 Key 正确但仍失败,检查请求头里的Authorization格式是否为Bearer加 Key,注意中间有空格。

5.2 候选绑定脚本报“缺少候选哈希文件”

说明你的构建流程没有产出哈希文件。在打包步骤后追加:

shasum -a 256 dist/App.app > dist/candidate.sha256

不要跳过这一步,否则人工验收的版本无法追溯。

5.3 真实进程 E2E 在 CI 里失败

CI 环境通常没有图形界面,osascript点击按钮会失败。这类门禁应该标记为“仅本地/真机执行”,在 CI 里跳过,但必须在人工验收前本地跑通。配置方式:

if [ "${CI:-false}" = "true" ]; then echo "CI 环境跳过真实 UI 门禁" exit 0 fi

5.4 模型审查输出全是泛泛建议

检查 prompt 是否明确要求“每条必须对应具体代码路径”。如果 diff 太大,模型会倾向于概括。把 diff 按文件拆分,逐个审查,效果更稳定。另外确认你用的模型能力足够,可以在模型对话里先试一条真实 diff。

5.5 人工反馈“错误依旧”但门禁全绿

这是最有价值也最容易被误处理的信号。不要用绿色报告反驳用户。正确动作是:把用户的真实操作路径录下来,转成确定性 E2E。比如进度拖动问题,最终是靠向签名 App 发送真实鼠标拖动事件,才复现出同一次松手提交两个 seek 的时序。门禁全绿只说明当前门禁覆盖的路径没问题,不说明用户路径没问题。

5.6 把新需求误算成缺陷

复盘时先区分:这条反馈在提出之前,有没有对应的验收规则?没有规则,就不是逃逸缺陷,而是需求浮现。把新需求、需求变更、体验校准、功能缺陷分开统计,否则你的缺陷率数据会失真,改进方向也会跑偏。

6. 把人工注意力放回真实世界边界

这套骨架跑下来,你会发现人工测试的定位变了。它不再负责重复点按钮、重复验证状态机、重复检查输入校验,这些已经被单元、契约、集成和 P0 E2E 拦掉了。人工真正要盯的是自动化最难覆盖的那几类:系统 TTS 和厂商 voice 的声学差异,扬声器、耳机、环境噪声和听者语言能力,OS 真正的进程、音频和锁屏生命周期,UI 框架产生的真实事件序列,以及 provisioning、设备授权和外部工具链状态。

如果你要长期做编码或 Agent 类任务,可以把这套门禁和 Coding Plan 结合,让模型调用和工程流程稳定在同一个入口上:https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding-plan&utm_campaign=rewrite

接入过程中遇到门禁脚本或 API 调用问题,先查接入文档: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

想先验证某个模型在根因假设生成上的表现,直接在模型对话里试:https://taotoken.net/models?utm_source=taotoken_aicg_blog_end&utm_content=models&utm_campaign=rewrite

最后留一个我踩过的坑:不要为了让门禁变绿而放宽断言。把“进程 3 秒内退出”改成“10 秒内退出”,问题不会消失,只会以无声、重头播放或假 playing 的形式继续出现。根因分析把多个表象收敛成同一个并发所有权问题,才是真正减少人工漏检的路径。

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

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

立即咨询