首页
/ TiDB 集成测试录制工作流:tests/integrationtest 的 .test/.result 最小化录制实践

TiDB 集成测试录制工作流:tests/integrationtest 的 .test/.result 最小化录制实践

2026-09-05 18:16:46作者:齐添朝

本文围绕 TiDB 仓库中 Agent 技能文档 .agents/skills/tidb-integrationtest-recorder/SKILL.md 展开,讲清 tests/integrationtest 集成测试套件的“录制(record)- 复核(review)- 最小化 diff”完整工作流:如何从 t/ 目录下的用例路径推导 TestName、如何用 ./run-tests.sh -r 精准再生 .result 文件、以及为什么必须避免无关 result churn。读完你可以独立完成 TiDB 集成测试的录制、校验与结果文件治理,理解底层 mysql-tester 的启用/禁用新 collation 双跑机制与数据竞争检查逻辑。

技能定位与适用场景

该技能文档以 Agent 技能(skill)的形式定义了一套操作规范,其核心声明如下:

  • 适用场景:当修改位于 tests/integrationtest/t/** 下的集成测试用例,或需要为 SQL 行为补充集成测试覆盖时,使用本工作流。
  • 明确禁忌:对该套件不要使用 Go 测试的 -record 标志-record 仅属于那些显式支持的测试套件,这一点在 docs/agents/testing-flow.md 的单元测试一节中被再次强调:Use -record only for test suites that explicitly support it.)。
  • 权威出处:规范命令细节不写在技能文件里,而是统一指向 docs/agents/testing-flow.md 中的 Integration tests (/tests/integrationtest) 小节。技能文件只保留“指路 + 流程约束”,长命令块集中维护在 playbook 中,避免命令细节在多处重复后产生漂移——这一设计原则在 docs/agents/testing-flow.md 开头即有说明:“skills under .agents/skills/ should point here rather than duplicating long command blocks”。

该技能也是仓库级技能清单中的一员,.agents/skills/README.md 将其列为九个运维工作流技能之一(tidb-integrationtest-recorder: run and review tests/integrationtest recording flow),与 tidb-verify-profiletidb-failpoint-test-runnertidb-realtikv-runner 等技能共同构成 TiDB 的 Agent 测试纪律体系。

集成测试套件的目录结构

理解录制工作流之前,先明确 tests/integrationtest 的布局(来源:tests/integrationtest/README.md 的 “How It Works” 一节与 tests/integrationtest/run-tests.sh 脚本默认值):

路径 角色
tests/integrationtest/t/ 测试输入:.test 文件定义 SQL 用例,可含 ## 行内注释说明(如 t/planner/core/binary_plan.test 中为每段 base64 输入附带的注释)
tests/integrationtest/r/ 期望结果:与 .test 同路径的 .result 文件,执行后与之逐字比对
tests/integrationtest/s/(由 s.zip 解压得到) 统计信息:s/*.json 在测试运行前装载,保证 planner 相关结果稳定可复现
tests/integrationtest/config.toml 默认服务端配置,开启新 collation、table lock、新字符集等
tests/integrationtest/disable_new_collation.toml 禁用新 collation 时的替代配置

run-tests.sh 的默认变量可确认脚本行为:stats="s"mysql_tester_log="./integration-test.out",脚本在每次运行时通过 unzip -qq s.zip 重新解压统计目录,保证统计基线一致。

run-tests.sh 还导出了 TZ="Asia/Shanghai"(注释写明 “make tests stable time zone wise”),即结果比对对时区敏感的用例依赖这一固定时区,本地调试环境应保持默认。

TestName 推导规则

技能工作流的第 2 步给出了录制命令的关键输入:

Derive TestName from the path under tests/integrationtest/t/ without the .test suffix (example: planner/core/binary_plan).

docs/agents/testing-flow.md 中给出了完全一致的映射示例:

Mapping example: if you modify t/planner/core/binary_plan.test, then TestName is planner/core/binary_plan.

也就是说,TestName 就是 .test 文件相对 t/ 的目录路径(保留子目录层级、去掉扩展名),目录结构在 t/r/ 之间一一对应。仓库中可以直接验证这一点:输入文件 tests/integrationtest/t/planner/core/binary_plan.test 与期望结果文件 tests/integrationtest/r/planner/core/binary_plan.result 位于镜像路径上。

用例的粒度决定了录制的粒度:例如 t/ 顶层散布着 explain.testindex_merge.testcte.test 等单文件用例,而 t/planner/core/t/executor/t/ddl/ 等子目录承载成套用例。录制时只指定受影响的 TestName,这正是下一节“定向录制”要求的直接原因。

录制命令:定向记录受影响的套件

docs/agents/testing-flow.mdIntegration tests 小节是权威命令出处:

pushd tests/integrationtest
./run-tests.sh -r <TestName>
popd

结合 tests/integrationtest/README.md 的 Script Options 与 run-tests.shgetopts 解析逻辑,完整参数语义如下:

  • -r <test-name>|all:运行 t/<test-name>.test将执行结果录制回 r/<test-name>.result。指定 all 表示运行全部用例并整体重录——这正是技能 Guardrails 中“Prefer targeted recording of the affected suite only”要防止的做法,除非刻意做全量刷新,否则不要使用。
  • -t <test-name>:仅运行不录制(提供 -r 时该选项被忽略,脚本中 record_case 分支优先于 $tests 分支)。回归验证时应使用 -t
  • -d <y|Y|n|N|b|B>:控制测试期间新 collation 的启用状态。默认 bcollation_opt=2):以 collation 为前缀的用例在启用/禁用两种状态下各跑一遍(因此 r/ 下会出现 collation_agg_func_enabled.result / collation_agg_func_disabled.result 这类成对文件),其他用例仅以启用状态运行。y 仅启用、n 仅禁用。
  • -s <tidb-server-path>:使用已有 tidb-server 二进制,跳过构建。
  • -b <y|Y|n|N>:是否构建测试二进制,默认构建;提供 -s 时自动跳过。
  • -P <port>:连接已在指定端口运行的 tidb-server,跳过本地构建与启停。

脚本在执行录制时的实际行为(见 run-tests.shrun_mysql_tester 函数):

  1. extract_stats 解压 s.zip 得到统计基线;
  2. start_tidb_server 启动服务——默认走 unistore-store unistore -path ''),只有设置了 TIDB_TEST_STORE_NAME=tikv 环境变量且提供 TIKV_PATH 时才走 -store tikv -path ...-d 为禁用模式时改用 disable_new_collation.toml 配置;
  3. 调用外部工具 mysql_tester(脚本用 go install github.com/pingcap/mysql-tester/src@f2d90ea9522d30c9a8e8d70cc31c7f016ca2801f 安装固定版本),录制模式即追加 --record <case> 参数,并始终带 --check-error=true--collation-disable=<true|false>
  4. 结束后 kill -15 等待服务退出,并在 unistore 场景下 check_data_race:grep 服务日志中的 DATA RACE,命中则整轮测试判失败并打印日志。

技能工作流的第 1 步与 AGENTS.md 的 Validation Matrix 相互印证:tests/integrationtest/t/** 发生变更时的最小验证动作正是 “Record and verify regenerated result correctness (see docs/agents/testing-flow.md -> Integration tests)”。

结果文件复核:把 diff 压到最小

技能工作流的第 3 步是“Review changed files in tests/integrationtest/r/** and keep result diffs minimal”,配合 docs/agents/testing-flow.md 的补充说明:

Review changed files in tests/integrationtest/r and confirm each diff matches expected behavior. Result files usually do not need manual edits; if edits are necessary, keep them minimal and verify correctness before reporting.

落地成可操作清单:

  1. 录制完成后,用 git diff tests/integrationtest/r/ 审视全部被重写的结果文件;
  2. 逐行确认每一处变化都能对应到你本次改动应当引起的行为差异(计划节点、类型推断、报错文案等)。任何无法解释的变化都说明录制范围过大或环境不一致(例如统计信息、时区、collation 状态变化);
  3. 结果文件通常不需要人工编辑。README 指出 .result 是从执行结果“再生”出来的(To generate new .result and .json files from execution, use the -r parameter);若确需手工修正某一行,修改必须最小化,并再跑一次(用 -t <TestName> 只跑不录制的验证模式)确认通过后才可报告。

技能 Guardrails 的三条规则与上述流程一一对应:

  • Prefer targeted recording of the affected suite only:只录受影响的 TestName,避免 -r all 把无关用例一并重写;
  • Avoid unrelated result churnr/ 下数百个结果文件之间是“零漂移”基线,一次 PR 只应触碰与改动相关的文件;
  • If result files need manual edits, keep them minimal and verify with another run:手工编辑后必须二次验证。

进阶:next-gen 运行器与真实 TiKV 集群

tests/integrationtest/README.md 还记录了第二套运行入口:./run-tests-next-gen.sh [run-tests.sh options],它“sets up a real cluster environment and then invokes run-tests.sh with your provided options”。

tests/integrationtest/run-tests-next-gen.sh 源码可见其机制:设置 TIDB_TEST_STORE_NAME=tikvTIKV_PATH=127.0.0.1:2379 后,委托 tests/realtikvtest/scripts/next-gen/bootstrap-test-with-cluster.sh ./run-tests.sh "$@" 启动一个本地 3 PD + 3 TiKV + 1 TiKV-worker + MinIO 的 next-gen 集群(脚本头部注释列出了所需 TCP 端口:pd 2379/2380/2381/2383/2384、tikv 20160-20162/20180-20182、tikv-worker 19000),随后以 NEXT_GEN=1 调用 run-tests.shNEXT_GEN 环境变量在 run-tests.shstart_tidb_server 中会被追加 -keyspace-name SYSTEM --tidb-service-scope dxf_service 启动参数。

因此录制/复核流程本身不变,只是后端从 unistore 换成了真实 TiKV:同样用 -r <TestName> 定向录制,同样要复核 r/ 下最小 diff;但要注意 next-gen 集群占用固定端口,且 docs/agents/testing-flow.md 的 RealTiKV 一节对真实集群的启动/清理纪律(启动、探活、测试、强制清理、端口不可达检查)仍应遵守。

回归验证与日常开发流程

技能文档聚焦“录制”,而录制的目的始终是让回归验证可信。tests/integrationtest/README.md 的 Typical Workflows 给出日常路径:

  • 代码变更后的回归make devmake integrationtest(构建并跑全量集成测试,用于发现计划变化);
  • 新增/更新用例:在 t/ 添加 .test 文件(或向既有文件追加查询)→ ./run-tests.sh -r <casename> 生成期望结果 → 提交 t/r/ 两侧改动。

与本文主题直接相关的收尾纪律来自 docs/agents/testing-flow.md 的 “Related guidance” 一节:准备 PR 更新时,要把精确的测试命令写进 PR 描述(Tests 段),并遵循 AGENTS.md 的 Quick Decision Matrix 做回归政策判断。

小结

TiDB 集成测试录制工作流可以浓缩为四步:推导 TestNamet/ 相对路径去 .test)→ ./run-tests.sh -r <TestName> 定向录制 → 复核 r/ 下的 diff 是否每处变化都有预期行为解释 → 若手工编辑过结果文件则用只跑不录的模式二次验证。该流程的价值在于把“结果文件再生”约束在最小范围,使 tests/integrationtest/r/ 这一庞大回归基线始终保持干净、可审计;而底层脚本固定时区、固定统计基线(s.zip)、collation 双跑与数据竞争检查,共同保证了录制结果的确定性。技能文件刻意保持简短、把命令细节集中于 docs/agents/testing-flow.md,是 TiDB 面向 Agent 协作的文档分层(AGENTS.md 管策略、testing-flow.md 管命令、skills 管流程约束)的一个典型样本。

登录后查看全文
热门项目推荐
相关项目推荐