《Effective Debugging:软件和系统调试的66个有效方法》一第11条:修改完代码之后,要能够尽快看到结果

第11条:修改完代码之后,要能够尽快看到结果

调试通常是一种循序渐进的过程。在每一轮中,我们都要花时间去构建并运行软件,而且要看着它发生故障,这些环节会占用很多时间,而且这些时间并没有用来解决软件中的问题。因此,我们要提前进行准备,设法缩短每一轮调试所花费的时间。
首先从软件的构建入手。我们应该能通过一条命令(如make或mvn compile)或一个按键(如F5)把发生故障的软件迅速构建出来。构建过程应该能够记录文件之间的依赖关系,使得我们在修改了某处代码之后只有少数几个文件需要重新编译。能够达到这种效果的构建工具包括make、Ant及Maven。
高效地部署与运行软件也是相当重要的,然而各个项目的具体实现方式有很大的区别。我们可能要在远程主机上面部署文件、要重启应用程序服务器、要清除缓存,或要重新初始化某个数据库,为此,可以使用项目的构建系统,或编写一些脚本来自动执行该流程(参见第12条)。如果安装软件之前需要花很长时间来对分配文件进行构建,而且软件安装得也比较慢,那么可以考虑设置一种快捷的安装途径,使得我们只需把改动之后的那些文件复制到适当的位置即可。
最后,要确保软件能够尽快暴露出故障(参见第55条)。如果发生故障的代码可以进行单元测试,或是可以放在回归测试框架中进行测试,那就构建一个能够展示故障的测试用例(参见第10条),然后通过采用IDE或测试环境所提供的特性来运行这个测试用例。例如,如果代码是用Maven来管理的,那么可以通过下面这条命令来运行名为TestFetch的用例:

如果要调试的程序在处理某个特定的文件时会发生故障,那就构建一个能够引发该故障的最简文件。为了重现GUI应用程序中的问题,我们可以通过软件自动化应用程序来完成,例如,适用于网页浏览器的Selenium、适用于Windows系统的AutoHotkey、适用于OS X系统的Automator,以及适用于Linux系统的AutoKey。
要点
设法在修改代码之后尽快看到其结果,以提升调试的效率。
配置一套快速的自动化构建及部署流程。
测试软件时,要令其尽快地将故障暴露出来。

时间: 2024-08-30 05:53:01

《Effective Debugging:软件和系统调试的66个有效方法》一第11条:修改完代码之后,要能够尽快看到结果的相关文章

《Effective Debugging:软件和系统调试的66个有效方法》——第11条:修改完代码之后,要能够尽快看到结果

第11条:修改完代码之后,要能够尽快看到结果 调试通常是一种循序渐进的过程.在每一轮中,我们都要花时间去构建并运行软件,而且要看着它发生故障,这些环节会占用很多时间,而且这些时间并没有用来解决软件中的问题.因此,我们要提前进行准备,设法缩短每一轮调试所花费的时间. 首先从软件的构建入手.我们应该能通过一条命令(如make或mvn compile)或一个按键(如F5)把发生故障的软件迅速构建出来.构建过程应该能够记录文件之间的依赖关系,使得我们在修改了某处代码之后只有少数几个文件需要重新编译.能够

《Effective Debugging:软件和系统调试的66个有效方法》——第18条:从自己的桌面计算机上调试那些不太好用的系统

第18条:从自己的桌面计算机上调试那些不太好用的系统 Jenny和Mike在谈论各自的调试经历.Jenny说:"我不喜欢在客户的计算机上面工作,要用的工具都没装,浏览器里也没有我收藏过的书签.这真是太麻烦了.我访问不了自己的文件,计算机上的按键绑定和快捷键,设置得也都不对."Mike惊讶地看着她说:"快捷键?你还有快捷键可用,这都算不错的了.我调试的那台计算机,连键盘都没有!" 如果你在工作时无法使用自己配置好的这台计算机,那么工作效率确实会大幅降低.除了Jenny

《Effective Debugging:软件和系统调试的66个有效方法》——第7条:试着用多种工具构建软件,并将其放在不同的环境下执行

第7条:试着用多种工具构建软件,并将其放在不同的环境下执行 有时我们可以通过改变环境来锁定一些难以捕获的bug.例如,我们可以用另外一款编译器来构建这个软件,也可以切换到其他的运行时解释器.虚拟机.中间件.操作系统或CPU架构上.由于那些环境可能会更加严格地检查输入数据,或能通过其结构来凸现程序中的错误(参见第17条),因此可以帮助我们发现原来很难找到的一些bug.如果程序不够稳定.总是发生无法重现的崩溃问题,或移植起来不太顺利,那就应该试着把它放在另外一种环境下进行测试,这使得我们能够使用更为

《Effective Debugging:软件和系统调试的66个有效方法》——第8条:把工作焦点放在最为重要的问题上

