반응형

제목: CPPUnit을 통한 단위 테스팅(Unit testing with CPPUnit)

저자: JM Navarro, 스페인

문서유형: 웹 문서, 2003

 

C/C++ 프로젝트에서 개발 단위의 품질을 향상시키기 위한 단위 테스트 작성에 어떻게 CPPUnit을 활용하는지 설명한 자료



단위 테스팅 설계 예

아래는 두 개 숫자를 더하는 일을 책임지는 프로그램을 C 언어로 작성한 예이다.

[단위 모듈 예 – C 함수]


위 단위를 테스트하는 프로그램이 아래처럼 별개 모듈(C 함수)로 작성됨. 모든 가능한 덧셈의 경우를 체크하고 모듈이 테스트를 통과했는지 아닌지를 나타내는 TRUE 또는 FALSE를 리턴

[단위 테스트 케이스 예 1]


위 테스트에서 체크하는 덧셈의 경우는 양수+양수, +, 양수+, 음수+, 양수+음수, 음수+양수, 음수+음수 이다. 각 테스트가 덧셈 결과를 예상 값과 비교하여 다르면 FALSE 리턴. 실행 경로가 마지막 줄에 도달하면 모든 테스트를 올바르게 통과한 것으로 간주하고 TRUE 리턴

 

