E D R , A S I H C RSS

Cpp Unit

1. 설치

Visual C++ 6.0 기준으로 설명한다. 다른 언어들에 비해 환경설정을 위해 해야 할 부분이 많으므로 인내심을 가지고 따라해야 한다.

1.1. 준비 1 - 다운 받고 한번 이상 꼭 해주어야 할 사항

1.1.1. Library 화일 생성하기

처음 압축화일을 받고 풀면 lib 폴더에 Library 관련 화일들이 없다. 이것을 만드는 방법

  • Library 화일 생성 : ~cpp ...cppunitexamplesexamples.dsw 을 연뒤 ~cpp WorkSpace ~cpp FileView 에서 ~cpp CppUnitTestApp files 에 Set as Active Project로 맞춰준다.(기본값으로 되어 있다.) 그리고 컴파일 해주면 lib 폴더에 library 화일들이 생성될 것이다.
컴파일 후 실행해 보면 다음과 같은 (혹은 비슷한) 결과를 볼수 있다.
이로서 가장 기본이 되는 셋팅은 완료된다.

1.2. 준비 2 - CppUnit을 사용할 프로젝트 열 때 해주어야 할 기본 세팅

1.2.1. include, library directory 맞춰주기 (둘중 하나를 선택한다.)

Library : ~cpp ...cppunit-x.x.xlib

Include : ~cpp ...\cppunit-x.x.xinclude
  1. 전체 세팅 변경시
    1. Tools -> Options -> Directories -> Include files 에서 해당 cppunit
    2. Tools -> Options -> Directories -> Library files 에서 역시 lib
  2. 해당 프로젝트에만 적용시
    1. Project -> Settings -> C/C++ -> Preprocessor -> Additional include directories
    2. Project -> Settings -> Link -> Input -> Additional Library directories

  1. RTTI 를 체크해준다.
  2. Project Setting - Link - General - object/library 에 cppunitd.lib, testrunnerd.lib 를 추가해준다.
  3. 해당 프로젝트가 있는 곳의 debug 등의 디렉토리에 해당 lib 디렉토리에 있는 testrunnerd.dll 을 복사해준다. 이는 Project Setting - Post-Build-step 의 Post-build-command 에 다음을 추가해주면 컴파일 할때마다 dll 화일을 자동으로 복사해준다.

~cpp 
copy c:cppunitlibtestrunnerd.dll .
  • Project Setting - Code Generation - Use Run-Time library 를 다음으로 맞춰준다.
    • Release Mode : Mulithreaded DLL
    • Debug Mode : Debug Multihreaded DLL
  • app 클래스에 다음과 같은 runner 실행을 위한 코드를 추가한다. 다음 코드를 추가함으로써 프로그램 실행시에 GUI Test Runner 가 실행된다.

~cpp 
#include <msvc6/testrunner/testrunner.h>
#include <cppunit/extensions/testfactoryregistry.h>
.
.
.
BOOL CMyApp::InitInstance () {
.
.
    // Dialog Based 의 경우는 dlg.DoModal ()을 실행하기 전에 적어준다.
    TestRunner  runner;
    runner.addTest ( CppUnit::TestFactoryRegistry::getRegistry().makeTest() );
    runner.run ();
}

2. UnitTest TestCase의 작성

Test Case 가 될 Class는 ~cpp CppUnit::TestCase 를 상속받는다.

2.1. ExampleTestCase.h

~cpp 
#ifndef CPP_UNIT_EXAMPLETESTCASE_H 
#define CPP_UNIT_EXAMPLETESTCASE_H 
 
#include <cppunit/TestCase.h> 
#include <cppunit/extensions/HelperMacros.h> 
 
class ExampleTestCase : public CppUnit::TestCase 
{ 
  CPPUNIT_TEST_SUITE( ExampleTestCase );      // TestSuite
  CPPUNIT_TEST( testExample );                // TestCase 의 등록.
  CPPUNIT_TEST_SUITE_END();                   // TestSuite 의 끝. 이로서 해당 Test Case 에 자동으로 suite 메소드가 만들어진다.
protected: 
        void                    testExample (); 
public: 
        void                    setUp (); 
        void                    tearDown (); 
}; 
#endif 

