4. 통합 테스트 VS 단위 테스트 통합 테스트 둘 이상의 모듈을 하나의 그룹으로 테스트 하는 것 소프트웨어에 기대되는 결과를 확인 하는 것. 많은 단위들을 실행 단위 테스트 단일 단위를 분리하여 실행하는 테스트
5. 단위 테스트란 다른 코드를 호출한 후 몇 가지 가정이 성립하는지 검사하는 코드 여기서 '단위(unit)'란 메서드나 함수를 의미 X + Y = Z ?
6. 좋은 단위 테스트 자동화 반복 실행 쉬운 구현 쉬운 실행 빠른 속도 로직 없는 테스트
7. 테스트 프레임워크 CppUnit, UnitTest++, TUT, … 사용하기 쉽고 신뢰할 수 있는 GoogleTest http://code.google.com/p/googletest/ 구글의 제품에 사용 중 Chromium, Protocol Buffers, … 등등
8. Gtest 사용하기 gtest라이브러리 다운로드 gtest.h파일 include 라이브러리 빌드 후 lib 파일 링크 #include <gtesttest.h> #pragma comment(lib, “gtest.lib”) int main(intargc, _TCHAR* argv[]) { ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); }
9. 테스트 문법의 기본 ASSERT_TRUE( ACTUAL )ASSERT_FALSE( ACTUAL ) ASSERT_EQ( EXPECTED, ACTUAL )ASSERT_NE( EXPECTED, ACTUAL ) ASSERT_FLOAT_EQ( EXPECTED, ACTUAL ) ASSERT_STREQ( EXPECTED, ACTUAL)
11. 간단한 테스트의 작성 swap() 함수 구현 X, Y 를 인자로 받고 X = Y, Y = X 로 교환
12. 테스트 파일 생성 Ex) Swap_Test.cpp 테스트스위트, 케이스 이름 결정 보수의 용이성을 위해 테스트 이름을 정한다 테스트 스위트는 테스트 카테고리 케이스 이름은 세부적인 테스트를 나타낸다
13. #include <gtesttest.h> TEST( Swap_Test, Swap_True){ } [==========] Running 1 test from 1 test case. [----------] Global test environment set-up. [----------] 1 test from Swap_Test [ RUN ] Swap_Test.Swap_True [ OK ] Swap_Test.Swap_True (0 ms) [----------] 1 test from Swap_Test (0 ms total) [----------] Global test environment tear-down [==========] 1 test from 1 test case ran. (0 ms total) [ PASSED ] 1 test.
14. #include <gtesttest.h> TEST( Swap_Test, Swap_True ){ int x = 30; int y = 15; swap( x, y ); ASSERT_EQ( 15, x ) << "x must be 15"; ASSERT_EQ( 30, y ) << "y must be 30"; } build => fail 존재하지 않는 함수 호출로 빌드실패
15. #include <gtesttest.h> void swap(int& x, int& y){} TEST( Swap_Test, Swap_True ){ int x = 30; int y = 15; swap( x, y ); ASSERT_EQ( 15, x ) << "x must be 15"; ASSERT_EQ( 30, y ) << "y must be 30"; } build => successtest => failure 빌드 성공, 테스트 실패
16. [==========]Running 1 test from 1 test case. [----------]Global test environment set-up. [----------] 1 test from Swap_Test [ RUN ]Swap_Test.Swap_True c:...wap_Test.cpp(124): error: Value of: x Actual: 30 Expected: 15 x must be 15 [ FAILED ] Swap_Test.Swap_True (0 ms) [----------]1 test from Swap_Test (0 ms total) [----------]Global test environment tear-down [==========]1 test from 1 test case ran. (0 ms total) [ PASSED ] 0 tests. [ FAILED ] 1 test, listed below: [ FAILED ] Swap_Test.Swap_True 1 FAILED TEST
17. [==========]Running 1 test from 1 test case. [----------]Global test environment set-up. [----------] 1 test from Swap_Test [ RUN ]Swap_Test.Swap_True c:...wap_Test.cpp(124): error: Value of: x Actual: 30 Expected: 15 x must be 15 [ FAILED ] Swap_Test.Swap_True (0 ms) [----------]1 test from Swap_Test (0 ms total) [----------]Global test environment tear-down [==========]1 test from 1 test case ran. (0 ms total) [ PASSED ] 0 tests. [ FAILED ] 1 test, listed below: [ FAILED ] Swap_Test.Swap_True 1 FAILED TEST
18. [==========] Running 1 test from 1 test case. [----------] Global test environment set-up. [----------] 1 test from Swap_Test [ RUN ] Swap_Test.Swap_True c:...wap_Test.cpp(124): error: Value of: x Actual: 30 Expected: 15 x must be 15 [ FAILED ] Swap_Test.Swap_True (0 ms) [----------] 1 test from Swap_Test (0 ms total) [----------] Global test environment tear-down [==========] 1 test from 1 test case ran. (0 ms total) [ PASSED ] 0 tests. [ FAILED ] 1 test, listed below: [ FAILED ] Swap_Test.Swap_True 1 FAILED TEST … ASSERT_EQ( 15, x ) << "x must be 15“; …
19. #include <gtesttest.h> void swap(int& x, int& y){ int t = x; y = x; x = t; } TEST( Swap_Test, Swap_True ){ int x = 30; int y = 15; swap( x, y ); ASSERT_EQ( 15, x ) << "x must be 15"; ASSERT_EQ( 30, y ) << "y must be 30"; } build => successtest => pass 테스트 통과
20. [==========] Running 1 test from 1 test case. [----------] Global test environment set-up. [----------] 1 test from Swap_Test [ RUN ]Swap_Test.Swap_True [ OK ]Swap_Test.Swap_True (0 ms) [----------] 1 test from Swap_Test (0 ms total) [----------] Global test environment tear-down [==========] 1 test from 1 test case ran. (0 ms total) [ PASSED ] 1 test.
21. 의존성 제거 클래스 간 복합적인 관계 의존성 존재 테스트 저해 설계 : 파일, 스레드, 통신등 외부 의존물을 사용 통합테스트 => 단위 테스트
25. class CPacketParser { public: ...... MSG_BASE* ParsePacket( const char* pBuf, size_tpacketSize ) { MSG_BASE* pMsg = (MSG_BASE*)pBuf; ... // 검증 코드 및 데이터 채우기 return pMsg; } ...... };
26. class CConnectionManager { CSendQueue* m_pSendQueue; public: ...... void SendPacket( MSG_BASE* pMsg ) { // 실제로 메시지를 보내는 코드 m_pSendQueue->PostMessage(pMsg); } ...... };
27. class CConnectionManager { CSendQueue* m_pSendQueue; public: ...... void SendPacket( MSG_BASE* pMsg ) { // 실제로 메시지를 보내는 코드 m_pSendQueue->PostMessage(pMsg); } ...... };