2011-09-15 6 views
1

관련 코드, 이것은 UnitTest++/TestRunner.h에서입니다 :UnitTest ++ 문제 : 상태가있는 조건부를 사용하려고합니다.

class TestRunner 
{ 
public: 
    explicit TestRunner(TestReporter& reporter); 
    ~TestRunner(); 

    template <class Predicate> 
    int RunTestsIf(TestList const& list, char const* suiteName, 
        const Predicate& predicate, int maxTestTimeInMs) const 
    { 
     Test* curTest = list.GetHead(); 

     while (curTest != 0) 
     { 
      if (IsTestInSuite(curTest,suiteName) && predicate(curTest)) 
      { 
       RunTest(m_result, curTest, maxTestTimeInMs); 
      } 

      curTest = curTest->next; 
     } 

     return Finish(); 
    } 

private: 
    TestReporter* m_reporter; 
    TestResults* m_result; 
    Timer* m_timer; 

    int Finish() const; 
    bool IsTestInSuite(const Test* const curTest, char const* suiteName) const; 
    void RunTest(TestResults* const result, Test* const curTest, int const maxTestTimeInMs) const; 
}; 

내 술어 클래스는 내가 원하는 것을 할 수 있도록 수정하려고합니다 :

class ListFilterRemember { 
    char **list; 
    int n; 
    Test **testsAlreadyRun; 
    int index_tar; 
    int max_allocd; 
public: 
    ListFilterRemember(char **list_, int count) { 
       int testCount = 0; 
     Test* curTest = Test::GetTestList().GetHead(); 
     while (curTest != 0) { 
      testCount++; 
     } 
       list = list_; n = count; max_allocd = testCount; 
     testsAlreadyRun = new Test *[max_allocd]; 
     index_tar = 0; 
    } 
    bool operator()(const Test* const t) const { 
     for (int i=0;i<index_tar;++i) { 
      if (testsAlreadyRun[i] == t) { return false; } 
     } 
     for (int i=0;i<n;++i) { 
      std::string dot_cpp_appended = std::string(list[i]) + ".cpp"; 
      if (!strcasecmp(t->m_details.testName, list[i]) || 
        !strcasecmp(t->m_details.suiteName, list[i]) || 
        !strcasecmp(t->m_details.filename, list[i]) || 
        !strcasecmp(t->m_details.filename, dot_cpp_appended.c_str()) || (
          filename_dir_prefix_len < (int)strlen(t->m_details.filename) && (// ensure the ptr arith in next 2 lines doesn't go out of bounds 
            !strcasecmp(t->m_details.filename+filename_dir_prefix_len, list[i]) || 
            !strcasecmp(t->m_details.filename+filename_dir_prefix_len, dot_cpp_appended.c_str()) 
          ) 
        ) || (
          std::string::npos != findCaseInsensitive(t->m_details.testName,list[i]) 
        ) 
      ) { 
       // erring on the side of matching more tests 
       //printf(" running\n"); 
       if (index_tar >= max_allocd) throw std::runtime_error("Did not allocate! Segfault here."); 
       testsAlreadyRun[index_tar] = (Test *)t; 
       index_tar += 1; 
       return true; 
      } 
     } 
     //printf(" not running\n"); 
     return false; 
    } 
    ~ListFilterRemember() { 
     delete[] testsAlreadyRun; 
    } 
}; 

TestRunner.h에서 정의 된 방식을 볼 수 있습니다. 내 operator() 함수가 멤버 변수를 변경할 수 없도록하는 const 한정자를 연결합니다. 이러한 변경을해야만 이미 실행 한 테스트가 기억되어 다시 실행할 수 없습니다. 다시 실행할 위험이있는 이유는 RunTestsIf()을 여러 번 실행하려고하기 때문입니다.

명령 행에 테스트 목록을 입력하여 이름에 따라 실행할 테스트를 지정합니다. 이것이 문자열 매칭 코드의 전부입니다. 나는 여전히 그것들을 사용하고 싶지만, 이번에는 내가 지정한 테스트들이 내가 지정한 순서대로 실행되도록 개선하고 싶다. 이것을하기 위해서 나는 테스트 러너를 움직여야한다. 지정된 테스트 목록을 검색하고 하나씩 일치시킵니다.

아이디어? UnitTest ++ 코드에서 핵을 가두 고 싶지만 꼭 할 필요가 없다면 일을 망치고 싶지는 않습니다.

답변

1

키워드는 mutable 키워드를 사용할 수 있지만 테스트가 구조화 된 방식은 테스트 러너가 동일한 술어 인스턴스를 다시 사용할 수 없으므로 테스트간에 변경 내용이 손실 될 수 있음을 나타냅니다. 물론 게시 된 코드가 전체 테스트 러너라면 매번 동일한 Predicate 인스턴스를 호출하는 것처럼 보입니다.

+0

'mutable' 키워드에 대해 전혀 알지 못했습니다. 그것을 지적 해 주셔서 고마워요. 거의 마치이 상황에 맞게 만들어진 것 같습니다. 후드 아래에있는 Predicate에 이상한 일이 있는지 확인하기 위해 몇 가지 테스트를해야합니다. 그러나 src와 내가 게시 한 비트는 '술어'에 대한 유일한 참조입니다. ** 아마도 ** UnitTest ++의 src를 약간 편집하여 작동하도록 해킹 할 수도 있지만, 재 컴파일을 요구할 가능성이 높습니다. 그냥 ... 좋지 않아. 어쨌든 감사합니다. –

0

일반적으로 단위 테스트에는 결정적인 테스트 대상 세트가 있어야합니다. 이것은 통합 테스트에 더 가깝습니다. 그게 반드시 나쁜 것은 아닙니다. 먼저 작은 비트를 먼저 테스트하십시오.

즉, UnitTest ++는 작고 쉽게 수정되도록 설계되었습니다. 나는 기존의 기능을 해치지 않고 필요에 맞게 확장하거나 줄 바꿈합니다.

+0

cmd 행없이 내 단위 테스트 실행 파일을 실행하면 args가 모든 테스트를 일반적인 방법으로 실행합니다. 나는 단지 그것을 생각했다, 왜 내가 그것을하고 싶어하는 것을하게하지 마라. –

관련 문제