이번 글에서는 googletest의 공식 입문 문서인 Googletest Primer를 번역하면서 영어 공부를 진행하려고 합니다.

번역 페이지

https://github.com/google/googletest/blob/master/googletest/docs/primer.md

 

google/googletest

Googletest - Google Testing and Mocking Framework. Contribute to google/googletest development by creating an account on GitHub.

github.com

 

소개 : 왜 googletest인가?

 googletest는 더 나은 c++ test 로직을 작성할 수 있도록 도와줍니다.

 googletest는 google의 특정 요구사항 및 제약사항을 기반으로 테스트 기술팀에서 개발한 testing 프레임워크입니다.

 Linux, Window 또는 Mac 어디에서든 c++코드를 작성한다면 googletest는 도움이 될 수 있습니다.

 단위 테스트뿐만 아니라 어떠한 종류의 테스트든지 지원합니다. 

 그렇다면 좋은 테스트는 무엇이며 googletest를 어떻게 사용해야 할까요? 

  1. 테스트는 독립적이고 반복적이어야 합니다. 다른 테스트의 결과로 성공하거나 실패하는 테스트를 디버깅하는 것은

     매우 고통스럽습니다. googletest는 서로 다른 객체에서 테스트를 실행시켜 테스트를 고립시킵니다.

     테스트가 실패했을 때 googletest는 빠른 디버깅을 위해서 독립적인 실행할 수 있습니다. 

  2. 테스트는 잘 구성되고 테스트되는 코드의 구조를 반영해야 합니다. googletest는 데이터와 서브루틴을

     공유할 수 있는 관련된 테스트들을 test suite들로 그룹화합니다.

     이러한 일반적인 패턴은 알아보기 쉽고 테스트를 쉽게 관리할 수 있습니다.

     이러한 일관성은 사람들이 프로젝트를 변경하고 새로운 코드로 작업을 시작할 때 특히 도움이 됩니다.

  3. 테스트는 이식이 용이하고(platform제한이 없어야 한다.) 재사용이 가능해야 합니다.

     Google은 plaform-neutral(플랫폼에 중립적)한 많은 코드를 가지고 있습니다.

     이것들의 테스트 또한 plaform-neutral 해야 합니다.

     googletest는 다른 OS들과 다른 컴파일러들과 함께 예외 없이 작동합니다.

     그래서 googletest는 다양한 구성으로 작동할 수 있습니다.

  4. Test가 실패했을 때 문제에 대해서 가능한 많은 정보를 제공해야 합니다.

     googletest는 첫 번째 테스트가 실패해도 멈추지 않습니다.

     대신에 현재의 테스트만 멈추고 다음 작업을 계속합니다.

     nonfatal failure가 보고된 이후에 테스트를 계속 실행하도록 설정할 수 있습니다.

     이렇게 해서 단일 run-edit-complie 사이클 안에서 여러 개의 버그를 발견하고 수정할 수 있습니다.

  5. testing 프레임 워크 테스트 작업자를 잡다한 일에 해방시켜고 테스트 내용에 집중할 수 있도록 해야 합니다. 

     googletest는 정의된 모든 테스트를 자동으로 추적하고 사용자가 실행하기 위해서 따로 열거할 필요가 없습니다.

  6. Test는 빨라야 합니다. googletest를 사용하면 테스트들 사이에서 공유 자원을 재사용할 수 있고 테스트끼리

    서로 의존하지 않고 설정 및 해제 비용을 한 번만 지불할 수 있습니다.

 googletest는 널리 사용되는 xUnit 설계 기반으로 작성되었기 때문에 만약에 JUnit 또는 PyUnit을 이전에 사용했다면

 편하게 느껴질 것입니다. 그렇지 않다면 기본 사항을 배우고 시작하는데 10분 정도 걸릴 것입니다. 

 그럼 시작해 봐요

 

