安全起见,我们仍然修改了所报告的问题以排除任何可能影响它的实际应用执行的风险。在修改代码的同时,我们同时也引入了回归测试,当我们再次运行单元测试时立即被检测到。在所有的自动化错误检测方法中,回归测试是唯一能够帮助我们检查到代码是否发生了功能性的改变的方法,并且能验证出对代码进行的修改是否引入了功能性的错误以及不可预知的副作用。最后,我们修改了回归测试套件,并重新测试代码,发现一切运行正常。
正如读者所见,我们使用的一切测试方法——基于模式的静态代码分析、内存分析、单元测试、数据流分析以及回归测试——并不是相互竞争的关系,恰好相反,它们是一种互补的关系。将上述工具结合使用,它们就是一套具有强大作用的工具集,并为嵌入式C语言程序/软件提供一个无可比拟的自动化错误检测解决方案。
总而言之,通过自动地查找很多关于内存和其它编码的缺陷,我们成功地让程序运行起来了。尽管如此,值得注意的是,最危险的缺陷却是实际的功能性错误:例如程序并未如所指定的要求运行。而不幸的是,这些错误往往是非常难以被发现的。
查找这类缺陷的最好的一个方式就是通过同行代码审查来实现。即另指派至少一人来检查代码并且审查代码与需求内容的一致性,这样用户就能对实际程序是否会如预期那样运行有一个很好的*估。
另外一个十分有用的策略是围绕代码创建一个回归测试套件,这能帮助用户快捷地验证代码与规范的一致性。在本文所描述的示例情景中,单元测试被用来强制执行应用程序级的运行时内存监测所未覆盖到的代码:它能覆盖到当前程序的功能性,在此之后,我们对代码做了一些修改,它能提醒我们代码出现的相应的功能性问题。事实上,这种单元测试用例应该被更早地创建起来:理想情况下,当用户在实现程序的功能时就应该被创建起来。这样,用户就能得到更高的覆盖率并同时构建起一个更强壮的“安全网”来捕捉关键的功能性改变。