Edebug 提供基础的覆盖度测试与执行次数统计显示功能。
覆盖度测试通过对比每个表达式的当前结果与上一次结果来工作: 在当前 Emacs 会话中开始覆盖度测试后,如果某个表达式返回过两种不同的值,就认为该表达式已被覆盖。 因此,要对你的程序进行覆盖度测试,需要在多种条件下运行它,并观察行为是否正确; 当你尝试了足够多的不同条件,使得每个表达式都返回过两种不同的值时,Edebug 会提示你。
覆盖度测试会降低执行速度,因此只有在 edebug-test-coverage 为非nil 时才会启用。
无论是否启用覆盖度测试,也无论运行模式是否为无间断运行,被插桩函数的所有执行过程都会进行执行次数统计。
使用 C-x X =(edebug-display-freq-count)显示当前定义的覆盖信息与执行次数统计。
直接按 =(edebug-temp-display-freq-count)则临时显示相同信息,直到按下下一个按键。
该命令显示当前定义中每一行代码的执行次数统计数据。
它会在每行代码后以注释行形式插入执行次数。你可以用一次 undo 撤销所有插入。
次数会显示在表达式前的左括号 ‘(’、表达式后的右括号 ‘)’ 下方,或变量的最后一个字符下方。
为简化显示,如果某表达式的次数与同一行上更早表达式的次数相同,则不重复显示。
表达式次数后面的字符 ‘=’ 表示:该表达式每次求值都返回相同的值。 换句话说,从覆盖度测试角度看,它尚未被覆盖。
要清除某个定义的执行次数与覆盖度数据,只需使用 eval-defun 重新插桩即可。
例如,在设置源码断点并执行 (fac 5),且将 edebug-test-coverage 设置为 t 后,
当断点触发时,执行次数数据如下所示:
(defun fac (n)
(if (= n 0) (edebug))
;#6 1 = =5
(if (< 0 n)
;#5 =
(* n (fac (1- n)))
;# 5 0
1))
;# 0
这些注释行表明 fac 被调用了 6 次。
第一个 if 语句返回了 5 次,且每次结果都相同;
第二个 if 的判断条件也是如此。
对 fac 的递归调用则完全没有返回。