명칭에 주의하세요

 Note : Test, Test CaseTest Suite 용어들의 서로 다른 정의로 인해서 약간 혼란스러울 수 있으므로 주의하세요

 

 역사적으로 googletest는 관련된 Test들을 그룹화하기 위해서 Test Case라는 용어를 사용하기 시작했지만

 ISTQB(International Software Testing Qualifications Board) 자료 및 소프트웨어의 품질에 대한 다양한 교재들을

 포함하는 최신의 발행물들은 이것을 Test Suite라는 용어를 사용합니다.

 

 googletest안에서 사용되는 Test라는 용어는 ISTQB와 기타들의 Test Case라는 용어와 일치합니다. 

 Test라는 용어는 ISTQB의 Test Cast의 정의를 포함하여 넓은 의미를 가지므로 큰 문제는 아닙니다. 

 그러나 googletest에서 사용된 Test Case라는 용어는 모순되어서 혼란스럽습니다. 

 

 googletest는 최근에 TestCase라는 용어를 TestSuite로 변경하기 시작했습니다.

 선호되는 API는 TestSuite입니다. 구식의 TestCase API는 천천히 폐기되고 리펙토링 됩니다. 

 

 용어의 대한 정의가 다른 것을 주의하세요

의미 googletest 용어 ISTQB용어
특정 입력값을 사용해서 특정 프로그램 경로 수행 및 결과 확인  Test Test Case

 

기본 개념

 googletest를 사용할 때는 조건이 true인지 아닌지 확인하는 구문인 assertion을 작성하는 것부터 시작합니다. 

 assertion의 결과는 success, nonfatal failure 또는 fatal failure(치명적인 실패)가 될 수 있습니다.

 만약 fatal failure가 발생한다면  현재의 함수를 중단합니다. 아니라면 프로그램은 정상적으로 수행됩니다. 

 

 Test들은 테스트되는 코드의 동작을 확인하기 위해서 assertions을 사용합니다.

 만약 테스트가 crashe 나거나 assertion이 실패하면 test는 실패합니다. 그렇지 않다면 성공합니다.

 

 Test Suite는 하나의 이상의 test들을 포함합니다. 테스트되는 코드의 구조를 반영하는 Test suite로 Test들을

 그룹화해야 합니다.

 Test suite안의 여러 개의 test들이 공통으로 사용할 객체와 서브 루틴의 공유가 필요할 때 그것들을

 Test fixture 클래스에 넣을 수 있습니다.  

 Test program은 여러개의 test suites를 포함할 수 있습니다.

 개별적인 assertion을 수준에서 시작하여 Test 및 Test suites를 구축하는 Test program 작성방법에 대해서 설명합니다. 

 

Assertions

 googletest에서 assertion은 함수 호출과 비슷한 매크로입니다.

 클래스나 함수의 동작에 대해서 assertion으로 만들어서 테스트합니다.

 assertion이 실패할 때 googletest는 assertion 소스파일과 라인 번호를 실패 메시지와 함께 출력합니다.

 당신은 googletest 메시지에 추가될 사용자 작성 실패 메시지를 제공할 수 있습니다.

 

 assertion은 테스트의 내용은 같지만 현재의 함수에 다른 영향을 주는 두 가지 형태로 제공됩니다.

 ASSERT_* 버전은 실패할 때 fatal failure를 발생시키고 현재의 함수를 중단합니다.

 EXPECT_* 버전은 non fatal failure를 발생시키고 현재의 함수를 중단시키지 않습니다.

 일반적으로 EXPECT_*가 테스트에서 하나 이상의 실패를 보고 받을 수 있으므로 선호됩니다.

 그러나 assertion이 실패할 때 계속하는 것이 의미 없다면 ASSERT_*를 사용해야 합니다. 

 

 실패한 ASSERT_*는 즉시 현재의 함수를 리턴하기 때문에 뒤에 있는 정리 코드가 건너뛰어져서 메모리 릭이

 발생할 수 있습니다. leak의 속성에 따라서 고치지 않거나 고쳐야 할지 모릅니다.

 그래서 asserion 오류 외에도 힙 검사 오류가 발생한다면 이점을 명심하셔야 합니다.

 

 사용자 정의 실패 메시지를 제공하려면 <<연산자 또는 이러한 연산자 시퀀스를 사용해서 매크로로 간단히 전송합니다.

ASSERT_EQ(x.size(), y.size()) << "Vectors x and y are of unequal length";

for (int i = 0; i < x.size(); ++i) {
  EXPECT_EQ(x[i], y[i]) << "Vectors x and y differ at index " << i;
}

 ostream에 전송될 수 있는 것들은 모두 assertion 매크로로 전송 될 수 있습니다. (특히 C string과 string 객체)

 만약에 wide string(Window에서 UNICODE 속하는 wchar_t*, TCHAR* 또는 std::wstring)을 assertion에 전송한다면

 UTF-8로 변환돼서 출력됩니다.

 