2.2. ExampleTestCase.cpp

~cpp   
#include "stdafx.h"                      // MFC 인 경우.
#include "hostapp.h"                     // MFC 인 경우 해당 App Class
#include "ExampleTestCase.h" 
 
CPPUNIT_TEST_SUITE_REGISTRATION( ExampleTestCase );      // TestSuite 를 등록하기. TestRunner::addTest 가 필요없다.
 
 
void ExampleTestCase::testExample ()     // 테스트 하려는 함수.
{ 
        CPPUNIT_ASSERT (1 == 2); 
} 
 
void ExampleTestCase::setUp ()          // fixture 관련 셋팅 코드. 
{ 

} 

void ExampleTestCase::tearDown ()       // fixture 관련 셋팅 코드.
{ 

} 
 
~cpp 
#include <iostream> 
using namespace std;

#include <cppunit/ui/text/TestRunner.h>
#include <cppunit/TextTestResult.h>

#ifndef _SIMPLE_H_
#define _SIMPLE_H_

#include <cppunit/TestCase.h>
#include <cppunit/extensions/HelperMacros.h>

class SimpleTest : public CppUnit::TestFixture { 
public: 
	CPPUNIT_TEST_SUITE( SimpleTest );
	CPPUNIT_TEST ( testOne );
	CPPUNIT_TEST ( testTwo );
	CPPUNIT_TEST_SUITE_END();

	void testOne () {
		CPPUNIT_ASSERT( 1 == 2 );
		CPPUNIT_ASSERT( 3 == 4 );
	}

	void testTwo () {
		CPPUNIT_ASSERT( 1 == 1 );
		CPPUNIT_ASSERT( 3 == 3 );
	}

};

#endif

int main( int argc, char* argv[] )
{
	CppUnit::TextUi::TestRunner runner;
	CppUnit::TextTestResult result;
	
	runner.addTest (SimpleTest::suite());
	
	runner.run("", false);

	return 0;
}

2.2.1. GUI Test Runner 의 이용

GUI Programming 을 하기 위해 winmain 이 시작인 코드의 경우(MFC GUI Programming 포함) 콘솔창이 뜨지 않는다. 이 경우 GUI Runner 를 실행해줘야 한다.
~cpp 
#include <cppunit/ui/text/TestRunner.h>

~cpp 
#include <cppunit/ui/mfc/TestRunner.h> 
로 수정한뒤, testrunnerd.dll 를 해당 프로젝트화일에 복사해주면 된다.

Runner 실행코드는 다음과 같이 MFC UI 의 Test Runner 를 이용한다.
~cpp 
	CppUnit::MfcUi::TestRunner runner;
	CppUnit::TextTestResult result; 
	
	runner.addTest (SimpleTest::suite()); 
	
	// runner.run("", false); 
	runner.run();

2.2.2. Win32 API or Console 프로그래밍시

Win API Programming 시에 Text Runner 를 이용하여 이용 가능. 다음과 같은 식으로 쓸 수도 있다.
~cpp 
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE, LPSTR, INT) {

	CppUnit::TextUi::TestRunner runner;

	CppUnit::OStringStream stream;
	CppUnit::TextOutputter* outputter = new CppUnit::TextOutputter(&runner.result(), stream);

	runner.setOutputter(outputter);	

	runner.addTest(SimpleTest::suite());

	runner.run();

	MessageBox(NULL, stream.str().c_str(), "Test", MB_OK);	

	return 0;
}


~cpp 
#include <cppunit/extensions/TestFactoryRegistry.h>
#include <cppunit/ui/text/TestRunner.h>
#include <cppunit/extensions/HelperMacros.h>

class SimpleTestCase : public CppUnit::TestCase {
public:
	CPPUNIT_TEST_SUITE ( SimpleTestCase );
	CPPUNIT_TEST(testOne);
	CPPUNIT_TEST(testTwo);
	CPPUNIT_TEST_SUITE_END();
public:
	void testOne() {
		CPPUNIT_ASSERT_EQUAL(10,10);
	}
	void testTwo() {
		CPPUNIT_ASSERT_EQUAL(20,20);
	}
};
CPPUNIT_TEST_SUITE_REGISTRATION (SimpleTestCase);

