반응형

제목: CppUnit 설명서(CppUnit Cookbook)

저자: Michael Feathers

문서유형: 웹 문서

출처 http://cppunit.sourceforge.net/doc/1.8.0/cppunit_cookbook.html

 

CppUnit 테스트 프레임워크을 처음 접한 이들의 이해를 돕기 위해 CppUnit에서 사용되는 기본적인 개념에 대해 간단히 설명 자료



CppUnit으로 간단한 테스트 케이스 작성 예

  • 클래스 TestCase의 서브클래스를 만들고, runTest() 메쏘드를 오버라이딩 한다.
  • 특정 값을 체크하기 위해 CPPUNIT_ASSERT(bool)을 호출하고 테스트 성공 시 참(true)이어야 하는 표현식을 준다.
  • 예를 들어, 복소수(complex number) 클래스를 위한 동등성 비교 테스트가 아래처럼 작성됨


위의 예는 매우 간단한 테스트일 뿐이고 대개는 동일한 오브젝트 셋 상에서 실행되어야 하는 여러 개의 작은 테스트 케이스들을 가지게 되며 이를 위해 fixture를 사용한다.


Fixture

Fixture는 한 무리의 테스트 케이스 집합을 위한 기지(base) 역할을 하는 오브젝트들의 집합으로 개발을 하면서 테스팅을 진행 시에 매우 유용하다. 예를 들어, 복소수 클래스를 개발 중이라고 가정했을 때 먼저 아래처럼 이름이 Complex인 비어있는 클래스를 정의한다.


위에 나온 ComplexNumberTest 클래스의 인스턴스를 생성하고 코드를 컴파일 하면 컴파일러 에러가 나타남. 테스트가 == 오퍼레이터를 사용하지만 이것이 정의되지 않았으므로 아래처럼 코드를 구현한다.


이제 테스트를 컴파일하고 실행시킨다. 이번에는 컴파일은 되지만 테스트가 실패함(== 오퍼레이터가 정확하게 작동하게 하려면 좀 더 작업이 필요함). 아래와 같이 구현 한 후에 컴파일하고 테스트를 실행시키면 테스트가 통과한다


이제 새로운 오퍼레이션과 새로운 테스트를 추가할 준비가 되었으며 이 시점에 fixture가 유용해진다.  , 3~4개의 복소수를 인스턴스화하고 이것들을 여러 테스트를 거쳐 재사용하는 편이 테스트 수행에 효율적임

 

그러기 위해서 아래와 같은 작업을 해야 한다.

  • fixture의 각 부분을 위한 멤버 변수 추가  
  • 변수를 초기화하기 위해 setUp() 오버라이딩 한다.  
  • setUp()에 할당한 영구 리소스를 풀기 위해 tearDown() 오버라이딩 한다.  


테스트 케이스(Test Case)

fixture를 사용하여 개별 테스트를 작성하고 호출하기 위해서는 테스트 케이스를 fixture 클래스의 메쏘드로 작성하고 이 메쏘드를 실행시키는 TestCaller를 생성한다


각 테스트 케이스를 위한 인스턴스들을 아래와 같이 생성하고 실행할 수 있다.


TestCaller 생성자(constructor)의 두 번째 인수(argument)ComplexNumberTest 상의 메쏘드 주소이며, TestCaller가 실행될 때 그 특정 메쏘드가 실행된다. 실행 결과를 디스플레이 하는 데는 대개 TestRunner를 사용함

 

태스트 스위트(Suite)

여러 개의 테스트가 존재하는 경우 이들을 한번에 실행할 수 있는 스위트로 구성한다. CppUnit은 다수의 TestCase들을 함께 실행시키는 TestSuite 클래스를 제공함. 테스트 스위트를 생성하기 위해 아래와 같이 코딩 한다.


TestSuite TestCase를 부르는 호출자만 포함하는 것은 아니며 Test 인터페이스를 구현하는 것이라면 어떤 오브젝트든 포함할 수 있다. 예를 들어, 개발자 A가 자신의 TestSuite 을 생성하고 개발자 B도 자신의 코드에 TestSuite 생성했을 , 이 둘을 모두 포함하는 또 다른 TestSuite 생성하여 둘을 같이 실행시킬 수 있다(아래 예).


TestRunner

테스트 스위트를 실행하고 그 결과를 디스플레이 하기 위해 static 메쏘드 suite를 가지고 TestRunner 프로그램에 해당 스위트가 액세스 가능하게 만든다. 예를 들어, ComplexNumberTest 스위트를 TestRunner 에서 가용하게 만들기 위해 ComplexNumberTest에 아래 코드를 추가한다.