Basic Assertion

 이 assertion들은 기본 true/false 상태를 테스트합니다. 

Fatal assertion Nonfatal assertion Verifies
ASSERT_TRUE(condition); EXPECT_TRUE(condition); condition is true
ASSERT_FALSE(condition) EXPECT_FALSE(condition); condition is false

 이것들이 실패할 때 ASSERT_* fatal failure를 발생시키고 현재의 함수에서 리턴하며 EXPECT_*는 Nonfatal failure를

 발생시키고 함수를 계속 실행할 수 있습니다. 양쪽 모두 assertion의 실패는 포함된 테스트의 실패를 의미합니다. 

 사용 가능 : Linux, Windows, Mac

 

Binary Comparison

이 섹션은 두 개의 값을 비교하는 assertion에 대해서 서술합니다. 

Fatal assertion Nonfatal assertion Verifies
ASSERT_EQ(val1, val2); EXPECT_EQ(val1, val2); val1 == val2
ASSERT_NE(val1, val2); EXPECT_NE(val1, val2); val1 != val2
ASSERT_LT(val1, val2); EXPECT_LT(val1, val2); val1 < val2
ASSERT_LE(val1, val2); EXPECT_LE(val1, val2); val1 <= val2
ASSERT_GT(val1, val2); EXPECT_GT(val1, val2) val1 > val2
ASSERT_GE(val1, val2) EXPECT_GE(val1, val2) val1 >= val2

 값 인자들은 assertion의 비교 연산자와 비교할 수 있어야 하며 그렇지 않으면 컴파일러 오류가 발생합니다.

 인자들이 ostream에 전송하기 위한 <<연산자를 지원하는 것을 요구했지만 이것은 더 이상 필요하지 않습니다.

 만약 <<을 지원한다면 assertion이 실패할 때 인자들을 출력하기 위해 호출될 것입니다.

그렇지 않다면 googletest는 그것들을 최선을 방법을 출력을 하려고 시도할 것입니다.

 더 자세한 내용과 어떻게 인자를 출력 방법을 정의하는지 알고 싶으면 documentation. 보세요

 

 이 assertion은 사용자 정의 타입과 함께 작업 알 수 있지만 비교 연산자가 정의되어 있어야 합니다. (예 == or <)

 Google C++ style guide는 권장하지 않기 때문에 사용자 정의 타입의 두 객체가 일치하는지 확인하기 위해서 

 ASSERT_TRUE()또는 EXPECT_TRUE()를 사용해야 할 수도 있습니다. 

 그러나 가능하다면 ASSERT_EQ(actual, expected)는 ASSERT_TRUE(actual == expected) 보다 선호됩니다.

 실패 시 actual과 expected 값을 알려주기 때문입니다. 

 

 인자는 항상 한 번만 평가됩니다. 그러므로 인자들이 side effect를 가지는 것은 괜찮습니다.

 그러나 일반적인 C/C++ 함수와 마찬가지로 인수의 평가 순서는 정의되지 않고 (즉 컴파일러가 랜덤 선택)

 코드는 특정한 인수의 평가 순서에 의존해서는 안됩니다.

 

 ASSERT_EQ()는 포인터와 포인터 간 동일한지도 체크합니다. 

 만약 2개의 C string에 사용한다면 같은 값을 가지는지 확인하지 않고 같은 메모리 위치에 있는지는 테스트합니다.

 그러므로 C string(예 const char*)들을 값들의 비교를 원한다면 나중에 설명될 ASSERT_STREQ()를 사용합니다.

 특히 C string이 Null임을 확인할 때 ASSERT_STREQ(c_string, NULL)을 사용합니다. 

 만약 c++ 11이 지원된다면 ASSERT_EQ(c_string, nullptr)을 사용하세요.

 두 개의 string 객체의 비교하려면 ASSERT_EQ를 사용해야 합니다.

