[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fnquybQ2TuEkkK46FH2xJuXe-ILvAFPTqUMSPtgaLG1E":3},{"item":4,"related":51},{"id":5,"type":6,"title":7,"slug":8,"summary":9,"body":10,"coverUrl":11,"productScreenshots":12,"productLinks":13,"authorName":14,"authorUrl":15,"authorSubject":16,"category":17,"tags":22,"sourceLabel":39,"sourceName":40,"sourceUrl":41,"status":42,"seoTitle":43,"seoDescription":44,"canonicalUrl":45,"isFeatured":46,"sno":47,"sortOrder":48,"publishedAt":49,"updatedAt":50,"createdAt":50},"9ad033ff-1bd4-49bd-b843-635ae2c48eaa","article","Property-based Testing：不要只测试几个例子","property-based-testing-ai-coding","性质测试通过描述输入输出应保持的规律，自动生成大量边界样本，帮助发现 AI 生成代码中隐藏的错误。","## Property-based Testing：不要只测试几个例子\n\n传统测试通常这样写：输入 3 和 5，期待结果是 8；输入空列表，期待结果是空列表。Property-based Testing，性质测试或基于性质的测试，则先描述一条应该对大量输入成立的规则，再让工具自动生成输入，包括人类容易忽略的边界情况。\n\n## 从“答案”换成“性质”\n\n以排序函数为例，单个例子只能说明 `[3, 1, 2]` 被排成了 `[1, 2, 3]`。性质测试可以描述：排序结果长度不变；结果仍包含原来的元素；从前到后不下降。工具会生成很多不同长度、重复值、负数和极端值的列表，尝试寻找违反性质的输入。\n\n这并不意味着测试可以不写预期结果。它只是把预期从一个具体答案改成一组更稳定的关系。对于数据转换、编码解码、权限判断和数学函数，这种表达方式往往比手工堆叠样例更有覆盖面。\n\n## AI 生成代码为什么适合这种测试\n\n模型很容易生成“看起来完整”的样例，但样例数量有限，且可能和实现共享同一个错误假设。性质测试迫使我们先问：这个函数无论输入怎样，都应该保持什么不变量？AI 可以帮助提出候选性质，再由人确认性质本身是否正确。\n\n它也适合测试 AI 生成的边界处理。比如分页函数应满足页码变化不丢数据，序列化再反序列化应保留关键字段，权限过滤不应因为输入顺序改变而放宽。测试框架负责大量试探，开发者负责定义真正重要的关系。\n\n## 性质写错了怎么办\n\n性质测试不是自动证明。如果性质过于宽松，错误实现仍可能通过；如果性质描述了错误的业务规则，测试反而会阻止正确功能。还要注意随机输入需要保存失败样本，以便把偶发失败变成稳定回归测试。\n\n## 适合从哪里开始\n\n优先选择有清晰不变量的纯函数、解析器、转换器和排序过滤逻辑。让 AI 先列出输入空间、核心性质和可能的反例，再由你确认后生成测试。这样，AI 的价值不只是写更多测试，而是帮助发现“我们到底希望代码永远保持什么”。\n\nPython 生态中的 Hypothesis 对这一思路有完整介绍，可阅读[官方文档](https:\u002F\u002Fhypothesis.readthedocs.io\u002Fen\u002Flatest\u002F)。","\u002Fuploads\u002F2026-09-14\u002Ff5f43a98-2205-40be-b69c-cba464cac309.jpg",[],[],"Foundit","https:\u002F\u002Ffoundit.cn","foundit-ai-editorial",{"id":18,"name":19,"slug":20,"description":21},"6179d3b6-dc34-4483-9ded-3cd9f1b37a47","科普","abbreviation","介绍各领域新兴概念",[23,27,31,35],{"id":24,"name":25,"slug":26},"0848beb4-db26-4fb8-b391-f852a11be192","AI编程","ai-coding",{"id":28,"name":29,"slug":30},"144abe77-0dc6-4f66-a176-20bddb1c0bfa","编程","coding",{"id":32,"name":33,"slug":34},"63b56667-dcdb-4b8b-bcbe-c405143a7ec2","测评","test",{"id":36,"name":37,"slug":38},"4c2bbea6-eab7-40a8-8447-1de478ff7749","分析","analyse","官方资料","Hypothesis","https:\u002F\u002Fhypothesis.readthedocs.io\u002Fen\u002Flatest\u002F","published","Property-based Testing 是什么？让 AI 自动寻找边界条件","从排序和数据转换例子出发，理解性质测试如何超越少量手写样例。",null,false,43,0,"2026-09-14T00:00:00.000Z","2026-09-14T15:01:45.728Z",[52,61,69],{"id":53,"type":6,"title":54,"slug":55,"summary":56,"coverUrl":57,"authorName":14,"sno":58,"publishedAt":59,"createdAt":60},"88cd83c5-bb5f-411a-85bf-1eefdcacebf4","AI 代码审查能不能替代人类 Code Review","ai-code-review-human-review","AI 很适合做第一轮代码审查，却不一定理解业务语义、风险取舍和变更完整性。本文梳理 AI 审查的强项与盲区，并给出自动检查、AI 建议和人工批准的三层协作方式。","\u002Fuploads\u002F2026-09-13\u002F1ff872e2-ecfe-4bd4-9dd1-327a09a8f6dc.jpg",41,"2026-09-13T00:00:00.000Z","2026-09-13T11:55:47.724Z",{"id":62,"type":6,"title":63,"slug":64,"summary":65,"coverUrl":66,"authorName":14,"sno":67,"publishedAt":59,"createdAt":68},"e958c89d-ebf2-4e02-ad21-b66cf10efa07","AI 写出来的测试靠谱吗？测试通过就代表没问题吗","ai-generated-tests-are-not-proof","AI 可以快速生成测试，但绿色结果只说明当前输入触发了当前断言。本文拆解 AI 测试最常见的遗漏，介绍如何用行为表、真实数据和故障注入判断测试是否真的在保护产品。","\u002Fuploads\u002F2026-09-13\u002F04a1c4c6-4a18-4122-9fb7-e8c237fdee9c.jpg",47,"2026-09-13T11:55:46.344Z",{"id":70,"type":6,"title":71,"slug":72,"summary":73,"coverUrl":74,"authorName":14,"sno":75,"publishedAt":59,"createdAt":76},"7cc644a5-e0de-4d7b-802e-9e8b69677e12","AI 生成的代码会不会复制开源项目","ai-code-open-source-reference-license","AI 生成代码不等于天然没有来源。本文区分常见写法与高相似片段，解释代码引用、许可证、依赖供应链和轻量来源检查，帮助团队把合规当成代码质量的一部分。","\u002Fuploads\u002F2026-09-13\u002F920327ad-de7f-4caa-a2f4-816d467c9f9c.jpg",40,"2026-09-13T11:55:49.911Z"]