ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

TiDB 测试体系重构方案解读:从 pingcap/check 到 testify 的迁移设计与落地验证

TiDB 测试体系重构方案解读:从 pingcap/check 到 testify 的迁移设计与落地验证 TiDB 测试体系重构方案解读从 pingcap/check 到 testify 的迁移设计与落地验证【免费下载链接】tidbTiDB is built for agentic workloads that grow unpredictably, with ACID guarantees and native support for transactions, analytics, and vector search. No data silos. No noisy neighbors. No infrastructure ceiling.项目地址: https://gitcode.com/GitHub_Trending/ti/tidbTiDB 在 2021 年发布了测试体系重构设计方案见 docs/design/2021-06-27-restructure-tests.md核心目标是把主测试框架从长期缺乏维护的 pingcap/check 迁移到 go testing stretchr/testify并同步解决不稳定用例、冗余日志与巨型测试文件等历史包袱。本文以该设计文档为骨架逐条还原其动机、框架选型对比、三阶段实施计划与配套测试改进建议并结合当前仓库源码验证这些设计最终落地的形态帮助读者理解 TiDB 测试基础设施的演进脉络与可复用的工程实践。一、方案背景TiDB 测试体系的四大痛点设计文档开篇即点明了迁移前测试体系面临的四类主要问题这些问题直接影响了开发者在项目中的日常体验并发逻辑相关的测试大量不稳定严重拖累项目迭代期间的整体开发体验主测试框架 pingcap/check 缺乏维护与 GoLand 等现代 IDE 集成很差导致每位新人都会问“如何单独跑一个单元测试”同时框架无人维护上游 go-check/check 的开发也几乎停滞已通过用例产生的日志既嘈杂又冗余开发者很难从日志中快速定位真实问题存在大量巨型“集成测试”文件使测试变得脆弱、难以并行执行文档逐一给出了当时这些文件的行数文件迁移前路径行数expression/integration_test.go9801executor/executor_test.go8726ddl/db_test.go6930session/session_test.go4825planner/core/integration_test.go3900此外文档还列出了散落在 CI 上的十余个“卫星测试”如 common-test、integration-ddl-test、sqllogic-test-1/2、mybatis-test、tics-test 等它们“在哪里、如何修复失败、如何新增用例”都缺乏统一入口。设计方案决定优先处理前四个问题把卫星测试的有序化作为讨论起点而非当轮实施范围。二、总体设计迁移到 go testing stretchr/testify针对上述问题方案给出两条主线将主测试框架从 pingcap/check 迁移到 stretchr/testify通过系列附录建议见后文“测试改进建议”为巨型测试文件、冗余日志和不稳定用例开出配套“药方”并另立跟踪 issue 逐步消化。方案明确指出go 标准库的testing本身已提供并行t.Parallel、子测试与日志能力因此 TiDB 的取向是“尽可能贴近 go testing”借用 testify 提供的丰富断言 checkers再自行封装项目级测试套件test kits而不是再造一套脱离标准库的框架。三个测试框架的选型对比文档给出了三者的横向对比数据为其撰写时的公开仓库状态仅作工程选型参考不代表当前仓库承诺维度pingcap/checkgo-check/checkstretchr/testify活跃度/维护基本停滞、约一年无活跃提交停滞已久持续活跃与生态集成差与 GoLand 等 IDE 不兼容脱离 go testing原生基于 go testing兼容 GoLand 等断言能力薄弱比 pingcap/check 更弱丰富且仍在增长文档同时援引了同期已完成同类迁移的项目如 pingcap/errors、pingcap/log、tikv/client-go作为先行证据说明该迁移路径在 TiDB 生态内已被验证可行。三、分阶段实施计划Phase 0/1/2为了保证迁移不阻塞日常开发方案把过程切分为三个阶段逐步收缩 pingcap/check 的“新代码面”Phase 0引入迁移依赖双轨并行——先让 stretchr/testify 进入依赖树但允许新测试继续以 pingcap/check 编写尽量降低迁移初期的摩擦Phase 1闸门收紧——当 testify 版测试套件就绪、且出现足够多可直接复制的迁移样例后禁止新增以 pingcap/check 编写的测试Phase 2完成迁移——全部存量用例迁移完毕后从依赖树中彻底移除 pingcap/check。方案预计在 23 个 sprint约四个月内完成。Phase 1 的前提是“项目必需的全部测试套件已实现 有可复制的迁移样例”并按包package为单位渐进推进作者会在社区论坛主持该提案并对 Phase 1 发起投票结果回写到跟踪 issue。四、影响与风险下游对util/testkit的依赖迁移最直接的风险来自下游项目对 TiDB 测试工具包的依赖。文档举例 pingcap/br 与 pingcap/tidb 因历史原因存在循环依赖且 br 依赖github.com/pingcap/tidb/util/testkit一旦走到 Phase 2移除 pingcap/check这类依赖就会失效。文档给出的缓解策略是受影响项目可在 Phase 2 时拷贝缺失的 test kit 代码同时 TiDB 团队也会主动协助其摆脱对 pingcap/check 的依赖。从当前仓库看br 已作为子目录 br 随 tidb 主仓库一同演进工具包则整体收敛到 pkg/testkit这一结构性调整从根上化解了文档中描述的跨仓库循环依赖困境。五、落地验证对照当前仓库源码看迁移结果设计文档发布于 2021 年如今可以对照仓库实际状态验证其是否落地。以下是当前快照中可观察到的证据1. 依赖树testify 在位、pingcap/check 已移除主模块 go.mod 中可检索到github.com/stretchr/testify v1.11.1见 go.mod全仓库 Go 源码与 go.mod 中已不再把 pingcap/check 作为依赖引入仅剩 pkg/parser/ast/functions.go 注释中“Avoid name conflict with ... in github/pingcap/check”这类枚举命名规避的历史说明。这正好对应设计文档 Phase 2 的终态pingcap/check 依赖被移除。2. 统一测试工具包pkg/testkit设计文档提到的util/testkit如今收敛为根目录下的 pkg/testkit。其中 pkg/testkit/testkit.go 定义的核心结构TestKit同时持有 testify 的两类断言器并内嵌标准库testing.TBtype TestKit struct { require *require.Assertions assert *assert.Assertions t testing.TB store kv.Storage session sessionapi.Session // ... }构造函数签名func NewTestKit(t testing.TB, store kv.Storage) *TestKit完全面向 go testing并且在非 benchmark 场景会校验测试须以--tagsintest编译运行见 pkg/testkit/testkit.go 中的提示信息这体现了“贴近 go testing、不脱离标准库”的设计取向。除 TestKit 外包内还提供pkg/testkit/asynctestkit.go带require/assert字段并支持MustExec、断言查询结果等于期望值的异步测试套件pkg/testkit/dbtestkit.go 与 pkg/testkit/result.go数据库驱动层测试与结果比对封装pkg/testkit/testsetup/bridge.go提供SetupForCommonTest()统一各类测试的公共初始化pkg/testkit/testflag、pkg/testkit/testfork、pkg/testkit/testutil分别负责命令行 flag、确定性 fork 复现与自定义断言/日志钩子。这些子包共同构成了一套“go testing testify 项目自有套件”的完整基础设施正是设计文档“generate our own test kits”的直接产物。3. 巨型文件拆分从“文件”走向“目录 独立 Test 函数”对照文档列出的五个体积最大的文件当前仓库已能观察到明显的拆分痕迹原expression/integration_test.go9801 行演化为目录形态 pkg/expression/integration_test包含integration_test.go、main_test.go、README.md与 BUILD 文件其中integration_test.go现约 4791 行且组织为标准func TestXxx(t *testing.T)形态如TestFTSParser、TestFTSSyntax、TestVectorLong等见 pkg/expression/integration_test/integration_test.goplanner 侧则拆出 pkg/planner/core/casetest 与 pkg/planner/core/integration_test.go现约 2662 行把 case 驱动的测试与核心包解耦ddl 侧相应缩小为 pkg/ddl/integration_test.go现约 316 行与 pkg/ddl/ingest/integration_test.go约 979 行等聚焦的独立文件。拆分之后每个测试都对应独立的Test函数可以单独执行、单独过滤天然契合文档“拆成可并行运行的小单元、尽量做白盒测试而非只测端到端行为”的建议。4. 集成测试走向“下一代 Runner”文档中抱怨的“卫星测试散落各处”在测试目录层也逐步收敛。仓库根目录的 tests 下形成了三类可独立运行的测试域tests/integrationtest执行计划与端到端行为的 SQL 集成测试套件*.test与*.result成对出现可用经典./run-tests.sh或基于真实 TiKV 集群的./run-tests-next-gen.sh运行详见 tests/integrationtest/README.mdtests/realtikvtest需要真实 TiKV 环境的测试如 addindextest、addindex、statustest 等大量子目录tests/globalkilltest、tests/graceshutdown 等专项测试以及沿用br/lightning生态的 tests/integrationtest2。这种“可并行、有明确入口、环境边界清晰”的划分正是对设计文档中“测试在哪里、如何修失败、如何写新用例”这一痛点的正面回应。六、测试改进建议设计附录解读除框架迁移外设计文档附录还给出了三条改善测试质量的建议它们与主方案互为表里1. 静音通过用例的日志失败时才输出设计指出通过用例产生的日志对开发者几乎无用。方案引用 zap 生态的zaptest模块——它可以把日志重定向到testing.TB且每个用例只缓存输出、用例失败才打到控制台从而让go test输出保持干净。文档进一步提出在 pingcap/log 中落地logutil.InitTestLogger(t zaptest.TestingT, cfg *LogConfig)并在每个与日志相关的测试中启用以便既保留失败现场、又能安全移除默认的冗余日志开关。当前仓库日志相关工具位于 pkg/util/logutil配套的日志钩子与通用初始化也在 pkg/testkit/testutil 与 pkg/testkit/testsetup 中有所体现。2. 用确定性同步原语替代“睡足够久”对并发逻辑的测试建议优先使用sync.Mutex、sync.WaitGroup或其他并发工具如 latch做显式同步彻底去掉“足够长的 sleep”——sleep 既脆弱又白白消耗测试时间。从当前仓库的 pkg/testkit/testfork 等设施可以看出TiDB 后续还进一步引入了 fork/复现机制来收敛并发与偶发类问题与这一建议一脉相承。3. 拆分巨型文件 白盒测试优先重申将上述巨型文件拆成可并行的小单元并提倡用白盒测试直接验证中间行为而不是把一切压成脆弱的端到端链路测试。七、替代方案调查与未决问题方案也客观评估了替代路径go testing 本身已提供并行、子测试与日志支持Kubernetes、CoreDNS、etcd 等项目都直接基于 go testing其中仅 Kubernetes 额外借用 testify 的丰富断言。TiDB 采用同样取向以 go testing 为底座、引入 testify checkers、再自建项目级套件。文档在“未决问题”一节坦承仍有设计细节待定该节原本留空由社区在讨论与跟踪 issue 中逐步补全例如迁移期间新旧用例的闸门时机、存量巨型文件的拆分优先级、卫星测试的统一收编节奏等。八、延伸阅读若要进一步验证本文描述可在当前仓库中重点查看以下内容设计文档原文docs/design/2021-06-27-restructure-tests.md测试工具包主入口与结构pkg/testkit/testkit.go、pkg/testkit/asynctestkit.go、pkg/testkit/result.go测试初始化与辅助设施pkg/testkit/testsetup/bridge.go、pkg/testkit/testfork/fork.go、pkg/testkit/testutil/require.go拆分后的集成测试样例pkg/expression/integration_test/integration_test.go、pkg/planner/core/integration_test.go端到端/真实集群测试入口tests/integrationtest/README.md、tests/realtikvtest。总的来说这份 2021 年的设计文档为 TiDB 测试体系划定了清晰的技术路线以 go testing 为标准底座、以 testify 为断言补充、以自建 test kit 为项目层封装并通过阶段化迁移把风险控制在最低。对照当前仓库可以看到从go.mod中的依赖收敛、pkg/testkit的统一形态到巨型文件拆分与新一代集成测试 Runner方案的核心主张均已形成可读、可运行的工程事实——这份“先设计、再分阶段落地”的测试治理思路对任何面临测试框架老化与存量用例膨胀问题的 Go 项目都具有直接的参考价值。【免费下载链接】tidbTiDB is built for agentic workloads that grow unpredictably, with ACID guarantees and native support for transactions, analytics, and vector search. No data silos. No noisy neighbors. No infrastructure ceiling.项目地址: https://gitcode.com/GitHub_Trending/ti/tidb创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表