(주의! C string과 string은 googletest에서 다르게 판단됩니다. C string은 포인터로 취급되고 string은 타입으로 )

 

 포인터 비교를 수행하려면 *_EQ(ptr, NULL)가 *_NE(ptr, NULL) 대신에 *_EQ(ptr, nullptr)과 *_NE(ptr, nullptr)을

 사용하세요. 왜냐하면 nullptr은 타입이지만 반면에 NULL은 아닙니다. 더 자세한 정보는 FAQ 보세요

 

 만약에 소수점 숫자를 수행한다면 반올림으로 인한 문제를 피하기 위해서 이 매크로 중 부동 소수점 변형을 사용

 할 수 있습니다. 자세한 내용은 Advanced googletest Topics을 보세요

 

 이 섹션 안의 매크로는 string과 wtring 양쪽에서 잘 작동합니다. 

 사용 가능 : Linux, Windows, Mac

 Historical note: 2016년 2월 이전에는 *_EQ는 ASSERT_EQ(expected[예상값], actual[실제값] )로 사용하라는

 관례가 있었습니다. 그래서 많은 코드들이 이렇게 사용합니다. 현재는 *_EQ는 두 파라미터를 동일한 방식으로

 처리합니다.

 

String Comparison

 이 그룹 안의 assertion들은 두 C String을 비교합니다. 만약에 두 개의 string 객체의 비교를 원한다면 EXPECT_EQ,

 EXPECT_NE 등을 사용하세요

Fatal assertion Nonfatal assertion Verifies
ASSERT_STREQ(str1, str2); EXPECT_STREQ(str1, str2); 2개의 C string이 동일한지
ASSERT_STRNE(val1, val2); EXPECT_STRNE(val1, val2); 2개의 C string이 다른지
ASSERT_STRCASEEQ(val1, val2); EXPECT_STRCASEEQ(val1, val2); 2개의 C string이 동일한지, 대소문자 무시
ASSERT_STRCASENE(val1, val2); EXPECT_STRCASENE(val1, val2); 2개의 C string이 다른지, 대소문자 무시

 Assertion안에서 "CASE"라는 이름은 대소문자를 무시한다는 의미를 가집니다.

 NULL 포인터와 비어 있는 string은 다르게 생각됩니다.

 *STREQ*와 *STRNE* 또한 와이드 C string(wchar_t)도 허용합니다. 만약 와이드 문자열의 비교가 실패한다면

 해당 값들은 UTF-8 narrow 문자열로 출력됩니다. 

 

 사용 가능 : Linux, Windows, Mac

 더 많은 문자열 비교 방법을 보려면 Advanced googletest Guide안에 이곳을 보세요

 

Simple Test

 테스트를 만들려면:

  1. TEST() 매크로를 사용해서 테스트 함수의 이름 지정 및 정의하세요.  테스트는 값을 리턴하지 않는 일반적인

     c++ 함수 형태를 가집니다. 

  2. 이 함수에 포함하려는 c++ 구문들을 다양한 googletest assertion을 사용해서 값을 확인하세요

  3. 테스트의 결과는 assertion에 의해서 결정됩니다. 만약에 테스트가 실패(fatally 또는 non-fatally)하거나 crash가

     발생하면 테스트는 실패합니다. 그렇지 않다면 성공입니다. 

 

 첫 번째 인자는 test suite의 이름이고 두 번째 인자는 test suite안에서 Test의 이름입니다.

 두 이름들은 C++ 식별자에서 유효해야 하며 언더 스코프( _ )를 포함하지 않아야 합니다.

 테스트의 전체 이름은 그 테스트가 포함된 test suite와테스트의 개별적인 이름(두번째 인자) 으로 구성됩니다.

 서로 다른 test suite를 가진 테스트들은 같은 개별적인 이름을 가질 수 있습니다.

 

 예를 들면 간단한 정수 함수를 보도록 합시다:

int Factorial(int n);  // Returns the factorial of n

 이 함수를 위한 test suite는 다음과 같습니다. 

// Tests factorial of 0.
TEST(FactorialTest, HandlesZeroInput) {
  EXPECT_EQ(Factorial(0), 1);
}

