作者提出用AI生成对抗性输入进行属性测试,发现传统测试未覆盖的边界case,比阅读第三方基准报告更能直接提升代码质量。
三周前,我看到一位同事花了 40 分钟阅读一份供应商的基准测试报告,又花了 20 分钟向团队解释为什么那些数字不适用于我们的代码库。同一周,我们配置解析器中一处两行代码的改动悄悄引入了一个日期格式边界情况的 bug,没有任何测试覆盖到。这两件事之间的关联就是本文的核心论点:免费模型 token 与其用来跑别人模型的基准测试,不如用来为自己的代码生成对抗性输入。
基准测试回答的是一个你早已知道答案的问题:模型比上一个版本更好还是更差。而模糊测试回答的是一个你确实不知道答案的问题:你的代码在哪些你从未想到要测试的地方会出问题?前者是购买决策;后者是 bug 发现决策。免费 token 让第二种变成一种习惯。
属性测试(Property-based testing)的思路是:不去写特定的输入输出对,而是声明一个不变量,然后让生成器产生数百个必须满足该不变量的输入。经典例子:如果你写了一个解析 ISO 日期字符串的函数,不变量就是「解析后再重新序列化应该返回原始字符串」。生成器会找到 2026-02-30 这种情况、24:00:00 这种情况,以及你手工测试漏掉的时区偏移情况。
编码 Agent 很擅长在你给出不变量的前提下写出属性声明。它们更擅长生成对抗性输入。瓶颈不在于模型生成测试用例的能力,而在于你能否在不按次付费的情况下运行足够多的测试。这正是免费 token 层级解决的问题。
MonkeyCode 是一个开源项目,目前提供 1000 万 token 的免费额度和免费服务器选项,足够在真实仓库上运行下面的属性测试循环。声明:本文是作为 MonkeyCode 产品推广的一部分撰写的。
工作流很简单:你写属性,Agent 生成测试 harness,免费额度运行迭代,直到找到反例或耗尽预算。
下面的设置使用 Python 的 Hypothesis,但模式可以迁移到 Rust 的 QuickCheck、JavaScript 的 fast-check 或任何其他属性测试库。关键是 Agent 写属性,你提供不变量。
# property_fuzz.py — run with: python property_fuzz.py
from datetime import datetime, timedelta
from hypothesis import given, strategies as st, settings, Phase
# The invariant: parsing then re-serializing must round-trip.
@given(st.datetimes(min_value=datetime(2000, 1, 1), max_value=datetime(2030, 12, 31)))
@settings(max_examples=5000, phases=[Phase.generate, Phase.reuse, Phase.shrink])
def test_round_trip(dt: datetime) -> None:
serialized = dt.isoformat()
reparsed = datetime.fromisoformat(serialized)
assert reparsed == dt
if __name__ == "__main__":
test_round_trip()
Agent 的工作是将这个扩展为你实际代码的完整测试套件:解析你的配置格式、序列化你的 API 响应、验证你的用户输入。你提供不变量;Agent 提供生成器。免费额度运行这个循环。
根据我运行这个模式的经验,三种不变量类型发现的真实 bug 比其他所有加起来还多。Round-trip 不变量检查序列化和反序列化是否是互逆的。幂等性不变量检查执行两次操作是否与执行一次产生相同结果。排序不变量检查排序、过滤和去重是否保留了你业务逻辑所依赖的属性。
每一种都是一个人类可以在几秒钟内陈述的句子属性。Agent 将其转化为一百行生成器代码。免费 token 将这些代码转化为数千次执行的例子。
并非每个代码库都能从属性模糊测试中同等受益。用这张表来决定免费额度首先在哪里产生回报。
从高价值行开始。在日期处理模块上花一个下午做属性模糊测试,发现的真实 bug 比花一周阅读 Agent 基准表格更多。
属性模糊测试不能替代集成测试、安全审计或负载测试;它只发现特定类型的逻辑 bug,对其他问题一概漏掉。如果你的代码库没有现有测试套件,先写基本的单元测试,因为属性测试需要基线来构建。如果你的团队没有人能清晰陈述不变量,Agent 会生成技术上正确但实际毫无用处的属性。免费额度配额和服务器选项可能会变动,因此在围绕它们构建工作流之前请核实当前条款。在安全关键系统上工作的团队应将模糊测试输出作为人工审查的起点,而不是正确性的保证。
对编码 Agent 最诚实的评估不是基准分数,而是 Agent 在你自己的仓库中帮助你发现的真实 bug 数量。免费 token 使这种评估变得零成本,这意味着唯一剩下的成本就是你花时间写下不变量的那一小时。如果你想知道你的配置解析器隐藏了多少边界情况,上面的属性测试循环会告诉你答案;MonkeyCode 的免费额度是一种低风险的方式来运行它。