텍스트 버전을 사용하기 위해서는 Main.cpp에 테스트를 위한 헤더 파일을 아래와 같이 포함시킨다.


그리고 main() 함수에서 addTest(CppUnit::Test *) 호출을 추가한다.


TestRunner가 테스트를 실행시키고, 모든 테스트가 통과하면 알림 메시지를 준다. 실패하면 아래와 같은 정보를 줌

  • 실패한 테스트 케이스 명
  • 테스트를 포함하는 소스 파일 명
  • 실패가 발생한 라인 번호
  • 실패를 발견한 CPPUNIT_ASSERT() 호출 내의 모든 텍스트

 

CppUnit failureserror를 구분함. Failureassertions을 통해 체크하는 예상된 실패이고, Errors 는 예기치 못한 문제이다(, 0으로 나누기, C ++ 런타임이나 구현 코드에 의해 발생된 예외).


Helper Macros

Fixture static suite() 메쏘드를 구현하는 것은 반복적이고 에러가능성 높은 작업이므로 이를 자동화하기 위해 한 무리의 매크로 집합이 생성됨. 아래는 이런 매크로를 사용하여 ComplexNumberTest를 재작성 한 예이다.


먼저 아래와 같이 클래스 명을 매크로로 넘겨 주어 스위트를 선언한다

static suite() 메쏘드에 의해 생성된 스위트는 이 클래스 명을 따서 명명됨. 아래와 같이 fixture의 각 테스트 케이스를 선언한다.

끝으로 스위트 선언을 마친다.

이 시점에 아래의 signature를 가진 메쏘드가 구현됨

fixture의 나머지는 변경 없이 그대로 남겨짐


스위트에 추가된 TestCaller의 이름은 fixture명과 메쏘드 명이 조합된 것임. 이 경우 "ComplexNumberTest.testEquality" "ComplexNumberTest.testAddition"가 된다.

 

Helper macros 는 공통 어써션을 작성하는 것을 도움. 예를 들어, 0으로 나누기에서 ComplexNumber MathException을 발생시키는 것을 체크하기 위해 CPPUNIT_TEST_EXCEPTION을 사용하여 테스트를 스위트로 추가하고(기대하는 예외 타입을 명세함), 테스트 케이스 메쏘드를 작성한다. 기대하는 예외(exception)가 발생되지 않으면 어써션 실패가 보고된다.


TestFactoryRegistry

Fixture 스위트를 test runner에 추가하는 걸 잊거나(다른 파일에 있어서 잊기가 쉬움) 또는 모든 테스트 케이스 헤더를 포함함으로 인해 야기되는 컴파일 병목 문제를 해결하기 위해 TestFactoryRegistry 가 생성됨. TestFactoryRegistry는 초기화 시에 스위트가 등록될 수 있는 장소이다. 예를 들면, ComplexNumber 스위트를 .cpp 파일에 등록하기 위해 아래를 추가한다.


막후에서는 정적 변수 타입 AutoRegisterSuite가 선언되며, 생성(Construction) 시 이것이 TestSuiteFactoryTestFactoryRegistry에 등록한다TestSuiteFactory는  ComplexNumber::suite()에 의해 리턴된  TestSuite 을 리턴한다.

텍스트 test runner를 사용하여 테스트 실행시키기 위해 더 이상 fixture를 포함할 필요가 없다.


먼저 TestFactoryRegistry 의 인스턴스를 회수한다.


CPPUNIT_TEST_SUITE_REGISTRATION()을 사용하여 등록된 모든 테스트 스위트를 포함하고 있는 TestFactoryRegistry에 의해 생성된 새로운 TestSuite 얻어 추가한다


Post-build check

단위 테스트를 빌드 프로세스에 통합하려면 애플리케이션이 반드시 0이 아닌 다른 값을 리턴해야 한다(에러가 있음을 나타내기 위해). TestRunner::run() 이 실행이 성공적인지를 나타내는 부울 값을 리턴하므로  아래처럼 메인 프로그램을 업데이트 함


이제 컴파일 후에 애플리케이션을 실행할 필요가 있음. Visual C++에서는 이 작업이 아래 명령어를 더하여 Project Settings/Post-Build 단계에서 수행됨. 애플리케이션 실행 경로로 확장됨. 이 기법을 활용하는 프로젝트 examples/cppunittest/CppUnitTestMain.dsp 참조  



반응형

+ Recent posts