COBOL 的发明者,被认为观察到第一个计算机 Bug——字面意义的Bug,一只飞进早期计算机系统中的蛾子。当被要求解释那台机器为什么不能正常工作时,技术人员报告“在系统中发现了一只 Bug”,并且很尽职地把它订在了记录本中,包括翅膀等所有部分
在团队中因为bug引发的争论数不胜数,特别是那种远程沟通协作的时候。
bug的人是程序员,负责测试的同事在项目收尾阶段会负责找出bug。我们来看下面一个场景。
Andy 曾经开发过一个大型的图形应用程序。临近发布的时候,测试人员报告说,每当他们用一个特定的笔刷画一笔时,应用程序就会崩溃。负责的程序员辩称没有任何问题;他试过用它画画,一切正常。这种对话来回了好几天,彼此的火气很快被带起来了。 最后,我们把他们聚在一个房间里。测试人员选择笔刷工具,从右上角到左下角画了一笔——程序崩了。“哦,”程序员小声说,然后不好意思地承认,他只是从左下角到右上角测试了一下,当时没有暴露出这个 Bug。 这个故事有两个要点: · 你可能需要拜访报告 Bug的用户,这样才能收集到比最初提供的更多的数据。 · 人为的测试(例如程序员从下到上画线)对应用程序的测试而言还不够。你必须粗暴地测试所有边界条件,并且复原实际的最终用户使用模式。你需要有系统地做这些事情。
程序不会出错,你的同事也不会故意撒谎,面对测试报告,我们要做的就是相信。在修复bug之前,我们需要先复现bug。而想要快速的复现bug,需要在调试前获取更多的信息。现在很多bug报告,还附带复现视频,这大大减少了修复的时间。
复现bug之后,第一件事情就是去看日志。大部分问题都能从日志中找到原因,如果遇到很复杂的问题,需要根据上下文来判断问题原因。然后通过调试来确认出错位置。这里推荐一个二分查错法。
普通用法,通过手动修改某个数据,来判断某个方法是否有问题,如果有,那就是方法内的问题,没有就是方法外的问题。通过层层二分,缩小问题范围。
进阶使用,版本回退。上一个版本运行好好的,怎么今天突然出问题了。直接回退看bug是否复现,没有出现,对比两个版本的代码,新问题是新的代码引起的,然后在调试确认具体哪一部分代码出的问题。
如果你实在是找不到bug原因,还有个简单的方法可以尝试。向另一个人或物解释代码。对方不需要反馈,这一简单的做法常常能让问题跳出屏幕来暴露自己。这听起来很简单,但是在向另一个人解释这个问题时,你必须明确地陈述自己检查代码时可能认为理所当然的事情。通过把这些假设用语言表达出来,你可能会突然对这个问题有了新的认识。
还有一种场景是”我就改了一个东西,然后系统就不工作了。“这类的bug一般都是一个或多个全局文件变更导致,比如升级了某个第三方库,更换了操作系统。这种变更会导致整个系统所有功能都需要测试一遍,一般会留在大的版本里做升级。
最后,程序不会说谎,人才会犯错。承认问题,才能解决问题。