UnitTest++ 테스트 결과를 Debug창으로 출력하기

UnitTest++에서 기본으로 사용하는 UnitTest::RunAllTests() 함수를 사용하면 테스트 결과가 콘솔창으로 출력됩니다. 콘솔 어플리케이션이 아닌 윈도우 어플리케이션 같은 프로젝트에서는 이 함수를 이용하면 결과를 볼수 없게 되므로 어떻게 할까 고민하다가 디버그창에 출력해보기로 했습니다.

class DebugOutputReporter : public TestReporter
{
public:
    DebugOutputReporter(void);
    ~DebugOutputReporter(void);

    virtual void ReportTestStart(TestDetails const& test);
    virtual void ReportTestFinish(TestDetails const& test, float secondsElapsed);
    virtual void ReportFailure(TestDetails const& test, char const* failure);
    virtual void ReportSummary(int totalTestCount, int failedTestCount, int failureCount, float secondsElapsed);
};

TestReporter 클래스를 상속 받아서 몇개의 함수를 구현해주면 됩니다.

ReportTestStart : 테스트가 시작할때 마다 호출
ReportTestFinish : 테스트가 끝날때 마다 호출
ReportFailure : 실패한 테스트에 대한 정보 출력
ReportSummary : 테스트 전반에 대한 정보 출력

DebugOutputReporter 소스는 아래 첨부했습니다.
DebugOutputReporter.zip

main 혹은 WinMain 함수에서 아래와 같이 사용하면 됩니다.
UnitTest::DebugOutputReporter reporter;
UnitTest::RunAllTests(reporter, UnitTest::Test::GetTestList(), NULL, 0);
return 0; // 이건 필요에 따라...

윈도우 어플리케이션이라면 #ifdef RunTest ~ #endif 안에 넣어두고 사용하면 RunTest가 정의되면 Testcase가 실행되고 정보가 Debug창에 출력됩니다.

Debug창에 출력하니 좋은점은 실패한 테스트 정보를 더블 클릭하면 해당 소스라인으로 커서가 자동으로 이동된다는 점입니다. 이것은 VS의 기능인것 같은데 출력창에 소스파일과 라인이 Format에 맞게만 출력되면 지원해주는 것 같습니다.

c:\work\projects\zetc\unittest++\debugviewtest\debugviewtest.cpp(11): error: Failure in SimpleTest: false

이런 것을 얻어 걸렸다고 하나요. ^^;

ps. 유니코드 / 멀티바이트 모두 지원합니다.

by 자바워크 | 2008/06/26 01:11 | Programming | 트랙백 | 덧글(1)

ACE를 정적 라이브러리로 사용하기

동적 라이브러리 사용
ACE를 동적 라이브러리로 사용하려면(VS2005기준) ACE_ROOT\ace\ace_vc8.sln를 빌드해서 나오는 ace.lib/aced.lib를 사용하면 됩니다. 이렇게 되면 dll도 필요합니다.(ace.dll, aced.dll) 배포되어야 하는 클라이언트라면 dll을 같이 배포해야 하는 불편이 따르므로 아무래도 정적 라이브러리 형태를 선호하게 됩니다.

정적 라이브러리 사용
정적 라이브러리로 사용하려면 ACE_ROOT\ace\ace_Static.sln를 빌드해서 나오는 aces.lib/acesd.lib를 사용하면 됩니다. 그냥 링크하고 빌드하면 링크에러가 납니다. 전처리기에 ACE_AS_STATIC_LIBS를 선언해 줘야 합니다.

ACE를 사용하면서 발생하는 LNK4217 Warning에 대해
ACE를 이용하여 만든 라이브러리를 링크하여 사용하다가 LNK4217 경고를 보게 되었습니다. 메세지는 아래와 같습니다.

지역으로 정의된 'symbol' 기호를 'function' 함수로 가져왔습니다.

locally defined symbol 'symbol' imported in function 'function'

조금 복잡한 상황인데 정리해보면
  • ACE 라이브러리를 사용하여 작성된 라이브러리를 A 라고 하고
  • A를 링크해서 사용하는 프로젝트를 B라고 정의
  • B에서 LNK4217 경고 발생
초반에 그냥 무시하다가 시간이 날때 파악을 해보니 아래와 같은 상황이었습니다.
  • A에서는 전처리기에 ACE_AS_STATIC_LIBS 가 선언되어 있지 않고
  • B에서는 전처리기에 ACE_AS_STATIC_LIBS 가 선언되어 있고
  • A라이브러리를 사용하는 B에서는 ACE 정적 라이브러리(acesd.lib, aces.lib)를 사용 하게되면 LNK4217 발생
해결 방법은
  • A의 전처리기에 ACE_AS_STATIC_LIBS 선언하여 라이브러리를 생성 하거나
  • B에서 ACE 동적 라이브러리를 사용