int main() {
	CppUnit::TextUi::TestRunner runner;
	CppUnit::TestFactoryRegistry &registry = CppUnit::TestFactoryRegistry::getRegistry();
	runner.addTest(registry.makeTest());
	runner.run();

	return 0;
}

2.2.3. assertEqual 의 이용

코드를 보면 알겠지만, ASSERT 문들에 해서 전부 매크로를 이용한다. 만일 이를 다른 언어들의 UnitTest Framework 처럼 assertEqual 이나 assert 문으로 쓰고 싶다면, 다음의 문장을 cppunit library 를 include 하기전에 추가해준다.
~cpp 
#define CPPUNIT_ENABLE_NAKED_ASSERT 1

기타 자세한 내용들은 (flag 들) cppunit/portability.h 를 참조하면 된다.

2.2.4. 주의점

  • 초기 준비할때 삽질하는 경우가 많다. -_-; CppUnit 의 경우는 헤더화일들의 include 순서들이 중요하다. 그리고 MFC 의 경우는 stdafx.h 를 각각의 화일들마다 include 해줘야 한다. (API에서 CppUnit 는 어떨지 궁금해진다.)
  • 중간중간에 Rebuild 해줄 필요가 있다. (제로 했다고 생각했는데 Test Case가 Failure 가 나는 경우에는 한번 의심할 필요가 있다.)
----
MSVC에서 에러가 나는 경우 부분은 CppUnit FAQ를 참고하면 해결할 수 있다. http://cppunit.sourceforge.net/FAQ


~cpp 
2) Questions related to Microsoft Visual VC++

2.1) Why does my application crash when I use CppUnit?
   
   You probably forgot to enable RTTI in your project/configuration. RTTI are disabled by default. 
   Enable RTTI in Projects/Settings.../C++/C++ Language. Make sure to do so for all configurations.

2.2) Why does the compiler report an error when linking with CppUnit library?

   You most likely are not using the same C-RunTime library as CppUnit.
   In Release configuration, CppUnit use "Mulithreaded DLL".
   In Debug configurations, CppUnit use "Debug Multihreaded DLL".
   Check that Projects/Settings.../C++/Code Generation is indeed using the correct library.

----
1.9.10 버전을 기준으로 VC++ 7.0 (VS.NET) 환경 세팅을 보인다.

2.2.5. 준비 - 1 lib, dll 만들기

1.9.10 은 sf.net 에 릴리즈 되어 있지 않다.
http://cppunit.sourceforge.net/snapshot/ 에서 받아올수 있다.
CppUnitCompile0.GIF
VC++ 6.0 파일을 받으면
CppUnitCompile2.GIF
이렇게 변환되어 컴파일 가능하다. 두개의 프로젝트가 에러남, 하지만 dll, lib 생성에는 지장없음
CppUnitCompile3.GIF
다음과 같은 파일들을 Test Case를 작성할 프로그램에 필요하다.

2.2.6. 준비 - 2 TestCase 만들기를 위한 세팅