이런 모듈을 테스트 케이스(Test Case)’라 부르며, 어떤 하나의 단위에 대해 테스터가 확인하는 체크사항들의 집합을 나타낸다. 테스트 케이스의 모든 검증은 특정한 하나의 단위 시나리오(unit scenario)와 관련이 있어야 함. 여기서는 덧셈 연산이 피연산자의 부호(operand's sign)에 어떻게 동작하는지를 체크하고 있음

 

다른 시나리오를 체킹하기 위한 다른 테스트 케이스도 작성 가능하다. 예를 들면, 아래 예는 수학적인 덧셈 속성과 관련 addition 모듈의 동작을 체크하는 또 다른 테스트 케이스이다.

[단위 테스트 케이스 예 2]


위에 나온 두 개의 테스트 케이스는 하나의 테스트 스위트(Test Suite)’로 구축될 수 있음. , 테스트 스위트는 동일한 단위를 테스트 하는 테스트 케이스들의 집합이다.

 

모든 테스트 케이스 및 테스트 스위트가 단위 모듈을 코딩하는 동안에 개발되어야 하며, 해당 단위가 변경될 때마다 상응하는 단위 테스트도 변경을 반영해야 한다(테스트 케이스를 수정하거나 또는 새로운 것을 추가).


단위 테스팅 프레임워크

  • 단위 테스팅 프레임워크는 애플리케이션의 모듈(, 클래스, 함수, 라이브러리)을 테스트하는 모듈을 개발자가 작성할 수 있도록 도와줌
  • Kent Beck Eric Gamma가 단위 테스팅을 최대한 자동화 하기 위한 Java 클래스들의 집합을 작성하였는데 이것이 JUnit이며 테스팅 세계에서 큰 인기를 얻음
  • 다른 개발자들이 이 JUnit 코드를 타 언어로 포트함(, C/C++을 위한 CUnitCPPUnit, Delphi를 위한 DUnit, Visual Basic을 위한 VBUnit, .NET 플랫폼을 위한 NUnit ). 이런 모든 프레임워크가 약간의 언어 의존적인 예외사항을 제외하고 비슷한 규칙을 적용함
  • CPPUnit은 객체 지형 프로그래밍을 사용하므로 상속(inheritance), 캡슐화(encapsulation), 다형성(polymorphism) 같은 개념이 포함됨. 또한 CPPUnitC++의 구조적 예외 처리(Structured Exception Handling)를 사용하므로 "예외(exception)"의 개념과 throw, try, finally, catch 등의 인스트럭션 및 구조를 이해하고 있어야 한다.

 

CPPUnit 사용하기 예

아래의 DiskData 클래스는 디스크에 데이터를 저장하는 모듈로 크게 두 가지 기능을 함: 디스크 파일에 데이터를 올리고(load) 저장(store) 

[DiskData 클래스 – 단위 모듈 예]


CPPUnit에서는 각 테스트 케이스가 TestCase 클래스로부터 상속된 서브클래스 내부에 구현됨. 위 클래스를 테스트 하기 위해 아래와 같이 테스트 케이스 클래스를 정의(define)함 

[DiskData의 단위 테스트 클래스 정의 예]


위에서 헤더 파일 TestCase.hHelperMacros.h을 반드시 포함해야 함. 첫 번째는 TestCase 베이스 클래스로부터 새 클래스를 도출할 수 있게 해주며, 두 번째는 단위 테스트를 빠르게 정의할 수 있는 매크로를 제공함. 예를 들면 아래와 같은 것들이 있다
-
CPPUNIT_TEST_SUITE: 테스트 스위트 정의를 시작하기 위한 매크로
-
CPPUNIT_TEST: 테스트 케이스를 정의하기 위한 매크로
-
CPPUNIT_TEST_SUITE_END: 테스트 스위트 정의를 끝내기 위한 매크로

 

DiskDataTestCase 클래스는 베이스 클래스의 메쏘드 setUp()tearDown()을 오버라이딩한다. 이 메쏘드들은 자동으로 불리어지며 각 테스트 케이스가 시작하고 끝날 때 각각 실행됨. 테스트 케이스의 실제 로직은 protected 메쏘드 loadTest()storeTest()에 구현됨

 

fixture라 불리는 애트리뷰트를 정의함. 이 포인터가 테스트의 타겟 오브젝트를 잡고 있게 됨. 각 테스트 케이스 이전에 불려지는 setUp()에서 fixture 오브젝트가 생성되고, 테스트 케이스 코드는 이 오브젝트를 사용하여 실행되며, 각 테스트 케이스 실행 후에 호출되는 tearDown()에서 이 오브젝트가 파괴됨. 이런 식으로 테스트 케이스를 실행할 때마다 매번 새로운 fresh 오브젝트를 얻는다.

 

테스트 시퀀스는 대략 아래와 같다.

    테스트 애플리케이션 시작

    "Run" 버튼 클릭

    setUp() 메쏘드 호출; fixture 오브젝트 생성

    첫 번째 테스트 케이스 메쏘드 호출

    tearDown() 메쏘드 호출; fixture 오브젝트를 자유롭게 함(free)

    setUp() 메쏘드 호출; fixture 오브젝트 생성

    두 번째 테스트 케이스 메쏘드 호출

    tearDown() 메쏘드 호출; fixture 오브젝트를 자유롭게 함

    ...

 

아래는 setUp tearDown 메쏘드 구현 코드임. 각각 fixture 오브젝트를 생성하고 자유롭게 풀어주는 일을 책임진다.

[DiskData의 단위 테스트 클래스 구현 예 - setUp과 tearDown 메쏘드]


아래의 loadTest 메쏘드 구현에서는 내부 데이터를 외부 파일의 데이터와 비교하여 동일한지 체크하고, 에러를 찾을 때마다(, 내부 데이터가 외부 데이터와 동일하지 않음) 예외를 발생시킴. 이를 위해 매크로 CPPUNIT_FAIL(message)를 사용하거나 또는 아래와 같은 어써션 매크로를 사용할 수도 있음

  • CPPUNIT_ASSERT(condition): 조건을 체크하고 거짓 시 예외 제기
  • CPPUNIT_ASSERT_MESSAGE(message, condition): 조건을 체크하고 거짓 시 예외 제기. 명세된 메시지 디스플레이
  • CPPUNIT_ASSERT_EQUAL(expected,current): 기대 값이 실제 값과 동일한지 체크하고 다르면 예외 제기. 기대 값과 실제 값 디스플레이
  • CPPUNIT_ASSERT_EQUAL_MESSAGE(message,expected,current): 기대 값과 실제 값이 동일한지 체크하고, 다르면 예외 제기. 기대 값, 실제 값, 명세된 메시지 디스플레이
  • CPPUNIT_ASSERT_DOUBLES_EQUAL(expected,current,delta): 기대 값과 실제 값 차이가 델타보다 작은지 체크하고 실패 시 이 두 값을 디스플레이


[DiskData의 단위 테스트 클래스 구현 예 – loadTest 메쏘드]


위의 단일 테스트 케이스에서 아래와 같은 네 개의 가능한 에러를 테스팅 함

  • load 메쏘드의 리턴 값
  • getData 메쏘드의 리턴 값
  • number 구조 멤버 값
  • string 구조 멤버 값

 

아래 두 번째 테스트 케이스(storeTest)도 비슷한 체계를 따르지만 조금 더 복잡해짐. 여기서는 fixture 데이터를 알려진 데이터로 채우고 이를 또 다른 디스크 파일(data.tmp)에 저장한다. 이어서 이 파일과 원래의 패턴 파일을 비교함(DiskData 클래스의 store 메쏘드가 동일한 파일 구조를 생성해야 하므로 이 두 파일이 같아야 함). 두 파일이 동일한지 비교할 때는 여러 측면을 확인한다(, 버퍼와 파일 사이즈, 버퍼의 콘텐츠).

[DiskData의 단위 테스트 클래스 구현 예 – storeTest 메쏘드]


CppUnit 단위 테스트의 사용자 인터페이스 예

위에서 구현된 테스트들을 등록하고 runner에 추가하는 과정을 거쳐 실행시키면 아래와 같은 MFC 기반 UI 다이얼로그가 디스플레이 됨


위에서 Browse 버튼을 클릭하면 아래와 같은 다이얼로그가 나타남. 단지 하나의 테스트를 선택하거나(녹색 노드) 또는 모든 등록된 테스트를 실행하기 위해 부모인 파란색 노드를 선택할 수 있음



여기서 설명된 데모 프로젝트(8kb)는 아래 사이트들에서 다운로드 받을 수 있음

http://www.codeguru.com/cpp/misc/samples/testingdebugging/article.php/c4685/Unit-Testing-with-CPPUnit.htm

http://www.codeproject.com/Articles/5660/Unit-testing-with-CPPUnit



반응형

+ Recent posts