위의 해결 방법 중 하나만 하시면 됩니다. 저는 정적 라이브러리를 사용하기 때문에 첫번째 방법으로 해결했습니다.

by 자바워크 | 2008/06/19 23:44 | Programming | 트랙백

P-Camp에 다녀왔습니다.

p-camp 그 세번째 만남에 참석하고 왔습니다. p-camp는 IT업계의 다양한 분야의 사람들이 모여서 몇가지 정해진 주제에 대해 토론을 진행하여 다양한 의견을 들어보는 자리 입니다.
p-camp 공식 블로그 : http://p-camp.tistory.com/

첫번째와 두번째는 다른 방식으로 이루어 졌다고 하던데 이번에는 월드 카페 라는 방식으로 진행이 되었습니다.
1. 한 테이블에 5명씩 착석하여 25분간 주어진 주제로 토론
   - 같은 테이블에 아는 사람이 없도록
   - 자기소개 -> 이슈제기 -> 토론 순서로 진행
   - 호스트를 한명 지정하여 커다란 종이에 정리(주로 마인드맵 방식)

2. 테이블을 변경하여 20분 토론
   - 호스트만 남고 나머지 인원은 다른 테이블로 이동
   - 호스트는 다른 사람들에게 진행된 내용을 간단히 설명
   - 다른 사람들도 이전의 내용과 연관성이 있는 내용 설명

3. 원래의 테이블로 이동하여 토론
   - 호스트는 다른 사람들이 자리를 비운 사이에 벌어진 토론에 대해 설명
   - 다른 사람들도 다른 테이블에서 듣고 왔던 내용을 설명

4. 갤러리 / 인덱스 카드 만들기
   - 정리된 종이를 가지고 나가서 벽에 붙이고
   - 그동안 토론된 내용중 중요한 3가지 이슈를 선별하여 인덱스 카드에 키워드를 기록
   - 모아진 인덱스 카드는 유사한 것끼리 모아서 붙인다.
   - 자유롭게 돌아다니며 구경(?)한다

5. 테이블로 돌아와 회고
   - 느낀점 / 좋았던 점 / 아쉬웠던 점 한가지씩 발언

첫번째 이슈는 더 나은 제품/서비스를 만들기 위해 모두 함께 할수 있는 것에는 무엇이 있을까?
두번째는  더 나은 제품/서비스를 만들기 위해 할 수 있는 질문
세번째는  더 나은 제품/서비스를 만들기 위해 할 수 있는 가능성 있는 것들 이었습니다.

대충 나온 의견들을 크게 분류해보면
  - 의사 소통
  - 개발자에 대한 보상 / 피드백
  - 개발 조직
  - 고객 분석
  - 제품에 대해 알기
  - 개발 프로세스
  - 상사 혹은 동료
이 정도 의견들이 모아졌습니다

장단점을 이야기 하자면 테이블 이동을 자주 하면서 의견이 전파되고 많은 사람들의 의견을 들을수 있게 되는 장점이 있지만 깊이 있는 토론은 힘들다는 단점도 있었습니다.

마지막으로 항상 이런 세미나 혹은 컨퍼런스 하면 기획이나 관리, 마케팅 쪽은 소수이고 프로그래머가 가장 많이 올까. 다양하게 오면 도움이 더 많이 될텐데 하는 생각이 듭니다.

by 자바워크 | 2008/06/12 01:24 | 트랙백

The Goal 시리즈

The Goal 시리즈는 제약조건이론(TOC)에 대해 소설 형식으로 쓴 책 입니다. 주로 공장에서 일어날 수 있는 어려운 상황들이 발생하고(갑자기 생산성을 2배로 높여야 한다거나) TOC로 그 상황들을 극복해 나가는 과정을 그리고 있습니다. 게임회사에서는 PM이나 PD라면 도움이 될 만한 내용들 입니다. 표지나 소개를 보면 재미없을 것 같은데 읽어보면 의외로 재미있는 편입니다.


  • 병목 부분의 생산성이 전체의 생산성을 결정한다.
  • 가능하면 병목부분을 프로세스의 가장 앞에 두는 것이 좋다 : 행군할 때 가장 느리게 걷는 사람을 맨 앞에 두는 원리
  • 병목 부분의 생산성 향상을 위해 다른 부분의 리소스를 적당히 투입하는 것도 좋다 : 행군시 느린 동료의 짐을 나누어 지면 전체의 속도가 빨라지는 원리


  • 1권과 비슷한 내용
  • 1권과 비슷한 재미

  • 탄탄대로를 걸어온 한 SI업체에 닥친 위기를 제약조건이론을 통해 극복하는 내용
  • 전작은 모두 공장이 무대였지만 이번엔 소프트웨어 개발사가 무대
  • 기억에 남는 대화

    • 협력사 : 2년 전에는 요청한 기능에 대한 반영율이 80%에 달했는데 현재는 20%에도 못 미칩니다. 어떻게 된 건가요?
    • 개발이사 :  예전에는 프로그램의 규모도 작고 기능도 많지 않아 쉽게 수정이 가능했지만 현재는 너무 많은 기능의 추가로 나조차도 전체의 기능을 다 알지 못하는 상태입니다.
    • 모두 : 그럼 어떻게 해야 하나요?
    • 개발이사 : 걱정마세요. 10월에 나올 8.0 버전에서는 기반부터 바꾸었기 때문에 예전의 모습을 찾을 수 있을 겁니다.
    • 마케팅 : 10월에는 너무 늦습니다. 7월에는 나와줘야 올해의 목표매출을 맞출 수 있습니다.(현재 2월)
    • 사장 : 7월까지 8.0 출시하는 겁니다. ㅇㅋ?
    • 개발이사 : ㅅㅂ... ㅜ.ㅡ