// Tests factorial of positive numbers.
TEST(FactorialTest, HandlesPositiveInput) {
  EXPECT_EQ(Factorial(1), 1);
  EXPECT_EQ(Factorial(2), 2);
  EXPECT_EQ(Factorial(3), 6);
  EXPECT_EQ(Factorial(8), 40320);
}

 googletest는 test suite별로 테스트의 결과를 그룹화합니다.

 그래서 논리적으로 관련 있는 테스트들은 같은 test suite안에 있어야 합니다.

 다시 말해서 TEST() 매크로의 첫 번째 인자 값들이 같아야 합니다.

 위의 예제의 2개의 테스트들은 같은 test suite인 "FactorialTest"에 속합니다.

 test suite와 테스트의 이름을 지을 때는 다음의 규칙을 따라야 합니다 => 링크

 

TEST Fixtures : 여러 테스트에서 같은 구성의 데이터 사용 하기

 만약에 비슷한 데이터 기반으로 동작하는 2개 이상의 테스트를 작성해야 한다면 test fixture를 사용할 수 있습니다. 

 이를 통해 여러 테스트에서 같은 구성의 객체를 재사용할 수 있습니다. 

 test fixture를 만들려면 :

  1. class에 ::testing::Test를 상속받으세요. 상속받은 클래스에서 fixture의 멤버들에 접근해야 하기 때문에

     protected:로 클래스 본문을 시작하세요

  2. 사용하려는 객체를 클래스 내부에서 선언하세요

  3. 만약 필요하다면 개별 테스트의 객체를 준비를 위한 기본 생성자나 SetUp() 함수를 작성하세요.

    보통 이곳에서 발생하는 실수는 SetUp() 함수를 소문자 u를 가진 Setup() 작성하는 것입니다.

    c++ 11이라면 override를 사용해서 철자가 올바른지 체크하세요

  4. 만약 필요하다면 SetUp()에서 할당한 모든 자원을 소멸자나 TearDown()을 작성하세요.

  5. 언제 생성자/소멸자를 사용해야 하고 언제 SetUp/TearDown을 사용해야 하는지 알고 싶으면 FAQ를 읽어 보세요

  6. 필요한 경우 테스트들이 공유할 서브 루틴을 정의하세요

 fixture를 사용할 때 test fixture의 객체와 서브루틴을 접근할 수 있도록 TEST() 대신에 TEST_F() 매크로를 사용합니다.

TEST_F(TestFixtureName, TestName) {
  ... test body ...
}

 TEST() 처럼 첫 번째 이름은 test suite 이름이지만 TEST_F()의 경우 test fixture 클래스의 이름이어야 합니다. 

 아마도 알고 있겠지만 _F는 Fixture입니다. 

 안타깝게도 c++ 매크로 시스템은 두 가지 유형의 테스트를 모두 처리할 수 있는 방법을 지원하지 않습니다.

 잘못된 매크로의 사용은 컴파일러의 에러를 발생시킵니다. 

 게다가 TEST_F()에서 test fixture 클래스를 사용하기 전에 그것을 먼저 정의해야 합니다.

 그렇지 않으면 컴파일러 에러 "virtual outside class declaration" 이 발생합니다.

 TEST_F()로 선언된 개별 테스트마다 googletest는 런타임에 새로운 test fixture를 생성할 것이고, 즉시 SetUp을

 통해서 그것을 초기화하고, 테스트를 수행하고, TearDown()을 호출하여 정리한 후에, test fixture를 삭제할 것입니다. 

 같은 test suite안의 서로 다른 테스트들은 서로 다른 test fixture 객체를 가지며

 googletest는 다음 text fixture를 생성하기 전에 언제나 text fixture 객체를 삭제합니다.

 googletest는 여러 테스트에서 같은 test fixture를 재사용하지 않습니다. 

 어떤 테스트에서 fixture에 변경을 가하더라도 다른 테스트에 영향을 미치지 않습니다. 

 예를 들어 다음 인터페이스를 가진 Queue라는 FIFO 대기열 클래스에 대한 테스트를 작성해 보겠습니다.

template <typename E>  // E is the element type.
class Queue {
 public:
  Queue();
  void Enqueue(const E& element);
  E* Dequeue();  // Returns NULL if the queue is empty.
  size_t size() const;
  ...
};

 먼저 fixture 클래스를 정의합니다.

 관례에 의해서 Foo라는 클래스를 테스트 하려면 Fixture 클래스의 이름을 FooTest 지어야 합니다.