CppUnitSettigDirectory0.GIF
다음과 같은 디렉토리 상태라고 가정한다.
CppUnitSettigInclude0.GIF
Include 시켜야할 디렉토리 추가(cppuint src 들어 있음)
CppUnitSettigLib0.GIF
라이브러리 디렉토리 세팅
CppUnitSettigLib1.GIF
라이브러리 추가
CppUnitSettigRuntime0.GIF
런타임 환경 세팅
----
싱가폴 국립학의 소프트웨어 공학 프로젝트 수업에서 CppUnit을 사용하고 있는데, http://www.comp.nus.edu.sg/~cs3214s/tools/cppunitVC.html 에 가면 MSVC에서 CppUnit을 사용하는 방법을 쉽게 설명한 안내서를 볼 수 있다.
학교 수업에서 CppUnitCVS를 실제로 쓴다는게 신기하다는; --1002
학교 수업에서 실질적이고 현장에서 직접 쓰이는 도구들을 사용하도록 유도하는 것이 정말 부럽고, 국내 프로젝트/실습 수업에서 그냥 교재의 챕터 하나씩 발표시키고 이를 지켜보고, 평가하고, 끝에 지엽적인 질문으로 발표자 골탕 먹이는 일 외에도, 교수(혹은 조교)가 해 줄 수 있는 것이 이렇게 많다는 것이 신기하다는; --JuNe
  • vc7 용 cppunit 은 없나요.? 환경이 너무 많이 바뀌어서 저걸 적용하려니까 힘드네요..-_- (인스톨 도큐먼트 보니까 최소 6.0이라고 나와있기는 하던데..) 임인택
    vc7 도 똑같이 하면 됨. 단, 프로젝트의 라이브러리 설정이 vc7 의 다른 메뉴에 있어서 그렇지. --1002
  • 전 "Project Setting - Link - General - object/library 에 cppunitd.lib, testrunnerd.lib 를 추가해준다."라고 해서 추가 해줬더니
linking...
LINK : fatal error LNK1104: cannot open file "cppunitd.lib,"
Error executing link.ex

라고 link에러가 나는데 왜 그렇죠? 흐 무척 삽질하고 있습니다.-- FredFrith

library path 문제일 것 같은데요. 아니면, CppUnit 이 컴파일 되어있는지 확인해야 할것 같습니다. (lib 디렉토리에 cppunitd.lib 화일이 있는지 확인) --1002

  • VC6에서 작업하고 있는데요. CFileDialog를 통해 파일 path를 받으려고 하는데, TestRunnerCFileDialog 명령을 수행하는 것보다 먼저 동작해 파일 경로를 받을 수 없습니다.. TestRunner가 실행되는 시점을 조절할 수 있나요? --FredFrith
어떠한 부분을 테스트하고 싶으신건지 궁금합니다. (테스트 상이 되는 코드부분과 테스트 코드를 보여주시면 좀 더 도움이 될듯합니다.) --1002

* 공간이 좁아 전부 올리기가 힘든데, file upload 할 수는 없나요? -- FredFrith

* 웹서핑을 통해 이곳에 왔습니다. 위에서 ExampleTestCase 클래스와 SimpleTest와의 관계는 어떻게 됩니까?
main에서는 ExampleTestCase를 사용하지 않는데요...

Win32 API환경에서 MFC TestRunner를 사용하는 방법을 찾았으면 좋겠군요. 여러가지로 시도해보았는데 MFC에 한 지식이 너무 부족해서 계속 실패하네요. --응준

GUI Runner 말씀이신가요? 실험 좀 해보고 리플하겠습니다. --1002

이 부분에 나오는 Code Generation부분이 어디에 있는지 찾지를 못 하겠네요. 메뉴가 숨어있기라도 한 건지...@-@;; --leoanrdong
~cpp 
Project Setting - Code Generation - Use Run-Time library 를 다음으로 맞춰준다. 

Release Mode : Mulithreaded DLL 

Debug Mode : Debug Multihreaded DLL 
- C/C++ 탭에 보면 category가 있는데 거기에 code generation 이 있습니다. - 임인택
고마워요. 해결하고 이제 돌릴 수 있네요 :) -Leonardong

또 이 부분은 제로 작동하지 않는 듯 하네요. 복사가 안 되어도 작동은 하니까 아직까지 문제는 없습니다만;;-Leonardong
~cpp 
copy c:cppunitlibtestrunnerd.dll .

아래 두 부분을 새 프로젝트 생성시 자동으로 추가되게 하는 좋은 방법 없나요. 매번 하려니 불편하네요; -- 황재선
{{|
Project Setting - Link - General - object/library 에 cppunitd.lib, testrunnerd.lib 를 추가해준다.
~cpp 
copy c:cppunitlibtestrunnerd.dll .
|}}
----
kldp.net 에 c 를 위한 UnitTest Framework 프로젝트가 있었네요. http://kldp.net/projects/act/
----
UnitTest
Valid XHTML 1.0! Valid CSS! powered by MoniWiki
last modified 2021-02-07 05:23:02
Processing time 0.0425 sec