by 자바워크 | 2008/05/15 23:05 | 서평 | 트랙백 | 덧글(4)

켄트벡의 구현패턴을 읽고


코드를 구현하기에 앞서 좀더  우선순위에 두어야 할 가치에는 어떤 것이 있는지 설명하고 실제 구현에 있어서는 클래스, 상태(필드), 행위, 메소드, 컬렉션 으로 나누어서 좀 더 나은 구현이란 어떤 것인지 설명하고 있는 책입니다.


좋은 코드를 구현하기 위해 우선 고려해야 할 가치

  • 커뮤니케이션 : 코드의 가독성을 높인다
  • 단순성 : 과도한 복잡도를 제거하고 최대한 단순하게 작성
  • 유연성 : 확장성 및 유연성을 고려


원칙

  • 지역적 변화 : 변경을 최소화 한다
  • 최소중복
  • 로직과 데이터의 결합
  • 대칭성

    1. void process()
    2. {
    3.     input();
    4.     count++;

          output();

    5. }
    6. 위 코드를 아래와 같이 수정
    7. void process()
    8. {
    9.     input();
    10.     incrementCount();

          output();

    11. }


클래스

  • 최상위 클래스의 이름은 단순하게 짓는다.
  • 인터페이스와 구현을 분리하고 인터페이스에 의존하게 만든다.
  • 값 객체

    • bounds = bounds.translateBy(10, 20);
  • if나 switch 같은 조건문은 하위 클래스나 위임으로 변경한다.
  • 위임을 적극 활용한다


상태(변수)

  • 지역변수는 사용되기 직전에 가급적 최소범위 내에서 사용
  • 같은 객체로 반복해서 전달되는 파라미터 변수가 있다면 그 객체의 생성자를 통한 한번만 전달하는 방식으로 변경
  • 여러개의 파라미터 변수가 함께 여러 메소드로 전달된다면 이들을 묶어서 하나의 객체로 만들어 전달한다.
  • 0xFFFFFFFF 와 같은 magic number는 Color.WHITE 같은 변수로 변경
  • 가독성을 위해서는 변수가 선언되자마자 초기화를 하는 것이 좋다


메소드

  • 추상화 수준이 비슷한 메소드로 하나의 메소드를 구성하라

    1. void compute()
    2. {
    3.     input();
    4.     flag |= 0x0080;
    5.     output();
    6. }
    7. 위 코드를 아래와 같이 변경
    8. void compute()
    9. {
    10.     input();
    11.     updateFlag(color.Brown);
    12.     output();
    13. }
  • 의도 제시형 이름

    • Customer.linearCustomerSearch(string id) 보다는 Customer.find(string id) 와 같은 코드가 사용자에게 쉽게 다가옴
  • 많은 수의 파라미터와 임시 변수를 사용하는 메소드를 찾아서 메소드 객체로 만든다.

    1. complexCalcuation()
    2. {
    3.     ComplexCalcuator calculator;
    4.     calcultor.calculate();
    5.     value = calculator.value();
    6. }
  • 도우미 메소드  

    • 당장 관련도가 떨어지는 세부 구현을 숨기고 메소드 이름을 통해 구현자의 의도를 나타냄으로써, 복잡하고 거대한 연산 코드를 좀더 읽기 좋게 만듬.
    • 보통 보호형(private, protected)으로 선언.
  • 컬렉션 접근자 메소드 : 컬렉션을 통채로 리턴해주는 것보다는 add/remove 함수와 iterator를 제공한다.

ps. 예제 코드는 java로 되어있습니다.

by 자바워크 | 2008/04/26 23:05 | 서평 | 트랙백 | 덧글(2)

◀ 이전 페이지          다음 페이지 ▶