rein's world

VisualUnitTest++: Native Code라서 겪는 문제

계속해서 VisualUnitTest++을 사용 중. (이하 VUTPP라고 부르겠음)

내가 이해하는 작동 구조가,

  1. Compiler.Preprocessor.Definition1에 특정 값(VUTPP_UNITTEST++)이 있는지 확인하고 있으면,
  2. 해당 프로젝트의 파일들을 해석해서 SUITE(), TEST() 매크로가 있나 확인하고,
  3. 전체 테스트를 실행하거나, 선택한 테스트를 실행하면,
  4. (빌드가 필요하면 빌드를 하고) VS AddIn으로 떠있던 VUTPP에서 DLL 파일을 링크 & 실행
  5. 실행 중에 적절한 callback을 호출해서 결과값을 받음
  6. 최종적으로 결과값(성공/실패여부 등등) 표시

인데, 4에 약간의 문제가 있다.

테스트되는 코드가 native C++이라 생기는 어쩔 수 없는 문제에 가까운 것인데.

  • VUTPP는 VS AddIn이니 VisualStudio의 프로세스 공간에서 동작한다
  • 테스트는 DLL파일을 링크해서 실행되는데 이 것은 VUTPP가 실행하는 것이다
  • 테스트되는 DLL안에서 잘못된 메모리를 참조한다거나 하면 VUTPP 사망 → VisualStudio 사망 으로 연쇄 반응(?)

이라는 것. .Net managed code나 python, Java같은 언어에서라면 exception을 처리하는 것만으로 충분할텐데, 실패하면 OS가 직접처리(보통은 프로그램 사망으로 결론)하는 C++은 괴롭구나 Orz 아마 이것 때문에 VUTPP 제작자인 쑥갓님도 “VS자체가 죽을 수 있습니다"라고 써놓으신 것 같은데…

어제 테스트하던 라이브러리에서 지운 메모리를 참조하는 버그가 있어서 좀 괴로웠다(…). UnitTest 돌릴 때마다 VS가 사망…

아마 이런 해결책이 가능하지 않을까싶다. 문제가 되는게 VS AddIn과 **믿을 수 없는 테스트될 DLL이 강하게 결합되어 있다**라는 것. 이걸 좀 더 약한 결합으로 바꿀 수 있지 않을까?

  • 별도의 “실행기"를 만들고, 이걸 command line으로 호출한다. 결과값은 문자열같은 걸로 받아서 VUTPP가 재해석
  • 별도의 “실행기"를 만들고, 이걸 socket으로 연결한다(일종의 RPC?). 그리고 결과값을 소켓 통신으로 받아서 VUTPP가 재해석

즉, “별도의 실행기"와 VUTPP를 분리하고 이를 약한 결합인 command line + text나 socket 통신으로 연결해보자는 것2 주말에 시간나면 짜볼까? (시간나면보다는 “엄한 일로 시간을 낭비하지 않으면"에 가깝긴하지만…)


  1. Project Property → C/C++ → Preprocessor Definitions에 해당. ↩︎

  2. 통신이 실패하거나 여하튼 죽어버리면 JUnit의 failure(비정상 종료 등등)처럼 처리해버리면 되나? ↩︎