class QueueTest : public ::testing::Test {
 protected:
  void SetUp() override {
     q1_.Enqueue(1);
     q2_.Enqueue(2);
     q2_.Enqueue(3);
  }

  // void TearDown() override {}

  Queue<int> q0_;
  Queue<int> q1_;
  Queue<int> q2_;
};

 이 경우에는 각 테스트가 수행이 끝난 후에 정리할 것이 없기 때문에 TearDown()이 필요하지 않습니다.

 이제 TEST_F fixture 사용해서 테스트를 작성합니다.

TEST_F(QueueTest, IsEmptyInitially) {
  EXPECT_EQ(q0_.size(), 0);
}

TEST_F(QueueTest, DequeueWorks) {
  int* n = q0_.Dequeue();
  EXPECT_EQ(n, nullptr);

  n = q1_.Dequeue();
  ASSERT_NE(n, nullptr);
  EXPECT_EQ(*n, 1);
  EXPECT_EQ(q1_.size(), 0);
  delete n;

  n = q2_.Dequeue();
  ASSERT_NE(n, nullptr);
  EXPECT_EQ(*n, 2);
  EXPECT_EQ(q2_.size(), 1);
  delete n;
}

 위의 예제는 ASSERT_*와 EXPECT_* assertion을 둘 다 사용합니다. 일반적으로 assertion 실패 후에도 더 많은 오류들을

 계속 확인하고 싶을 때 EXPECT_*를 사용하고 assertion이 실패 후에 계속 진행할 수 없을 때는 ASSERT_*를

 사용합니다. 

 예를 들어서 Dequeue 테스트 안에서 두 번째 assertion은 나중에 포인터 n을 역참조 해야 하는데 n이 null이면

 segfault가 발생하기 때문에 ASSERT_NE(nullptr, n)입니다.

 

 이 테스트를 수행할 때 다음과 같은 일이 발생합니다. 

  1. googletest QueueTest 객체를 생성합니다.( 그것을 t1이라고 부릅니다.)
  2. t1.SetUp()은 t1을 초기화합니다. 
  3. t1에서 첫 번째 테스트(IsEmptyInitially)를 수행합니다. 
  4. 테스트가 끝난 후에 t1.TearDown()으로 정리합니다. 
  5. t1을 해제합니다. 
  6. 위의 스탭을 다른 QueueTest 객체에서 반복합니다. 이번에는 DequeueWorks테스트를 수행합니다. 

Invoking the Tests(테스트 호출)

 TEST()TEST_F()는 보유한 테스트들을 내부적으로 googletest에 등록합니다. 그래서 다른 대다수의 c++ 테스트

 프레임 워크와 달리 테스트를 실행하기 위해 정의된 모든 테스트를 다시 나열할 필요가 없습니다.

 테스트를 정 한 후에 RUN_ALL_TEST()로 그것들을 수행할 수 있으며 모든 테스트가 성공하면 0을 그렇지 않으면 1을

 리턴합니다.

 RUN_ALL_TESTS()는 연결된 유닛 안에 모든 테스트를 수행합니다. - 서로 다른 test suites이거나 다른 소스 파일들도

 될 수 있습니다.

 

 RUN_ALL_TESTS 매크로가 수행될 때:

  • 모든 googletest flag의 상태를 저장합니다. 
  • 첫 번째 테스트의 test fixture 객체를 생성합니다. 
  • SetUp()을 통해서 초기화합니다. 
  • fixture 객체에서 테스트를 수행합니다.
  • TearDown()을 통해서 fixture를 정리합니다. 
  • Fixture를 삭제합니다. 
  • 모든 googletest flag의 상태를 복원합니다.
  • 모든 테스트가 수행될 때까지 다음 테스트에서 위의 스탭을 반복합니다. 

 만약에 fatal 오류가 발생하면 다음 단계를 건너뜁니다.

 중요 : RUN_ALL_TEST() 반환 값을 무시하지 말아야 합니다. 그렇지 않으면 컴파일러 에러가 발생합니다. 

 이렇게 디자인한 이유는 자동화된 테스트 서비스는 stdout/stderr 출력이 아닌 종료 코드를 기반으로 테스트의 통과

 여부를 결정하기 때문에 main() 함수는 RUN_ALL_TESTS()의 값을 반환해야 합니다. 

 

 또한 RUN_ALL_TESTS()를 한 번만 호출해야 합니다. 두 번 이상 호출하면 googletest의 일부 최신 기능

 (예를 들면 thread-safe death tests)과 충돌해서 그것이 동작하지 않습니다.

 

