测试不等同于调试,各自都有自己的概念集和方法论。
Test:examine input/output pairs.
调试:定位,修改。
但如果能做到错误异常的准确定位,调试的一半以上的工作已经完成了。
测试共分两种:
- unit testing(单元测试)
- functions
- classes
- integration testing(集成测试)
- overrall program
Test suite(测试集):small enough so that we can test it in a reasonable amount of time, large enough to boost confidence.
debug 的方法:(准确地说应叫 bug 的定位)
二分搜索 + 打印中间值(逐步缩小搜索空间)
每一个函数,无论是普通函数,还是类内成员函数,都是为实现某一功能进行实现,当独立地完成一个函数的设计时,应当编写相应的主调函数,去验证函数的基本功能是否实现,当然若为追求更高的鲁棒性,还应考虑一些常见的非法输入等问题,此外还有内聚性、耦合性等等的要求。
防止错误越积越多,最终难以确定程序出错的源头。
1. 断点与单步
是查找程序中的一些运行时的逻辑错误;
这种错误不易察觉,程序编译运行均可通过,只是最终得到的结果,未必是一种期待的结果,或者说未必是正确的结果。
为避免此类错误:
- 第一,不放从头至尾通读代码、检查代码,就像考试时,最后的检查时间,检查计算是否正确,是否犯了一些低级错误;
- 第二,则是回溯而上,直至找到错误的源头;
- 第三,则是单步追踪,顺流而下,找到开始出错的地方。
2. 区分 debug 模式和 release 模式
两种模式下,代码实现和规模是不同的。
debug 模式,调试成功时,可以将一些 debug 的代码注释掉(而不是完全删除),使其进去 release 模式:
if 0,
assert( ... );
end
3. log
一段复杂、庞杂的代码,仅仅给出最终的结果,在 debug 阶段是十分不够的,而应该在某些程序执行的关键地方,给出必要的日志信息,也即 log 信息。