第8条:把工作焦点放在最为重要的问题上 许多大型软件系统都含有数量极其众多的bug(有一些是已知的bug,还有一些则尚未发现).要想高效地进行调试,就必须把应该受到关注的bug与可以忽略的bug明智地区分开.这样做不是为了单纯地缩减事务清单中的未决事务,而是为了帮助我们开发出稳定.易用.可维护而且效率较高的软件,毕竟这才是公司给我们支付薪水的原因.为此,我们要通过事务追踪系统来设定各项事务的优先级(参见第1条),从而使自己能够把工作重心汇聚在优先级较高的那些事务上,并把优先级较低的事务忽略掉.下

《Effective Debugging:软件和系统调试的66个有效方法》——第15条:查看第三方组件的源代码,以了解其用法

第15条:查看第三方组件的源代码,以了解其用法 我们所要调试的代码之所以会出bug,通常并不是由于它使用的第三方程序库或应用程序本身有问题(参见第14条),而是因为它使用这些第三方组件时所采取的方式有误. 这种情况并不令人惊讶,由于这些软件本身是作为黑盒来与你所写的代码进行集成的,因此,你不太可能在它们之间相互协调.对于这类问题来说,有一个很有用的办法,就是去查看第三方程序库.中间件甚至是底层软件的源代码. 首先,如果想查明某个API为什么没有像你所期望的那样运作,或是想查明某条奇怪的错误消息是

《Effective Debugging:软件和系统调试的66个有效方法》——第6条:使用软件自身的调试机制

第6条:使用软件自身的调试机制 程序是一种很复杂的东西,因此它们通常都包含内置的调试机制.(至于怎样给自己正在开发的软件里面添加这样的机制,请参见第40条.)这种机制有很多好处,其中包括: 我们可以通过禁用后台执行或多线程执行等特性来简化程序的调试工作. 我们可以有选择地执行其中某一部分功能,以便通过测试用例来精确地再现相关的故障. 程序可以给我们提供与性能有关的报表及其他信息. 程序可以把更多的信息记录在日志文件中. 因此,我们应该花一些时间,看看自己要调试的这款软件内置了哪些调试机制.想要了

《Effective Debugging:软件和系统调试的66个有效方法》——第12条:将复杂的测试场景自动化

第12条:将复杂的测试场景自动化 我们可以用脚本对复杂的测试场景进行自动化.自动化的方式有很多种.如果是要对处理流程与文件进行编排,那么可以考虑Unix shell所提供的大量实用工具(参见第22条).此外,通过能够获取URL的curl命令,以及能够解析JSON数据的jq命令,我们还可以用shell来测试Web服务.对于牵涉API访问及状态维护等事宜的复杂场景来说,我们可以求助于功能更为丰富的脚本语言,如Python.Ruby或Perl,另外,还有很多系统会内置它们自己的脚本语言,如Apache

《Effective Debugging:软件和系统调试的66个有效方法》——第5条:在能够正常运作的系统与发生故障的系统之间寻找差别

第5条:在能够正常运作的系统与发生故障的系统之间寻找差别 我们通常都能够同时访问这样两个系统,其中一个是发生故障的系统,另一个是与之相似但却可以正常运行的系统.当我们实现了某项新功能.更新了某些工具或基础组件,或是把系统部署在某个新的平台上面时,就可能会遇到新系统无法正常运行的问题,此时如果旧系统依然正常,那么我们通常可以通过寻找(下面就会讲到如何寻找)或尽量缩小(参见第45条)新旧两个系统之间的差别来锁定问题的原因. 之所以能根据新旧系统间的差距来进行调试,其原因在于:尽管各人所经历的问题有所

《Effective Debugging:软件和系统调试的66个有效方法》——第10条:高效地重现程序中的问题

第10条:高效地重现程序中的问题 要想高效地调试程序问题,一个关键的因素就是要能够可靠且方便地重现它.这么说有三个理由.首先,如果我们总是能做到只按一个按钮就可以重现问题,那么自然能够专心地去寻找问题的原因,而不用再浪费时间去研究怎样才能把这个问题重现一遍.第二,如果我们可以方便地重现问题,那么也就能够同样方便地把问题描述出来,以寻求外人的帮助(参见第2条).第三,修复错误之后,我们可以把重现问题所需的步骤执行一遍,如果程序这次没有出现故障,那就证明我们对其所做的修复是正确的. 创建短小的范例或

《Effective Debugging:软件和系统调试的66个有效方法》——第19条:使调试任务自动化

第19条:使调试任务自动化 我们或许会找到很多个与程序错误有关的因素,但是却没有办法轻易推断出究竟哪一个因素才是致使程序出错的真正原因.为了把这个原因找出来,我们可以编写一小段例程或脚本,把有可能使程序出错的所有情况全都搜索一遍.如果待搜索的情况比较多,不便于手工进行搜索,但是却能够通过循环来进行遍历,那么就可以考虑对其加以自动化.例如,如果想遍历的是500个字符,那么可以通过自动化的脚本来实现,然而如果要把用户可能会输入的所有字符串全都尝试一遍,那么采用自动化脚本就不太合适了. 下面举一个例子