如何保证40万首诗词转换不出一个错?chinese-poetry-api测试策略:单元测试、模糊测试与集成测试
【免费下载链接】chinese-poetry-api📜 诗泉:高性能中国古诗词 API 服务项目地址: https://gitcode.com/gh_mirrors/ch/chinese-poetry-api
诗泉(chinese-poetry-api)是一个基于 Go 语言的高性能中国古诗词 API 服务,内置近 40 万首唐诗、宋词、元曲,并提供简繁转换、体裁分类、全文搜索等能力。数据量这么大,任何一个错别字、任何一首分类错误的诗,都会被用户一眼看到。该项目的答案是:用"单元测试 + 模糊测试 + 集成测试 + 基准测试"四层防线,把 40 万首诗词的批量转换当成一个可验证的工程问题来解决。
为什么数据转换系统需要"零容忍"测试
这个项目的数据链路是:
原始 JSON 数据 → 文本归一化 →简繁转换+体裁分类→ 写入 SQLite → 通过 REST / GraphQL 双接口对外服务
真正"会出错"的环节集中在 internal/classifier/:
- 简繁转换(
converter.go):"床前明月光" 转繁体后必须逐字正确,错一个字就是事故; - 体裁分类(
type.go):根据行数、每行字数、韵脚判断是五言绝句、七言律诗还是词,规则多、边界多。
这两类函数是纯函数,恰好最适合被自动化测试"锁死"。
第一道防线:单元测试——表驱动测试锁死转换规则
单元测试全部采用 Go 生态惯用的表驱动测试风格,覆盖真实诗词样例和边界场景:
| 测试文件 | 守护对象 | 典型用例 |
|---|---|---|
| converter_test.go | 简繁转换 | "春眠不觉晓"→"春眠不覺曉"、已是繁体、空字符串、中英混合 |
| type_test.go | 体裁分类 | 五言绝句(无标点/带标点)、七言律诗、带词牌名的"词"、超长异常行 |
| helpers/common_test.go | 文本归一化 | 全角/半角标点、空段过滤、断句切分 |
以简繁转换为例,测试用例只关心"输入→期望输出"两列,"中国"→"中國"、混合文本、空串各占一行,新增边界场景只需追加一行数据。
涉及数据库的测试则统一由 internal/testutil/testutil.go 提供公共脚手架:每次测试打开一个内存 SQLite 数据库、自动执行迁移、测试结束自动清理,无需任何外部依赖,秒级跑完。
第二道防线:模糊测试——用随机输入轰炸边界用例
单元测试只覆盖"你想到的"错误,模糊测试(Fuzzing)负责找出"你没想到的"。项目使用 Go 标准库原生 fuzz 框架,对核心转换函数持续投喂随机字符串:
FuzzToTraditional/FuzzToSimplified:随机输入 → 断言不 panic、输出是合法 UTF-8、往返转换可回环(繁→简→繁不报错);FuzzClassifyPoetryType:随机"诗句+韵脚" → 断言分类结果必须落在已知体裁集合内;FuzzRemovePunctuation/FuzzSplitBySentence:随机标点串 → 断言结果不含残留标点。
种子语料(seed corpus)本身就很有讲究——"床前明月光"、"123abc!@#"、"混合text文字123"、空串、超长行,等于把真实数据的脏场景提前喂了进去。详见 converter_fuzz_test.go 与 type_fuzz_test.go。
第三道防线:集成测试——REST 与 GraphQL 结果必须一致
同一份数据有 REST 和 GraphQL 两套接口,最怕的是"两边返回不一致"。internal/integration/consistency_test.go 专门做这件事:
- 在内存库中插入李白的《静夜思》《将进酒》作为固定测试数据;
- 用
httptest直接调用 REST 路由,同时用 GraphQL 客户端发起查询; - 断言两套接口的总条数、结果条数、逐条 ID 和标题完全一致;
- 再验证分页
hasNextPage、随机诗词接口在相同过滤条件下的行为对齐。
测试全程不启动真实服务器、不落盘,make test一条命令即可复现。
第四道防线:基准测试——正确性之外还要守住性能
简繁转换标称 ~300ns/op,性能回退同样会被 converter_bench_test.go 和 type_bench_test.go 捕捉到。短、中、长、混合四类输入各跑一组基准,覆盖"单句"到"整首多诗"的场景。
一键运行:Makefile 把测试流程固化为四个命令
所有测试入口都固化在 Makefile 中,开发者(或 CI)只需:
make test # 运行全部单元测试 + 集成测试 make coverage # 生成 HTML 覆盖率报告(自动排除 generated 目录) make bench # 运行全部基准测试 make fuzz # 对 classifier 包执行 4 组模糊测试,每组 10s如果想在本地体验完整流程,克隆仓库:
git clone https://gitcode.com/gh_mirrors/ch/chinese-poetry-api总结:四层防线各司其职
| 测试层级 | 回答的问题 | 所在目录 |
|---|---|---|
| 单元测试 | 转换/分类规则对不对? | internal/classifier/ |
| 模糊测试 | 有没有想不到的输入会崩溃? | internal/classifier/ |
| 集成测试 | REST 与 GraphQL 是否一致? | internal/integration/ |
| 基准测试 | 性能有没有回退? | internal/classifier/ |
对普通开发者来说,这套结构也是一份很好的 Go 测试教科书:表驱动测试保证可读性,模糊测试兜住长尾边界,集成测试守护双接口一致性,而 Makefile 让"跑一遍全部测试"的成本趋近于零。
【免费下载链接】chinese-poetry-api📜 诗泉:高性能中国古诗词 API 服务项目地址: https://gitcode.com/gh_mirrors/ch/chinese-poetry-api
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考