当前时间: 1970-01-01 08:00:00
分类:办公文件
评论(0)
为什么软件测试很难,以及如何修复1. 软件测试真正难在哪里
1.1 状态空间巨大,无法“穷尽测试”
- 变量状态、内存状态、线程调度、网络顺序、磁盘行为都会影响结果。
- 分布式系统中,不同节点之间事件发生的顺序本身就是关键状态。
- 用启发式方法找到高价值、低概率、但破坏性极强的 bug。
1.2 非确定性让 bug 难以复现
- 多线程、计时器、网络、磁盘、操作系统调度、硬件延迟都会引入非确定性。
- 模糊测试和随机测试难以基于历史结果继续优化探索路径。
1.3 真实系统往往是交互式的
- 很多系统不是“输入一次、运行一次、输出一次”的模型。
- 数据库、Web 服务、游戏、操作系统、分布式系统都需要持续交互。
2. 从示例测试到性质测试
2.1 示例测试依然非常有效
- 好的类型系统与少量示例测试结合,常能产生“扣合式”的验证效果。
2.2 基于性质测试的核心思想
- 不再只写固定输入输出样例,而是定义系统应始终满足的性质。
- 插入 N 个元素、删除 M 个元素后,剩余数量应为 N 减 M。
2.3 模糊测试的独特贡献
3. 确定性仿真:复杂系统测试的关键杠杆
3.1 FoundationDB 的经验
- FoundationDB 能快速构建复杂分布式数据库,很大程度依赖确定性仿真框架。
3.2 传统确定性方案的局限
- 依赖注入可以替换时间、网络、磁盘等非确定性接口,但需要大量工程纪律。
3.3 Antithesis 的核心路径
- 更底层的做法是:在 hypervisor 层构造一个确定性的虚拟计算机。
- 通过内存页去重和 copy-on-write,系统可高并发探索大量分支状态。
4. 如何定义“正确”:性质、观测与不变量
4.1 不必一开始完整形式化系统
- 但对于数值精度、交易策略、业务规则等细粒度正确性问题,仍需明确性质。
4.2 从观测系统中提取测试性质
- 生产环境中的监控和告警,本质上已经是一种性质定义。
4.3 推测性性质也有价值
- 如果某个参数在大量运行中总是为正,可以尝试把“它应为正”作为推测性性质。
- 即使它不是真正的不变量,打破它也往往会引导测试进入有趣状态。
5. AI 编程时代,验证成为新瓶颈
5.1 写代码变快后,验证变成限制因素
- 但如果无法快速判断代码是否正确,整体开发速度仍然受限。
5.2 AI Agent 容易“优化指标而非解决问题”
- 当 AI 被放进“测试不通过就继续改”的循环时,可能出现类似 Goodhart 定律的问题。
- 强验证系统很重要,但也必须避免把模型推向“投机取巧”。
5.3 测试无法替代架构
- 未来工程能力的核心之一,是设计能安全容纳“不那么可靠代码”的架构边界。
6. 测试策略应是工具组合,而非单一信仰
6.1 不同方法适合不同问题
6.2 最优策略是“把能用的都用上”
- 由于软件验证接近不可判定问题,不存在万能测试方法。
- 测试基础设施的目标,是让验证像自来水一样便宜、自然、随手可用。
7. 工程组织与测试文化
7.1 测试是被低估的高杠杆领域
7.2 高信任组织能降低协作成本
- 低层级、高密度、高信任的环境,能显著降低内部交易成本。
7.3 文化需要有意识地维护
- Chesterton’s fence 式思维很重要:不要轻易拆掉看似奇怪但可能承载文化的制度。
8. 实践启发
- 对依赖方进行“bugification”测试:让系统在测试中偶尔表现出合法但极端的行为。
- 不要把所有验证责任交给 AI 或测试框架;架构质量仍然是长期可靠性的基础。
- 测试基础设施越强,团队越敢做深层重构与高风险创新。
- 真正优秀的测试系统,不只是找 bug,而是扩大工程团队的安全速度边界。
基本
文件
流程
错误
SQL
调试
- 请求信息 : 2026-06-24 22:55:19 HTTP/1.1 GET : https://www.yeyulingfeng.com/a/785992.html
- 运行时间 : 0.189811s [ 吞吐率:5.27req/s ] 内存消耗:4,654.30kb 文件加载:145
- 缓存信息 : 0 reads,0 writes
- 会话信息 : SESSION_ID=0dab3e4bc17b2625897dc9ea927e18e8
- CONNECT:[ UseTime:0.000943s ] mysql:host=127.0.0.1;port=3306;dbname=wenku;charset=utf8mb4
- SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.001408s ]
- SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.000661s ]
- SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.000620s ]
- SHOW FULL COLUMNS FROM `set` [ RunTime:0.001514s ]
- SELECT * FROM `set` [ RunTime:0.000571s ]
- SHOW FULL COLUMNS FROM `article` [ RunTime:0.001460s ]
- SELECT * FROM `article` WHERE `id` = 785992 LIMIT 1 [ RunTime:0.001169s ]
- UPDATE `article` SET `lasttime` = 1782312919 WHERE `id` = 785992 [ RunTime:0.001574s ]
- SELECT * FROM `fenlei` WHERE `id` = 64 LIMIT 1 [ RunTime:0.000748s ]
- SELECT * FROM `article` WHERE `id` < 785992 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.001378s ]
- SELECT * FROM `article` WHERE `id` > 785992 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.001293s ]
- SELECT * FROM `article` WHERE `id` < 785992 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.001880s ]
- SELECT * FROM `article` WHERE `id` < 785992 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.001915s ]
- SELECT * FROM `article` WHERE `id` < 785992 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.002174s ]
0.193240s