main() 함수 작성

 대부분의 유저들은 main 함수를 작성할 필요가 없고 대신에 적절한 진입점을 정의하는 gtest_main과

 연결합니다. 자세한 내용은 이 섹션의 마지막 부분을 참조하세요

 이 섹션의 나머지 부분은 테스트가 수행 전에 test suite나 text fixture 프레임워크 안에서 정의할 수 없는 사용자 정의

 작업이 필요한 경우에만 적용해야 합니다. 

 만약 main함수를 작성했다면 RUN_ALL_TESTS() 값을 리턴해야 합니다. 

 이 표준으로부터 시작할 수 있습니다. 

#include "this/package/foo.h"

#include "gtest/gtest.h"

namespace my {
namespace project {
namespace {

// The fixture for testing class Foo.
class FooTest : public ::testing::Test {
 protected:
  // You can remove any or all of the following functions if their bodies would
  // be empty.

  FooTest() {
     // You can do set-up work for each test here.
  }

  ~FooTest() override {
     // You can do clean-up work that doesn't throw exceptions here.
  }

  // If the constructor and destructor are not enough for setting up
  // and cleaning up each test, you can define the following methods:

  void SetUp() override {
     // Code here will be called immediately after the constructor (right
     // before each test).
  }

  void TearDown() override {
     // Code here will be called immediately after each test (right
     // before the destructor).
  }

  // Class members declared here can be used by all tests in the test suite
  // for Foo.
};

// Tests that the Foo::Bar() method does Abc.
TEST_F(FooTest, MethodBarDoesAbc) {
  const std::string input_filepath = "this/package/testdata/myinputfile.dat";
  const std::string output_filepath = "this/package/testdata/myoutputfile.dat";
  Foo f;
  EXPECT_EQ(f.Bar(input_filepath, output_filepath), 0);
}

// Tests that Foo does Xyz.
TEST_F(FooTest, DoesXyz) {
  // Exercises the Xyz feature of Foo.
}

}  // namespace
}  // namespace project
}  // namespace my

int main(int argc, char **argv) {
  ::testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}

 ::testing::InitGoogleTest() 함수는 googletest flag의 command line을 분석하고 모든 인식된 flag를 제거합니다. 

 이를 통해서 사용자는 다양한 flag를 통해서 테스트 프로그램의 동작을 제어할 수 있고 이것은 AdvancedGuide에서

 다룹니다. 

 RUN_ALL_TESTS()를 호출하기 전에 이 함수를 호출해야 합니다. 그렇지 않으면 플레그가 제대로 초기화되지 않습니다.

 윈도우에서 InitGoogleTest()는 유니 코드 문자열에서도 동작하고 그래서 유니 코드 모드로 컴파일된 프로그램에서

 사용할 수 있습니다.

 그러나 모든 main 함수를 작성하는 것이 너무 힘든 일이라고 생각하시나요? 우리는 그 생각에 완전히 동의하며

 이러한 이유 때문에 googletest는 기본 구현 main()을 제공합니다. 

 당신의 요구 사항에 맞는다면 테스트를 gtest_main 라이브러리와 연결하는 것이 좋습니다. 

 ParseGUnitFlags()는 InitGoogleTest()로 인해서 사용되지 않습니다. 

 

Known Limitations(알려진 제한사항)

 googletest는 스레드 안전하도록 설계되었습니다.

 pthreads 라이브러리가 사용 가능한 시스템에서는 구현이 스레드에 안전합니다. 

 이외 시스템에서 두 스레드에서 동시에  google test assertion을 사용하는 것은 안전하지 않습니다. ( 예 : 윈도우)

 대부분의 테스트들은 일반적으로 assertion이 main thread에서 수행되기 때문에 문제가 되지 않습니다.

 만약에 해당하는 플랫폼을 위한 도움이 필요하다면 gtest-port.h 안에서 필요한 동기화 동작을 구현을 지원받을

 수 있습니다. 

'googletest' 카테고리의 다른 글

[googletest] visual studio에서 google 테스트 사용하기  (0) 2020.04.27

+ Recent posts