EN

程序员的修炼-04-关于测试的一些思考

字数统计: 2.3k阅读时长: 7 min
2018/09/27
loading

本文是 <程序员的修炼-从优秀到卓越> 的读书笔记的第四篇,这本书的作者是 Jeff Atwood,StackOverflow 的创始人之一,Jeff 的文章涉及面很广,他是一个经验老道的程序员、管理者、创业者,这本书谈到了编程之外的很多东西,不管你是初级工程师,还是资深工程师,本书都值得一读。随着你的阅历的增加,每一次重读这本书,都会有不一样的感悟,正如书名“从优秀到卓越”,作者为你指明了道路,至于是否能成功,则要看自己的修炼了。

我会把读书过程中一些精彩的言论摘录下来,有时会加入一些自己的见解或者经历,读书笔记的大纲与书本身的大纲是一致的,这也是我从另外一个地方学到并一直在用的“如何阅读一本书”,记录下来方便自己经常查看,也方便读者查看。下面是<程序员的修炼-从优秀到卓越> 读书笔记系列:

  1. 程序员的修炼-01:绝地反击之术
  2. 程序员的修炼-02:编程之道
  3. 程序员的修炼-03:Web 设计原则
  4. 程序员的修炼-04:关于测试的一些思考
  5. 程序员的修炼-05:了解你的用户
  6. 程序员的修炼-06:互联网那些事
  7. 程序员的修炼-07:游戏与编程
  8. 程序员的修炼-08:阅读之美

阅读说明(2026-10 核查):本文保留 2018 年读书笔记的结构。所读文章写于 2005–2009 年;下面补全硬件案例,并标明旧工具与现代错误处理的区别。


单元测试是必要的

单元测试的价值之一,是迫使你停下来思考怎样验证代码。在 Good Test, Bad Test(2005) 中,Jeff 批评一些开发者只是随意输入数字、点几个按钮,没遇到未处理异常,就认为可以交给测试团队了。原文“大部分开发人员都不做测试”是作者当年的评论,不能当作今天的行业统计;没有异常,也不代表输出和行为正确。

单元测试让你为刚刚写下的代码思考一连串艰难但又不得不思考的问题:

  1. 我该怎样测试这块代码?
  2. 我该执行何种测试?
  3. 通常的情况是怎么样的?
  4. 可能碰到的异常情况有哪些?
  5. 我有多少外部依赖关系?
  6. 我可能碰到哪些系统故障?

补充到今天的实践中,测试还要明确预期结果和断言,覆盖有意义的边界与失败路径;外部依赖之间的协作,可能需要集成测试或端到端测试验证。单元测试不能独自证明整个系统可用。Google 的代码审查指南也要求检查测试是否合适,以及断言是否真的能在行为出错时失败。

有时候是硬件问题

原例出自 Sometimes It’s a Hardware Problem(2006-08-11):一台双 Opteron 250、8 GB 内存的服务器,运行 Windows Server 2003 x64 和 Virtual Server 2005 R2,出现反复重启。更新 BIOS 和驱动解决了一条内存节点相关警告,但没有解决重启。作者用 Memtest86+ 和 Prime95 对照测试,发现 4 GB 配置稳定,8 GB 配置会失败;更偏 CPU 的 small FFT 测试通过,也不能排除内存相关问题。

后来作者把 BIOS 中的内存速度从 200 MHz 调到 166 MHz,Memtest86+ 和 Prime95 blend 测试才通过。这个案例支持继续检查内存配置及其与平台的配合,不能据此断定某根内存条损坏,也不能把一次压力测试通过当作永久稳定的证明。今天排查类似问题,仍应记录硬件、固件、驱动、负载和复现条件,逐项对照;这不是让读者照搬 2006 年的降频参数或直接升级 BIOS。

我们不能总把矛头指向软件,有时候也得回头看看硬件和配置。

异常驱动的开发

