我想编写一个测试(使用clojure.test
)来验证某些示例代码不会导致无限循环。如果我测试的代码有错误并导致无限循环,我希望测试工具报告失败 - 而不是直接断开和循环。 (我假设有一种不会溢出堆栈的无限循环。)
任何想法如何做到这一点?
答案 0 :(得分:4)
这相当于解决halting problem,这是不可能的。
答案 1 :(得分:4)
当然,在一般情况下你不能做到这一点,如果你有兴趣解决一个更简单的问题,比如"这个功能能在最多五秒内完成执行吗?"然后你可以相对容易地做到这一点。例如,参见clojure本身的test for the same thing:
(defn sample [& args]
0)
(deftest test-vars-apply-lazily
(is (= 0 (deref (future (apply sample (range)))
1000 :timeout)))
(is (= 0 (deref (future (apply #'sample (range)))
1000 :timeout))))
创建一个能够做你想做的事情的未来,然后用超时来决定未来。
答案 2 :(得分:0)
另外,如果已知您的循环将相同的数据传递给相同输入数据的下一次迭代(在某种程度上是纯粹的),那么您可以确定,如果您在不同的itarations上遇到相同的循环参数循环可能是无限的(意味着它已在某处循环)。例如(非常愚蠢):
(loop [i 20]
(if (zero? i)
(recur 10)
(recur (dec i))))
所以当你第二次遇到(= i 10)
时,你知道它是无限的。
也许您可以创建一些宏,仅用于测试目的,跟踪循环的参数并找到重复的参数,如下所示: