레이블이 MFC인 게시물을 표시합니다. 모든 게시물 표시
레이블이 MFC인 게시물을 표시합니다. 모든 게시물 표시

2008년 9월 18일 목요일

MFC CPPUnit 사용하기(2) - 소스코드 수정하기

MFC CPPUnit 사용하기(1) - 설정하기 를 마쳤으면 이제 소스코드를 수정해야 한다.

파란색으로 수정할 부분을 나타내었다. 원본에 파란 부분을 추가 혹은 주석처리 하면 된다.

<1> CppUnitDemo.cpp 파일

// CppUnitDemo.cpp : Defines the class behaviors for the application.
//

#include "stdafx.h"
#include "CppUnitDemo.h"
#include "CppUnitDemoDlg.h"

//+++++++++++++++++++++++++ < 가 동작을안함.< CPPUNIT 요부분
// CppUnit: MFC TestRunner
#include cppunit/ui/mfc/TestRunner.h>


// CppUnit: TestFactoryRegistry to retreive the top test
// suite that contains all registered tests.
#include cppunit/extensions/TestFactoryRegistry.h>
// +++++++++++++++++++++++++



#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CCppUnitDemoApp

BEGIN_MESSAGE_MAP(CCppUnitDemoApp, CWinApp)
//{{AFX_MSG_MAP(CCppUnitDemoApp)
// NOTE - the ClassWizard will add and remove mapping macros here.
// DO NOT EDIT what you see in these blocks of generated code!
//}}AFX_MSG
ON_COMMAND(ID_HELP, CWinApp::OnHelp)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CCppUnitDemoApp construction

CCppUnitDemoApp::CCppUnitDemoApp()
{
// TODO: add construction code here,
// Place all significant initialization in InitInstance
}

/////////////////////////////////////////////////////////////////////////////
// The one and only CCppUnitDemoApp object

CCppUnitDemoApp theApp;

/////////////////////////////////////////////////////////////////////////////
// CCppUnitDemoApp initialization

BOOL CCppUnitDemoApp::InitInstance()
{
// Standard initialization
// If you are not using these features and wish to reduce the size
// of your final executable, you should remove from the following
// the specific initialization routines you do not need.

#ifdef _AFXDLL
Enable3dControls(); // Call this when using MFC in a shared DLL
#else
Enable3dControlsStatic(); // Call this when linking to MFC statically
#endif

CCppUnitDemoDlg dlg;
m_pMainWnd = &dlg;
int nResponse = dlg.DoModal();
if (nResponse == IDOK)
{
// TODO: Place code here to handle when the dialog is
// dismissed with OK
}
else if (nResponse == IDCANCEL)
{
// TODO: Place code here to handle when the dialog is
// dismissed with Cancel
}

// Since the dialog has been closed, return FALSE so that we exit the
// application, rather than start the application's message pump.
return FALSE;
}

MFC CPPUnit 사용하기(1) - 설정하기

<1> CPPUnit 다운로드하기

- Cppunit 을 다운로드 받는다.

<2> CPPUnit Libraries 빌드하기(Build CppUnit Libraries)

- $CPPUNIT\src\CppUnitLibraries.dsw 파일을 VC++ 을 통하여 연다.
- Build 메뉴에서 BatchBuild 메뉴를 선택 RebuildAll을 통해 빌드를 한다.
- 빌드가 완료되면 $CPPUNIT$\lib 폴더에 파일들이 나타난것을 볼수 있을것이다.

- 빌드하는 도중 에러가 발생할수 있을것이다. 이는 Unicode libraries 가 인스톨되지 않았을경우에 그렇수 있다.
- VC 설치시 Default 로 설치시 설치되지 않으니 Unicode libraries 를 설치하길 바란다.

<3> MFC exe 프로젝트 생성하기.(Create A New 'MFC AppWizard (exe)' Project)

1.File -> New 선택
2.Projects Tab 선택
3.MFC AppWizard (exe)' project 선택
4.Project name = 'CppUnitDemo' 입력> OK 누름
5. 'Dialog based' 선택> Next 누름
6. 'About box' 와 'ActiveX Controls' 체크 해제>Next 누름
7. 'MFC Standard' 와 Source comments 'Yes,please' 와 As a shared DLL' 선택> Finish 누름

<4> Setting 정보 설정하기.
CPPUnit 을 사용하기위해서 설정해야할 Settung 을 설명한다.

<4-1> RTTI 설정하기(Enable Run-Time Type Information (RTTI))

1. Project > Settings 선택
2. C/C++ tab 선택
3. Category dropbox 의 'C++ Language' 선택
4. 'Enable Run-Time Type Information (RTTI)' 체크

<4-2> Run-Time Library 사용

1. Project > Settings 선택
2. C/C++ tab 선택
3. Category 'dropbox 의 Code Generation' 선택
4. 'Use run-time library:' dropbox 의 'Debug Multithreaded DLL' 선택

<4-3> Precompiled Headers 사용 해제

1. Project > Settings 선택
2. C/C++ tab 선택
3. Category 'dropbox 의 'Precompiled Headers' 선택
4. 'Not using precompiled headers' 선택

<4-4> Preprocessor Include Path 설정하기.

1. Project > Settings 선택
2. C/C++ tab 선택
3. Category 'dropbox 의 'Preprocessor' 선택
4. 'Additional include directories:' box 에 $CPPUNIT\include 를 입력

<4-5> CppUnit/TestRunner Libraries 사용 설정

1. Project > Settings 선택
2. Link tab 선택
3. Category 'dropbox 의 'General' 선택
4. 'Object/library modules:' box 에 $CPPUNIT$\lib\cppunit.lib 와$CPPUNIT\lib\testrunner.lib 입력

<5>. Include Path 수정

1. Tools -> Options 선택
2. 'Directories' tab 선택
3. 'Show directories for:' dropbox 의 'Include files' 선택
4. 'Directories' list 에 $CPPUNIT$\include 추가

<6> Library Path 수정
1. Tools -> Options 선택
2. 'Directories' tab 선택
3. 'Show directories for:' dropbox 의 'Library files' 선택
4. 'Directories' list 에 $CPPUNIT$\lib 추가

<7> Source Path 수정
1. Tools -> Options 선택
2. 'Directories' tab 선택
3. 'Show directories for:' dropbox 의 'Source files' 선택
4. 'Directories' list 에 $CPPUNIT\src\cppunit 추가

<8> Testrunner.dll Path 설정
빌드 하기전에 Testrunner.dll을 복사하기 귀찬차나~ 설정을 해주면 Build 전에 복사되는 부분이다.
1. Project -> Settings 선택
2. Post-build step tab 누름
3.'Post-build description' box 에 'Copying TestRunner DLL To Build Folder' 입력
4.'Post-build command(s)' list 에 "$CppUnit\lib\Testrunner.dll" $(OutDir)' 입력

설정을 마쳤으면 추가한 프로잭트에서 소스의 내용을 수정해야한다.

2008년 9월 12일 금요일

DECLARE_DYNCREATE()와 IMPLEMENT_DYNCREATE()

DECLARE_DYNCREATE()와 IMPLEMENT_DYNCREATE()
1.요약 MFC프로그램을 하면서 DECLARE_DYNCREATE()와 IMPLEMENT_DYNCREATE()라는 매크로를 자주보게 될 것입니다. 이 매크로가 무엇때문에 사용되는지 알아보겠습니다.

2.본문 DYNCREATE라는 단어서 볼 수 있듯이 동적생성에 관계있습니다. 이 매크로는 CObject를 선조로 하는 class에서 사용될 수 있으며 이 클래스가 동적으로 생성된다는 것을 알립니다. 위 매크로로 정의된 class를 동적으로 생성하기 위해서는 CRuntimeClass를 사용하는데 이 CRuntimeClass를 가져오기 위해서는 RUNTIME_CLASS(class)를 사용합니다. 보통 어떤 클래스를 동적으로 생성할려면 new연산자를 사용하고 delete연산자로 메모리에서 해제합니다. 그런데 왜 이 매크로를 사용할까 궁금해 질겁니다. 이유는 자기 스스로 파괴되는 객체에 대한 명확한 사용법을 제시하기 위해서 입니다. 자기 스스로 파괴되는 객체의 경우 정적으로 선언하여 사용하면 두번 메모리에서 제거되는 시도를 하기 때문에 메모리 참조가 일어나게됩니다. 그러므로 스스로 파괴되는 객체의 경우 반드시 동적으로 생성되어야하고 프로그래머가 정적으로 선언하는 실수를 방지하기 위해 생성자와 소멸자를 protected 멤버로 선언합니다. 생성자와 소멸자를 protected로 선언하면 다른 class에서 new나 delete로 객체를 생성할 수 없기 때문에 이러한 생성을 도와주는 class가 필요하게되는 것입니다. 이게 바로 CRuntimeClass입니다.

3.예제 위에 말이 좀 어려움감이 있는데 쉽게 예를들어보면 CFrameWnd나 CView같은 class들은 new로 생성할 수 없을 것입니다. 이러한 class를 생성할려면 다음과 같이하면 됩니다. CRuntimeClass *pRuntimeClass = RUNTIME_CLASS(CMyFrameWnd);
CMyFrameWnd *pFrame = (CMyFrameWnd*)pRuntimeClass->CreateObject();
pFrame->Create(...);
CreateObject()함수에서 내부적으로 new를 사용해서 객체를 생성하게되는데 이렇게 생성된 객체는 delete시킬 필요가 없을 겁니다. 그건 이 매크로로 작성된 class는 스스로 파괴되도록 설계되어 있을테니까요... 스스로 파괴되도록 설계되어있지 않다면 delete해야 됩니다. 위의 예제에서 보면 CFrameWnd나 CView를 동적으로 생성할 수 있기 때문에 Dialog base 프로그램에 CFrameWnd나 CView를 생성시킬 수 있습니다. 다음번에는 이 매크로를 사용하여 동적으로 생성되는 modeless dialog class를 만들어보겠습니다

2008년 9월 8일 월요일

MFC에서 CPPUinit 테스트 케이스 추가하기

0. Project Settings

Project Settings -> C/C++ -> C++ Language -> Enable Run-Time Type Information(RTTI) 체크

Project Settings -> Link -> Object/library modules -> cppunitd.lib testrunnerd.lib 추가( Debug모드일때 파일들 )

testrunnerd.dll 파일을 프로젝트 폴더로 복사한다.

  
 

1. XXXApp.cpp 파일에 아래 내용을 추가한다.

#include <msvc6/testrunner/testrunner.h>

#include <cppunit/extensions/testfactoryregistry.h>

...

BOOL CHostAppApp::InitInstance()

{

  TestRunner runner;

  runner.addTest(CppUnit::TestFactoryRegistry::getRegistry().makeTest());

  runner.run();

  ...

  return FALSE;

}

  
 

2. TestCase h파일을 만들어서 다음과 같은 방식으로 작성한다.( ExampleTestCase.h )

#ifndef TESTBLACKSCHOLES_H_

#define TESTBLACKSCHOLES_H_

#include <cppunit/TestCase.h>

#include <cppunit/extensions/HelperMacros.h>

class TestBlackScholes : public CppUnit::TestCase

{

 CPPUNIT_TEST_SUITE(TestBlackScholes);

 CPPUNIT_TEST(TestBS);

 CPPUNIT_TEST_SUITE_END();

public:

 void setUp();

 void tearDown();

 void TestBS();

};

#endif

  
 

3. TestCase cpp파일을 만들어서 다음과 같은 방식으로 작성한다.( ExampleTestCase.cpp )

#include "StdAfx.h"

#include "TestBlackScholes.h"

CPPUNIT_TEST_SUITE_REGISTRATION(TestBlackScholes);

void TestBlackScholes::setUp()

{

  
 

}

void TestBlackScholes::tearDown()

{

}

void TestBlackScholes::TestBS()

{

 CPPUNIT_ASSERT_EQUAL( 10, 10 );

}

  
 

이제 빌드하고 실행하면 아래와 같은 TestRunner가 먼저 실행되고 나서 실제 Application이 실행된다.


 

[출처]
MFC에서 CppUnit으로 TestCase만들기|작성자
이쓩

  
 

원본 위치 <http://blog.naver.com/PostView.nhn?blogId=gmgm21&logNo=80043354631&from=search>