2016-08-29 4 views
0

일부 샘플 코드가 무한 루프를 일으키지 않는지 확인하는 테스트 (clojure.test 사용)를 작성하고 싶습니다. 테스트중인 코드가 버그가있어서 무한 루프가 발생하면 테스트 하네스가 실패를보고하기를 원합니다. (스택을 오버플로하지 않는 일종의 무한 루프를 가정합니다.)무한 루프에 대한 클로저 테스트

아이디어가 있습니까?

+2

[일부 구형 - 소 가정과 :

어쩌면 당신은 루프의 매개 변수를 추적하고이 답변에 같이 반복되는 사람을 찾을 것입니다 무슨 만 테스트 목적을 위해, 몇 가지 매크로를 생성 할 수 (무한한 기억과 같은), 당신은 (아마 comp-sci 101 수학적으로 불가능한) 어떤 언어에서도 그렇게 할 수는 없습니다. 나는 특별한 경우에 효과가있는 대답을 생각할 수있다. trampolines 또는 loop/recur 호출을 찾기 위해 코드를 다시 컴파일하고 이전의 모든 관찰 된 상태와 현재 상태를 비교하고 이전에 상태를 본 적이 있다면 중단합니다. 그러나 주어진 상태를 두 번 반복하지 않는 무한 루프는 정확히 올 수 없습니다 으로. –

+1

... "이제까지 N 밀리 초의 벽시계 시간 (CPU 시간 또는 what-have-you)으로 항상 완료해야합니다."와 같은 주장을하고 싶다면 훨씬 쉽습니다. –

답변

3

물론 "이 기능이 최대 5 초 내에 실행을 완료합니까?"와 같은 간단한 문제를 해결하는 데 관심이있는 경우 일반적인 경우에는이 작업을 수행 할 수 없습니다. 그러면 비교적 쉽게 할 수 있습니다. 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)))) 

당신이하고 싶은 일을 미래를 만든 다음 시간 제한과 미래 DEREF.

+0

질문의 정신을 이해해 주셔서 감사합니다. – johnv02139

3

이는 불가능합니다. halting problem을 해결하는 것과 같습니다. 이는 불가능합니다.

+0

단위 테스트를 작성할 때 예상되는 동작을 정의합니다. 당신이 맞다면, "이 코드는 결국 10 억년이 걸리더라도 값을 반환합니다"라는 예상되는 동작을 정의하고 싶다면 중단 문제를 해결해야 할 것입니다. 나는 이것이 그 질문의 합리적인 해석이 아니라는 것을 알지만, 코드가 합리적인 기간 내에 가치를 반환 할 것으로 기대되는 것은 명시하지 않았다는 것이 옳다. 아무도 묻지 않을 질문에 정답을 주셨습니다 (Stack Overflow에서) – johnv02139

0

또한 루프가 같은 입력 데이터에 대해 동일한 데이터를 다음 반복에 전달하는 것으로 알려져 있다면 (다른 방식으로는 순수합니다), 다른 루프에서 동일한 루프 매개 변수가 발생할 경우 itarations 루프는 아마도 무한합니다 (즉, 어딘가에 순환했습니다). 예 (아주 어리석은 일)의 경우 : 두 번째로 (= i 10)가 발생할 때

(loop [i 20] 
    (if (zero? i) 
    (recur 10) 
    (recur (dec i)))) 

그래서, 당신은 무한 알고있다. 일반적인 경우

clojure loop see values

관련 문제