CruiseControl.NET에서 2개 이상의 UnitTest++ ‘프로그램’을 실행하려면?

제목이 좀 애매하게 된 것 같은데, CruiseControl.NET에서 관리하는 하나의 프로젝트 안에 테스트를 실행시키는 것이 2개 이상일 수 있다. 간단히 생각해보니

  • 2 개 이상의 단위 테스트;unit-test 프레임웍이 사용된다 – 단위 테스트마다 사실 상 서로 다른 바이너리가 있게 된다 이 경우는 해당 사항이 없다. XSL 에서 각각을 최종적으로 통합해주기만 하면 OK.
  • 하나의 단위 테스트 프레임웍만 사용되지만 링크 문제나 연관성 문제로 2개 이상의 실행 바이너리가 존재한다
  • 단위 테스트 자체의 개념과는 좀 어긋나지만, 약간 큰 컴퍼넌트들의 결합을 테스트할 때 "프로그램 자체를 재시작"해야하는 객체들이 있으면 바이너리가 1개라도 비슷한 현상(?)이 나타난다.

이런 경우가 있을 수 있을 것 같다. 근데 문제는 두 개의 바이너리가 실행되고나면,

  1. 2개의 UnitTest++ — CruiseControl.NET은 특정 XML 형태[1] 의 출력만 제대로 알 수 있다 — 결과파일이 나온다
  2. 내가 사용했던 방법 — 결과 파일을 빌드 로그에 통합;merge 하는 방식으로는 XML의 root-node 에 해당하는 것[2] 이 2개 이상이 존재하게 된다
  3. 결과 파일을 최종적으로 해석하는 unittest.xsl[3]첫 XML node 만 해석하게 된다 모든 결과를 보기는 하지만 시간 등등에서 통합된 값을 내놓지 못한다.

즉, 모든 테스트 결과가 하나의 통일된 view로 제공되지 못하게 되는 것.

정정

정확히 말하면, 모든 테스트 결과가 보이기는 한다. 다만 통합되어서 보여야할 일부 정보(실행 시간/실패 갯수 등등)이 제대로 보이지 않는다.


물론 위의 경우들에서 CruiseControl.NET 자체에서 제공하는 해결책은 없지만 꼼수를 써서 피해가는 것은 가능한 것 같다.

  • A 안: 프로젝트 자체를 2개 이상으로 쪼갠다 – 단위 테스트 프레임웍이 2개 이상 쓰일 정도로 큰 프로젝트라면 사실 이렇게 작게 쪼개는게 맞을지도? 그리고 각각의 테스트 바이너리는 각각의 프로젝트 출력이된다
  • B 안: CruiseControl.NET의 XSL 파일(unittest.xsl)을 수정해서 두 개 이상의 XML 출력을 인식 시킨다.
  • C 안: 원래 사용하던 CruiseControl의 <merge> 구문 대신에 둘 이상의 UnitTest 결과를 통합하는 스크립트를 작성한다.

A 안은 일단 지금으로썬 하위 라이브러리를 모두 공유해서 현실성이 없는 것 같고 – 사실 링크 타임 문제랑 연관성 문제(이쪽이 상대적으로 작은 이유)로 쪼갠거라. B 안의 경우엔 CruiseControl.NET의 XSL 로딩 시점 문제 — 관련된 서비스를 다시 띄워야하고 + 가끔은 Windows 를 다시 띄워야 인식함 — 로 디버깅이 최악으로 괴롭다는 점으로 기각[4].

일단 C 안를 선택해서 진행하려 한다. Python 으로 DOM 만들어내는 것은 코드 1줄이고, 나머지는 최상위 node의 통합 작업 뿐…이라고 일단 생각되니; 그리고 아마도지만 좀 더 확장하거나 필터를 더하면 좀 다른 형식으로 나오는 애도 통합할 수 있게 되지 않을까 하는 중; 그렇지만 이 문제의 경우 단순히 XSL 수정이 너무 쉬웠다…

C 안 기각(..)후 B안으로 간 결과

UnitTest.xsl 의 앞부분을 다음과 같이 수정했다.

 <!–Data transform to use UnitTest++–>
<
xsl:variablename="unittest__.result.list"   
    select="//unittest-results" />
<
xsl:variablename="unittest__.time"
    select="sum($unittest__.result.list/@time)"/>
<
xsl:variablename="unittest__.case.list"   
    select="$unittest__.result.list/test" />
<
xsl:variablename="unittest__.case.count"
    select="count($unittest__.case.list)" />
<
xsl:variablename="unittest__.failure.list"
    select="$unittest__.result.list/test/failure"/>
<
xsl:variablename="unittest__.failure.count"
    select="count($unittest__.result.list/test/failure)"/>

일단 unittest-results node를 모두 고르고, 시간을 더하는 부분을 추가했다. 나머지 부분은 XPATH가 전부 골라준 것을 한꺼번에 처리하는 부분들이라 놔둬도 자동으로 잘 돌아가게 된다.  이것으로 삽질 종료(…).

  1. UnitTest.xsl에서 인식하는 것만 []
  2. UnitTest++의 경우 <unittest-results tests="24" failedtests="0" failures="0" time="1.3"> 하는 식의 root-node가 생긴다. 그리고 각각의 test-suite들과 실제 test들의 결과(성공/실패+실패 이유)들이 나열된다. nunit을 쓰거나 junit을 쓰면 조금 다른 노드가 생긴다. []
  3. unittest-result 라는 node를 찾아 거기에서 테스트 수나 실패한 테스트에 대한 정보를 찾아서 최종 출력용 페이지를 만들게 된다 []
  4. 근데 글을 쓰고나서 좀 생각해보니 이 자체도 좀 괜찮은듯하다. 상대적으로 스크립트 인터프리터같은 문제에 대해 portable하고, XSL을 다시 들여다보니 다른 UnitTest 프레임웍들은 전부 통합할 수 있는 구조(즉 여러개의 UnitTest가 있어도 잘 도는 구조)로 동작한다. 결국 이걸로 최종 선택 []

Published by

rein

나는 ...

One thought on “CruiseControl.NET에서 2개 이상의 UnitTest++ ‘프로그램’을 실행하려면?”

  1. 처음엔 결과가 다 안나오는 줄 알았는데, 실패하게 해서 테스트해보니 실패한 것들이 제대로 나오기는 하는 것 같다 -_-;;
    (그런 의미에서 밑에 정정하면서 퍼머링크 바꾼 포스팅은 뻘타가 Orz)

Leave a Reply