利用代码分析工具
自从走上编程之路,测试的价值就深深地灌入软件开发人员的脑海中了。近年来,单元测试、测试驱动开发、敏捷方法的崛起见证了对在所有开发阶段进行测试的兴趣的激增。然而,测试只是改进代码质量的诸多方法中的一种。
穿越时间的迷雾,追溯到C语言还是新事物的年代,CPU时间和任何种类的存储都很昂贵。考虑到此,第一代的C语言编译器通过移除一些语法分析进行了代码的简化。这意味着编译器只检查了可以在编译时期检测的bug的中的一小部分。为了弥补这些,Stephen Johnson写了一个叫做lint的工具,它实现了一些在其姐妹编译器中被移除了的静态分析。然而,静态分析工具却因给出大量的误报的警告或者不总必需遵循的转换风格的警告而出名。
现在的语言、编译器和静态分析工具已经大不相同了。内存和CPU现在也相对便宜了,于是编译器可以检测更多的错误了。每种语言都至少有一个工具检查变换风格、常见陷阱,有时运行时的错误很难捕捉,比如解引用空指针。更精巧的工具,比如C语言的Splint和python的Pylint,是可配置的,意味着你可以通过一个配置文件、命令行开关、或者IDE选择提示哪些错误和警告。Splint甚至可以让你注解代码,以给出程序如何运行的更好的提示。
如果你要查找编译器、IDE或者lint工具不能捕捉到的错误,然而又没有其它办法时,你可以开发自己的静态检查工具。这并不像听起来那么难。大多数语言,特别是标榜“动态”的语言,将他们的抽象语法树和编译工具做为了其标准库的一部分。了解你所使用的语言的标准库中开发团队使用的“卫生死角”总是值得的,因为它们通常包含可用于静态分析和动态测试的实用技巧。例如,python标准库中包含一个反汇编器,它可以告诉你生成编译代码或者目标代码的二进制代码。听起来像是python开发团队中的编译器编写者使用的晦涩难懂的工具,但它在日常情形中也非常有用。这个工具可以反汇编的一个东西是你的最后的堆栈跟踪,可以反映出二进制指令最后抛出的没有捕获的异常。
因此,不要让测试成为你的最终质量保证,引用分析工具,并大胆开发你自己的。