VC++ 7.0의 MFC에서
NUnit을 써보자. 이것보다 좋은 방법이 있을듯한데... 인수군은 이방법밖에는 만들어내지 못했다.
- 일단 MFC 프로젝트를 만든다. 이것을 메인프로젝트라고 하자.
- 전체 솔루션에 Managed C++ Library 프로젝트를 새로 추가한다. 이것을 테스트프로젝트라고 하자.
- 테스트 프로젝트의 속성으로 들어가서 #using 참조에 nunit\bin폴더를 넣어준다.
- 테스트 프로젝트의 속성으로 들어가서 포함 디렉토리에 위의 메인프로젝트의 폴더를 넣어주자.
- 메인프로젝트의 속성탭에 가서 Managed C++ Extension을 체크해준다.
일단 준비는 됐다. 시작해 보자.
메인프로젝트에서 만든 새 클래스를 테스트 프로젝트에서 테스트하고 싶다. 어떻게 해야할까? 순진한 인수군은 #include <domain.h> 이렇게 하고, 테스트 클래스에 .h랑 .cpp 참조 넣어주면 될줄 알았다. 이것땜에 어제밤부터 삽질했다. 이렇게만 하면 안되고... 새로 만든 클래스를 일단 보자.
#pragma once
class CDomain
{
public:
CDomain(void);
~CDomain(void);
int add(int a, int b);
int mult(int a, int b);
};
평소대로 하자면 이렇게 하면 될것이다. 하지만 현재 프로젝트는
Managed C++ Extensions(http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vcmxspec/html/vcmanagedextensionsspec_16_2.asp)이다. 이것은 C++을 이용해서 .Net을 Platform위에서 프로그래밍을 하기 위하여 Microsoft에서 C++을 확장한 형태의 문법을 제안된 추가 문법을 정의해 놓았다. 이를 이용해야
NUnit이 C++ 코드에 접근할수 있다. 이경우
NUnit 에서 검증할 클래스에 접근하기 위해 다음과 같이 클래스 앞에
__gc(http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vcmxspec/html/vcmanagedextensionsspec_16_2.asp) 를 붙여서 선언해야 한다.
#pragma once
public __gc class CDomain
{
public:
CDomain(void);
~CDomain(void);
int add(int a, int b);
int mult(int a, int b);
};
__gc의 가 부여하는 능력과 제약 사항에 대해서는
__gc(http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vcmxspec/html/vcmanagedextensionsspec_4.asp) 을 참고하자.
NUnit 상에서 테스트의 대상 클래스는 무조건 포인터형으로 접근할수 있다. 이제 테스트 클래스의 내용을 보자.
// TestCase.h
#pragma once
#using <nunit.framework.dll>
using namespace System;
using namespace NUnit::Framework;
#include "Domain.h" // 포함 디렉토리에 메인프로젝트의 폴더를 넣어놨으므로 가능
namespace TestCase
{
[TestFixture]
public __gc class Class1
{
private:
CDomain* m_pD; // Only Pointer
public:
[SetUp]
void init() {
m_pD = new CDomain; // delete 필요없다.
}
[Test]
void testAdd() {
Assertion::AssertEquals(7, m_pD->add(3,4));
}
[Test]
void testMult() {
Assertion::AssertEquals(12, m_pD->mult(3,4));
}
};
}
이렇게 해주면 된다. 이거 알아내느라 엄청 삽질했다. 그런 의미로...
NUnit 많이 애용해 달라. 혹시나 더 간단하고 좋은 방법 있으면 올려 주세요.
이 경우 Unmanaged C++ 코드에 대해서 적용할수 없다. 즉, MFC로 완성된 프로그램이라도, .Net Platform 이 없는 곳에서는 작동할 수 없다. (로직에 __gc 가 존재하므로)
류상민은
NUnit 과 Unmanged C++의 연결을 완전하게는 하지 못했다. Managed C++프로젝트와 Unmanged C++ 프로젝트 두개를 만들어 Managed C++ 코드에서
NUnit 을 이용해 Unmanaged C++ 에 접근해 테스트 코드를 작성했다. 하지만, .Net Platform에 미숙과, Managed C++ Extension의 몰이해, 프로젝트 관리와 의존성 문제에 봉착해 곧 벽에 부딪쳤다. 이 둘은 혼용할수 없음을 알았다.
Unmanaged C++에서 가장 좋왔던 방법은 Unmanaged C++ Project 두개를 만들어서, 한쪽으로 의존시킨후 assert 를 이용해 자체적인 Test Framework 을 작성해서 사용하는 방법이었다.
--
NeoCoin
아..
gc를 쓰면 닷넷 플랫폼없는 곳에서는 쓸 수가 없겠네요. 그러면 이방법은 어떤가요? 일단 테스트할때는 테스트할 클래스에 __gc를 붙이잖아요? 나중에 배포할때는 __gc를 없애는 겁니다. 물론 Managed C++ Extensions의 문법을 쓰면 안되겠죠.(gc빼고) 매크로를 잘 쓰면 어떻게 될거 같기도 한데... --
인수
현재는 Managed C++에 깊히 공부해 보지 않아서, 잘 모르겠다. 이것이 __gc를 붙였다 때었다 하는 문제인지 확신할수가 없다.
그것을 떠나서, MFC를 쓰면서 테스트를 하는 것이 의미 있어 지려면, MFC 로 작성한 프로그램이 정상 동작하면서, 테스트를 할수 있어야 하는데, MFC Frameworks 이 Managed C++ 모드로 컴파일이 잘되고, 잘 돌아가는지, 이것이 의문이다. 된다면, MS에서 모든 MFC class앞에 __gc가 붙이기라도 한걸까? 혹은 이미 해당 매크로가 존재하지 않을까?
그래서 MFC 예제는 네가 작성한 첫번째 예제와 동일한 수준으로 쓸수 있는 것이 아닐까 생각한다. 길을 열어줘
--
NeoCoin