Update primer.md

This commit is contained in:
Hyuk Myeong 2019-08-13 11:16:52 +09:00 committed by GitHub
parent 8117fd29e2
commit 6f6ab42e32
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -21,9 +21,9 @@ Googletest가 xUnit architecture를 기반으로 설계되었기 때문에 JUnit
*Note:* *Test*, *Test Case*, *Test Suite*과 같은 용어를 사용함에 있어서 googletest와 [ISTQB](http://www.istqb.org/) 간에 정의가 다르기 때문에 주의가 필요합니다. *Note:* *Test*, *Test Case*, *Test Suite*과 같은 용어를 사용함에 있어서 googletest와 [ISTQB](http://www.istqb.org/) 간에 정의가 다르기 때문에 주의가 필요합니다.
Googletest는 개별 테스트를 가리키는 용어로서 Test를 사용해왔고 여러 Test의 묶음을 의미하는 용어로 Test Case를 사용해왔습니다. 그러나 [ISTQB](http://www.istqb.org/)를 비롯한 표준기관에서는 여러 Test의 묶음을 의미하는 용어로 [*Test Suite*](http://glossary.istqb.org/search/test%20suite)를 채택하고 있어서 혼란이 발생하곤 했습니다. Googletest는 개별 테스트를 가리키는 용어로서 Test를 사용해왔고 여러 Test의 묶음을 의미하는 용어로 Test Case를 사용해왔습니다. 그러나 [ISTQB](http://www.istqb.org/)를 비롯한 표준기관에서는 여러 Test의 묶음을 의미하는 용어로 [*Test Suite*](https://glossary.istqb.org/en/search/test%20suite)를 채택하고 있어서 혼란이 발생하곤 했습니다.
즉, googletest의 Test라는 용어를 ISTQB의 [*Test Case*](http://glossary.istqb.org/search/test%20case)와 동일한 의미로 사용하려고 해도 원래 googletest에서 Test 묶음을 의미하는 용어였던 Test Case와 충돌이 발생해서 문제가 되었던 것입니다. 결국 googletest는 *Test Case*라는 용어를 *Test Suite*으로 바꾸기로 결정했으며 *TestCase*로 시작하는 API들을 *TestSuite*으로 변경하는 과정에 있습니다. 즉, googletest의 Test라는 용어를 ISTQB의 [*Test Case*](https://glossary.istqb.org/en/search/test%20case)와 동일한 의미로 사용하려고 해도 원래 googletest에서 Test 묶음을 의미하는 용어였던 Test Case와 충돌이 발생해서 문제가 되었던 것입니다. 결국 googletest는 *Test Case*라는 용어를 *Test Suite*으로 바꾸기로 결정했으며 *TestCase*로 시작하는 API들을 *TestSuite*으로 변경하는 과정에 있습니다.
다만, 그러한 변경작업이 완료된 것은 아니기 때문에 이런 부분을 유념하여 용어를 구분하는데 문제가 없기를 바랍니다. 정리하면 개별테스트에 대해서는 Test, Test Case,`TEST()`가 사용되며 Test의 묶음에 대해서는 Test Suite을 사용하지만 일부 정리안된 Test Case가 남아있을 수도 있습니다. 다만, 그러한 변경작업이 완료된 것은 아니기 때문에 이런 부분을 유념하여 용어를 구분하는데 문제가 없기를 바랍니다. 정리하면 개별테스트에 대해서는 Test, Test Case,`TEST()`가 사용되며 Test의 묶음에 대해서는 Test Suite을 사용하지만 일부 정리안된 Test Case가 남아있을 수도 있습니다.
@ -90,7 +90,7 @@ Fatal assertion | Nonfatal assertion | Verifies
`ASSERT_GT(val1, val2);` | `EXPECT_GT(val1, val2);` | `val1 > val2` `ASSERT_GT(val1, val2);` | `EXPECT_GT(val1, val2);` | `val1 > val2`
`ASSERT_GE(val1, val2);` | `EXPECT_GE(val1, val2);` | `val1 >= val2` `ASSERT_GE(val1, val2);` | `EXPECT_GE(val1, val2);` | `val1 >= val2`
위의 assertion을 사용하려면 `val1`, `val2`와 같은 argument들이 assertion 종류에 맞는 비교연산자(`==`, `<` 등)를 제공해야 합니다. `int`, `double`과 같은 산술타입들은 기본적으로 제공되겠지만 사용자 정의 타입이라면 그에 맞는 비교연산자를 구현해서 제공해야 합니다. 그렇지 않으면 당연하게도 compile error가 발생합니다. 이전에는 argument에 대한 정보를 출력하기 위해 `<<` 연산자도 필요했지만 현재는 그 부분은 꼭 제공하지 않아도 괜찮습니다. 만약 argument가 `<<`연산자를 지원한다면 assertion이 실패했을 때 정의된 연산자를 통해 관련정보를 출력하게 됩니다. 반대로 지원하지 않는다면 googletest가 출력할 수 있는 방법을 최대한 찾게 됩니다. 이러한 출력정보에 관련한 더 자세한 내용은 [여기](https://github.com/google/googletest/blob/master/googlemock/docs/cook_book.md#teaching-gmock-how-to-print-your-values)을 참고하세요. 위의 assertion을 사용하려면 `val1`, `val2`와 같은 argument들이 assertion 종류에 맞는 비교연산자(`==`, `<` 등)를 제공해야 합니다. `int`, `double`과 같은 산술타입들은 기본적으로 제공되겠지만 사용자 정의 타입이라면 그에 맞는 비교연산자를 구현해서 제공해야 합니다. 그렇지 않으면 당연하게도 compile error가 발생합니다. 이전에는 argument에 대한 정보를 출력하기 위해 `<<` 연산자도 필요했지만 현재는 그 부분은 꼭 제공하지 않아도 괜찮습니다. 만약 argument가 `<<`연산자를 지원한다면 assertion이 실패했을 때 정의된 연산자를 통해 관련정보를 출력하게 됩니다. 반대로 지원하지 않는다면 googletest가 출력할 수 있는 방법을 최대한 찾게 됩니다. 이러한 출력정보에 관련한 더 자세한 내용은 [여기](../../../googlemock/docs/kr/cook_book.md#gmock이-사용자타입-정보도-출력-가능하게-만들기)을 참고하세요.
이처럼 assertion을 사용자정의 타입과 함께 사용하는 것이 가능하지만, 비교연산자도 함께 제공해야만 합니다. 다만, 이렇게 비교연산자를 제공하는 것은 Google [C++ Style Guide](https://google.github.io/styleguide/cppguide.html#Operator_Overloading)에서 권장하는 내용은 아니기 떄문에 비교연산자가 아닌 별도의 function을 통해 비교를 수행한 후에 그 결과인 `bool`값만 `ASSERT_TRUE()` 혹은 `EXPECT_TRUE()` 를 통해 검사하는 것도 괜찮습니다. 이처럼 assertion을 사용자정의 타입과 함께 사용하는 것이 가능하지만, 비교연산자도 함께 제공해야만 합니다. 다만, 이렇게 비교연산자를 제공하는 것은 Google [C++ Style Guide](https://google.github.io/styleguide/cppguide.html#Operator_Overloading)에서 권장하는 내용은 아니기 떄문에 비교연산자가 아닌 별도의 function을 통해 비교를 수행한 후에 그 결과인 `bool`값만 `ASSERT_TRUE()` 혹은 `EXPECT_TRUE()` 를 통해 검사하는 것도 괜찮습니다.
@ -100,9 +100,9 @@ Argument가 변수형태라면 assertion코드가 수행되는 시점에 저장
포인터에 대해서 `ASSERT_EQ()`를 사용하게 되면 의도한 것과 다르게 동작할 수도 있습니다. 왜냐하면 포인터가 가리키는 대상 전체가 아니라 가키리는 곳의 주소값만 비교하기 떄문입니다. 예를 들어, C언어 문자열(e.g. `const char*`) 2개를 비교한다고 가정하면 일반적으로 문자열 전체가 같은지를 비교하려는 목적일 것입니다. 그러나 여기서는 문자열을 비교하는 것이 아니라 memory location만 검사하게 됩니다. 만약, C언어 문자열의 내용을 비교하고 싶다면 `ASSERT_STREQ()`를 사용해야 합니다. 나중에 자세하게 설명하겠지만 C 문자열이 `NULL`이라는 것을 판정하려면 `ASSERT_STREQ(c_string, NULL)`를 사용하면 됩니다. C++11이 지원되는 경우에는 `ASSERT_EQ(c_string, nullptr)` 도 가능합니다. 마지막으로 2개의 string object를 비교한다면 `ASSERT_EQ`를 사용해야 합니다. 포인터에 대해서 `ASSERT_EQ()`를 사용하게 되면 의도한 것과 다르게 동작할 수도 있습니다. 왜냐하면 포인터가 가리키는 대상 전체가 아니라 가키리는 곳의 주소값만 비교하기 떄문입니다. 예를 들어, C언어 문자열(e.g. `const char*`) 2개를 비교한다고 가정하면 일반적으로 문자열 전체가 같은지를 비교하려는 목적일 것입니다. 그러나 여기서는 문자열을 비교하는 것이 아니라 memory location만 검사하게 됩니다. 만약, C언어 문자열의 내용을 비교하고 싶다면 `ASSERT_STREQ()`를 사용해야 합니다. 나중에 자세하게 설명하겠지만 C 문자열이 `NULL`이라는 것을 판정하려면 `ASSERT_STREQ(c_string, NULL)`를 사용하면 됩니다. C++11이 지원되는 경우에는 `ASSERT_EQ(c_string, nullptr)` 도 가능합니다. 마지막으로 2개의 string object를 비교한다면 `ASSERT_EQ`를 사용해야 합니다.
포인터가 아무것도 가리키지 않는지 확인하고자 할 때는 `*_EQ(ptr, NULL)`, `*_NE(ptr, NULL)`가 아니라 `*_EQ(ptr, nullptr)`, `*_NE(ptr, nullptr)`와 같이 구현해야 합니다. `nullptr`을 사용해야 타입관련 문제가 발생하지 않습니다. 이와 관련한 자세한 내용은 [FAQ](faq.md)를 참조하십시오. 포인터가 아무것도 가리키지 않는지 확인하고자 할 때는 `*_EQ(ptr, NULL)`, `*_NE(ptr, NULL)`가 아니라 `*_EQ(ptr, nullptr)`, `*_NE(ptr, nullptr)`와 같이 구현해야 합니다. `nullptr`을 사용해야 타입관련 문제가 발생하지 않습니다. 이와 관련한 자세한 내용은 [FAQ](faq.md#왜-expect_eqnull-ptr-assert_eqnull-ptr만-지원하고-expect_nenull-ptr-assert_nenull-ptr은-지원하지-않나요)를 참조하십시오.
만약 부동소수점 타입을 확인하고자 할 때는 반올림관련 문제가 있기 때문에 별도의 assertion을 사용해야 합니다. 자세한 내용은 [Advanced googletest Topics](advanced.md)를 참조하세요. 만약 부동소수점 타입을 확인하고자 할 때는 반올림관련 문제가 있기 때문에 별도의 assertion을 사용해야 합니다. 자세한 내용은 [Advanced googletest Topics](advanced.md#floating-point-비교하기)를 참조하세요.
이 섹션의 macro들은 narrow string(string), wide string(wstring) 양쪽 모두에 대해서 잘 동작합니다. 이 섹션의 macro들은 narrow string(string), wide string(wstring) 양쪽 모두에 대해서 잘 동작합니다.
@ -127,7 +127,7 @@ Argument가 변수형태라면 assertion코드가 수행되는 시점에 저장
**Availability**: Linux, Windows, Mac. **Availability**: Linux, Windows, Mac.
**See also**: 기본적인 문자열 비교 외에 추가로 제공되는 기능(substring, prefix, suffix, regular expression 비교하기 등)이 궁금하다면 [Advanced googletest Guide](https://github.com/google/googletest/blob/master/googletest/docs/advanced.md)를 참조하세요. **See also**: 기본적인 문자열 비교 외에 추가로 제공되는 기능(substring, prefix, suffix, regular expression 비교하기 등)이 궁금하다면 [여기](../../../cheat_sheet.md#string-matchers)를 참조하세요.
## 간단한 테스트 ## 간단한 테스트
@ -183,7 +183,7 @@ Fixture를 생성하는 방법
1. `::testing::Test` class를 상속받아서 test fixture class를 하나 만듭니다. 이제 `protected:` 영역에 필요한 내용을 구현할 것입니다. 1. `::testing::Test` class를 상속받아서 test fixture class를 하나 만듭니다. 이제 `protected:` 영역에 필요한 내용을 구현할 것입니다.
2. test fixture class 내부에 여러 Test들이 공유하게 될 데이터(변수)를 선언합니다. 2. test fixture class 내부에 여러 Test들이 공유하게 될 데이터(변수)를 선언합니다.
3. 필요하다면 `SetUp()`이나 default constructor를 정의함으로서 test fixture에 속한 각각의 Test들이 시작될때 공통적으로 수행할 일들(공유자원 자원할당 등)을 구현할 수 있습니다. 이 때, `SetUp()`**`Setup()`**으로 구현하는 대소문자 실수를 하는 경우가 많기 때문에 주의하기 바랍니다. C++11의 `override` 키워드를 사용한다면 실수를 줄일 수 있을 것입니다. 3. 필요하다면 `SetUp()`이나 default constructor를 정의함으로서 test fixture에 속한 각각의 Test들이 시작될때 공통적으로 수행할 일들(공유자원 자원할당 등)을 구현할 수 있습니다. 이 때, `SetUp()`**`Setup()`**으로 구현하는 대소문자 실수를 하는 경우가 많기 때문에 주의하기 바랍니다. C++11의 `override` 키워드를 사용한다면 실수를 줄일 수 있을 것입니다.
4. 필요하다면 `TearDown()`이나 destructor를 정의함으로서 개별 Test가 끝날때마다 공통적으로 수행할 일들(공유자원 자원해제 등)을 구현한 수 있습니다. `SetUp()/TearDown()`과 constructor/destructor를 어떻게 구분해서 사용해야 하는지 궁금하다면 [FAQ](faq.md)을 참조하기 바랍니다. 4. 필요하다면 `TearDown()`이나 destructor를 정의함으로서 개별 Test가 끝날때마다 공통적으로 수행할 일들(공유자원 자원해제 등)을 구현한 수 있습니다. `SetUp()/TearDown()`과 constructor/destructor를 어떻게 구분해서 사용해야 하는지 궁금하다면 [FAQ](faq.md#test-fixture에서-constructordestructor-와-setupteardown중-어느것을-써야하나요)을 참조하기 바랍니다.
5. 필요하다면 각 Test가 공통적으로 수행하게 될 함수(subroutine)를 정의하는 것도 좋습니다. 5. 필요하다면 각 Test가 공통적으로 수행하게 될 함수(subroutine)를 정의하는 것도 좋습니다.
Test fixture를 사용하기 위해서는 개별 Test를 구현할 때, `TEST()` 대신에 `TEST_F()`를 사용해야 합니다. 이러한 `TEST_F`의 첫 번째 argument로는 위에서 `::testing::Test`를 상속받아 생성한 test fixture class의 이름을 전달합니다. Test fixture를 사용하기 위해서는 개별 Test를 구현할 때, `TEST()` 대신에 `TEST_F()`를 사용해야 합니다. 이러한 `TEST_F`의 첫 번째 argument로는 위에서 `::testing::Test`를 상속받아 생성한 test fixture class의 이름을 전달합니다.
@ -363,7 +363,7 @@ int main(int argc, char **argv) {
} }
``` ```
`::testing::InitGoogleTest()`는 command line으로부터 전달된 googletest flag들을 파싱하고 초기화합니다. 사용자는 flag를 통해서도 test program의 동작을 제어할 수 있습니다. Flag와 관련한 상세한 내용들은 [AdvancedGuide](advanced.md)에서 더 자세히 다루고 있습니다. 그리고 `::testing::InitGoogleTest()``RUN_ALL_TESTS()`보다 먼저 호출되어야만 합니다. 그렇지 않으면 flag들이 초기화되지 않은 상태에서 Test가 수행되기 때문에 문제가 발생합니다. `::testing::InitGoogleTest()`는 command line으로부터 전달된 googletest flag들을 파싱하고 초기화합니다. 사용자는 flag를 통해서도 test program의 동작을 제어할 수 있습니다. Flag와 관련한 상세한 내용들은 [AdvancedGuide](advanced.md#test-program을-실행하는-다양한-방법)에서 더 자세히 다루고 있습니다. 그리고 `::testing::InitGoogleTest()``RUN_ALL_TESTS()`보다 먼저 호출되어야만 합니다. 그렇지 않으면 flag들이 초기화되지 않은 상태에서 Test가 수행되기 때문에 문제가 발생합니다.
윈도우 환경에서는 `InitGoogleTest()`가 wide string에도 잘 동작되기 때문에 `UNICODE`모드에서 컴파일 된 프로그램에서도 사용할 수 있습니다. 윈도우 환경에서는 `InitGoogleTest()`가 wide string에도 잘 동작되기 때문에 `UNICODE`모드에서 컴파일 된 프로그램에서도 사용할 수 있습니다.