Outsider's Dev Story

Stay Hungry. Stay Foolish. Don't Be Satisfied.
RetroTech 팟캐스트 44BITS 팟캐스트

FireUnit : FireBug 확장 자바스크립트 유닛 테스트

Ajaxian을 보다가 눈에 띄는 기사가 보였다. "FireUnit: JavaScript Unit Testing Extension"라는 기사로 jQuery를 만든 John Resig과 Firebug 풀타임 Contributor인 Jan Odvarko이 만든 Firebug의 확장플러그인으로 자바스크립트 유닛테스트를 할 수 있게 하는 FireUnit이라는 걸 만들어서 공개했다는 기사이다. 현재 적용하고 있지는 않지만 TDD에는 관심을 꽤 가지고 있기 때문에 언젠가 꼭 적용해봐야지 하고 있었는데 이런것까지 등장했다.

Alankang님이 만드신 JSSpec이라는 BDD프레임웍도 있기는 하지만(이것도 써봐야되는데... ㅠ..ㅠ) 프레임웍은 소스에 관련 라이브러리를 포함시켜야 하지만(단점이란 얘긴 아니다.) 이건 그냥 유닛테스트 소스만 있으면 된다.

FireUnit은 Firebug의 확장기능이므로 당연히 파이어폭스에서만 가능하고 파이어버그가 깔려 있어야 한다. 설치는 다른 파이어폭스 익스텐션과 동일하게 설치하면 된다.(Firefox 3이상, Firebug 1.2이상일때만 사용가능하다.) 설치하고 나면 아래처럼 Firebug에 Test라는 탭이 생긴다. 끝이다. 이제 테스트유닛만 만들어 내면 된다.

사용자 삽입 이미지

FireUnit의 Wiki에 가면 관련정보를 얻을 수 있다.  위키문서의 Internals를 보면 사용할 수 있는 유닛테스트 함수를 알 수 있다.

  • ok : prints a message (test result) into the Test panel. If the specified condition is false, the message is marked as failing (displayed in red).
  • compare : prints a message into the Test panel. If expected and result parameters are not equal, the message is marked as failing.
  • reCompare : expects regular expression (within expected) to compare with result parameter.
  • testDone : Finishes a test.
  • forceHTTP : starts local HTTP server (httpd.js) for network related tests. Also makes sure that cache is cleared.
  • registerPathHandler : makes possible to register handler for dynamically generated responses.
  • runTests : run list of specified tests (in the same order as the are specified)
  • id : returns DOM element according to the specified ID.
  • test : inserts tests to execute into a current queue.
  • click : fires fake click event on specified DOM element.
  • focus : focuses specified DOM element.
  • value : sets value of the specified DOM element.
  • key : fires fake keypress event on specified DOM element.
  • panel : returns specified Firebug’s panel.


Internals부분은 파이어유닛의 개발자를 위한 설명 페이지라서 각 메서드의 정확한 사용법에 대해서는 잘 나와있지 않다. 다행히도 존레식잔 오드바코(이렇게 읽는거 맞나 ㅡ..ㅡ)가 FireUnit에 대한 포스팅을 하면서 간단한 예제를 올려두었고 사용방법이 그리 어렵지 않기 때문에 약간 보면 이해할 수 있다.


function okUnitTest(){
    return true;
}    
    
fireunit.ok(true, "ok 성공 테스트");
fireunit.ok(false, "ok 실패 테스트");
fireunit.ok(okUnitTest, "ok 성공 테스트 - okUnitTest함수");

fireunit.compare("문자열 비교", "문자열 비교", "성공 : compare 문자열 비교");
fireunit.compare("<div>파이어유닛</div>", "<div>파이어버그</div>", "실패 : compare 문자열 비교");

fireunit.reCompare(/01[016789]-[0-9]{3,4}-[0-9]{4}/, "016-123-4567", "성공 : reCompare 비교");

window.onload = function() {
    var target = document.getElementById("box");
    fireunit.mouseDown(target);
    fireunit.click(target);
    fireunit.focus(target);
    fireunit.key(target, "a");
    fireunit.value("username", "Outsider");
    
    fireunit.testDone();
}

내가 테스트해본 코드이다. 이 유닛테스트 코드를 실행하면 아래와 같이 출력되는 것을 볼 수 있다. Compare같은 경우는 하위탭으로 비교값을 바로 확인해 볼 수 있다.

사용자 삽입 이미지

잠시 만져본 걸로 간단히 함수를 설명하면....(깊게는 나도 몰라서.. ㅋ)

fireunit.ok( , "") : ok는 boolean값으로 판단한다. 첫번째 파라미터로 불린값이 오고(위의 코드처럼 함수를 따로 호출해도 된다.) 두번째 파라미터나 Test패널에 표시될 메시지이다.
fireunit.compare("", "", "") : 첫번째와 두번째 파라미터의 문자열을 비교하고 세번째 파라미터나 표시될 메시지다.
fireunit.reCompare( , "", "") : 정규식으로 문자열을 검사한다. 첫번째 파라미터에 정규식이 들어가고 두번째 파라미터에 검사할 문자열이 들어가고 세번째 파라미터가 표시될 메시지이다.

fireunit.mouseDown(target)
fireunit.click(target)
fireunit.focus(target)
fireunit.key(target, "a") : 위 4개의 메서드는 가짜로 이벤트(각 onmousedown, onclick, onfucus, onkeypress)를 발생시킨다. 파라미터로는 이벤트를 발생시킬 엘리먼트를 넘겨준다. key의 경우에는 두번째 파라미터로 keypress로 눌려질 키를 입력한다.

fireunit.value("", "") : value는 대상엘리먼트에 값을 입력한다. 첫번째 파라미터에 대상엘리먼트(input등)의 id값을 주고 두번째 파라미터에 넣을 값을 준다.

fireunit.testDone() : 테스트를 수행하는 메서드로 항상 테스트코드 맨 아래에 있어야 테스트코드가 실행된다.


위쪽에 메서드를 나열한대로 이밖에도 몇가지가 더 있는데 어떻게 사용하는 건지 잘 모르겠다. 특히 fireunit.runTests();는 꽤나 유용할 것 같은데 죽어도 동작을 안한다. 어떻게 사용하는건지.. (누가 이 우매한 중생을 좀... ㅡ..ㅡ 존레식이 예제소스까지 써놨는데도 따라를 못하네.. ㅠ..ㅠ)

이제 막 발표한 상황이기는 하지만 이거 잘 쓰면 꽤나 유용할 듯 싶다. JSSpec은 아직 안써봐서(script.aculo.us에도 Unit Test가 있던데) 어느쪽이 더 좋은지는 잘 모르겠지만.... ㅎ
2008/12/20 16:44 2008/12/20 16:44