开发者需要持续查看系统的异常和错误报告,不能只等用户投诉;用户反馈同样是重要的信息来源。Jeff 在 Exception-Driven Development(2009-04-16) 中介绍,Stack Overflow 当时使用的是定制版 ELMAH。这是历史记录,不代表它今天的生产配置。原 ELMAH 1.2 SP2 面向 .NET Framework 上的 ASP.NET,通过 HTTP modules/handlers 接入,不能把这套配置直接套到 ASP.NET Core。

作者当时用“修复用户永远不会碰到的 bug 是否值得”讨论时间投入,但我们通常无法仅凭没有报告,就断定问题永远不会发生。原文也明确支持测试驱动开发,并认为两者可以并用。测试用于验证预期行为,线上反馈帮助发现测试环境没覆盖的情况;二者不能互相替代。

原文建议根据线上异常反复改进。结合今天的实践,可以把这套反馈过程补充为:

  1. 完成与改动相关的测试和审查,再按产品风险控制发布范围。
  2. 结合异常、错误率、延迟和用户反馈定位问题,记录版本、发生条件和影响范围。
  3. 按严重程度和影响排序,做必要的修复,并补回归测试;原文的“最严重 3 个”是迭代示例,不要求每次都重新架构。
  4. 发布后检查用户可见的结果是否改善,再继续迭代;日志减少本身不能证明问题消失。

异常日志只是其中一种信号。返回了错误内容、请求过慢,甚至 HTTP 200,都可能对应用户可见的失败;统计错误时还要结合请求量看错误率。Google SRE 的监控章节把延迟、流量、错误和饱和度作为四类重要信号。反馈能帮助改进系统,但不能保证几个迭代后就“坚如磐石”。

版本补充:ASP.NET Core 10 / .NET 10。 官方错误处理文档介绍了异常处理中间件和 IExceptionHandler。从 .NET 10 起,TryHandleAsync 返回 true 的已处理异常,默认会抑制中间件的日志、指标等诊断输出;.NET 8/9 的默认行为不同,可用 SuppressDiagnosticsCallback 调整。因此升级后要核对诊断策略,不能把没有日志理解成没有错误。开发者异常页仅用于 Development 环境,可能含堆栈、查询参数、Cookie 和请求头;生产环境不要公开这些诊断细节,集中日志也应限制访问。


以下保留当年摘录的豆瓣简介,其中访问量等描述属于历史资料,并非 2026 年统计。

《程序员的修炼——从优秀到卓越》是《高效能程序员的修炼》的姊妹篇,包含了Coding Horror博客中的精华文章。全书分为8章,涵盖了时间管理、编程方法、Web设计、测试、用户需求、互联网、游戏编程以及技术阅读等方面的话题。作者选取的话题,无一不是程序员职业生涯中的痛点。很多文章在博客和网络上的点击率和回帖率居高不下—— from 豆瓣

Jeff Atwood于2004年创办Coding Horror博客(.codinghorror.),记录其在软件开发经历中的所思所想、点点滴滴。时至今日,该博客每天都有近10万人次的访问量,读者纷纷参与评论,各种观点与智慧在那里不断激情碰撞 —— from 豆瓣

《程序员的修炼——从优秀到卓越》的写作风格风趣幽默,且充满理解和关怀;适合从新手到老手的各个阶段的程序员阅读,也适合即将成为程序员的计算机和相关专业的学生阅读。《程序员的修炼——从优秀到卓越》能够帮助读者更多地关注技术工作的人性和人文因素,从而实现程序员职业生涯的成功转折 —— from 豆瓣

关于我 && 博客

下面是个人的介绍和相关的链接,期望与同行的各位多多交流,三人行,则必有我师!

  1. 博主个人介绍 :里面有个人的微信和微信群链接。
  2. 本博客内容导航 :个人博客内容的一个导航。
  3. 个人整理和搜集的优秀博客文章 - Android 性能优化必知必会 :欢迎大家自荐和推荐 (微信私聊即可)
  4. Android性能优化知识星球 :付费社群已于 2026 年停止运营,不再招收新成员;此处保留历史介绍。

一个人可以走的更快 , 一群人可以走的更远

微信扫一扫

CATALOG
  1. 1. 单元测试是必要的
  2. 2. 有时候是硬件问题
  3. 3. 异常驱动的开发
  • 关于我 && 博客