아마 자바스크립트로 unit test를 해본 사람이라면 늘 막히는 곳이 있게 마련인데
그중에 잘 막히는 부분은 set(Timeout|Interval)을 테스트 하는 것일겁니다..

예를 들면 아래와 같은 코드를 테스트 하고 싶다면 현재 자바스크립트의 특성상 일반적인 방법으로는 테스트가 불가능 합니다.



자바스크립트는 단일 스레드 방식이기 때문에 testDelay 함수를 호출할때 testDelay함수가 호출이 끝나지 않고는 delay안에 있는 setTimeout에 할당한 함수는 실행하지 않습니다. 그렇기 때문에 testDelay는 테스트 절대 성공할수 없습니다,

안되는 문제의 원인을 보면 자바스크립트가 단일 스레드이기 때문에 그렇고
그래서 setTimeout과 같은 함수를 사용하면 테스트가 한 함수 스코프에서 불가능하다는 생각을 했습니다.
위에 문제점을 어떻하면 해결할수 있을까 고민을 했는데 방법은 두 가지가 떠올랐습니다.

첫 번째.단일 스레드라는 환경을 변경하면 됩니다.
즉,일반적으로 iframe방식을 사용하면 됩니다.(즉,selenium 같은 방식)
실제 코드가 실행하는 환경과 테스트 코드가 실행하는 환경과 분리하면 된니다.

 아래 그림을 보면 이해하기가 쉽습니다.

이 방법은 테스트는 가능하지만 약간 복잡해질 소지가 있습니다.

두 번째. setTimeout을 안사용하면 됩니다.
즉, Simulating Time in jsUnit Tests,라고 나온 방법입니다.
이 방법의 핵심은 어차피 우리는 setTimeout을 테스트를 하는게 아니고 주기적으로 함수가 호출될 경우 정상적으로 작동하는지만 확인 하는게 목적이기 때문에 setTimeout과 유사한 함수를 만들어서 테스트를 하면 됩니다,
(mock으로 만들면 됩니다.-Ajax도 유사한 방법으로 테스트 하곤 합니다.)

2가지중 여러가지 고민을 해봤지만 2번째 방법이 쉽고 좋은 방법이라고 생각합니다.
혹시 javascript로 unit테스트를 진행하는데 이런 부분이 고민이였다면 해결하셨으면 좋겠습니다.

요즘 javascript란 언어를 가지고 (unit|acceptance)테스트를 진행하다보면 여러가지 문제을 겪게 되는데 이런 문제를 해결하기위해 고민 중입니다.
몇가지는 해결이 되고 몇가지는 아직도 고민 중인데 시간이 되면 겪었던 경험들을 공유할수 있도록 노력하겠습니다.^^;
Posted by 전용우
,