티스토리 툴바


Library2012/01/05 18:12

CPPUNIT 이후 C++ 테스트 프레임웍 중 최고로 평가 되는 구글테스트, 구글목테스트 사용기 이다.
머 사실 선택의 폭이 그리 넓지 않다는 ...

구글 테스트는 C 타입의 함수타입 이고, 구글목 테스트는 C++ 객체 타입이라고 이해하면 이해가 빠르것 같다.

구글목은 테스트 프레임웍이 아니라 구글테스트의 확장이므로 구글테스트도 같이 필요하다.
구글목 테스트를 설치 하면 구글 테스트도 같이 설치된다.

1, 먼저 구글목 테스트 프레임웍을 다운받는다. http://code.google.com/p/googlemock/

2, 다음 Visual C++ 로 구글목 테스트를 빌드 한다. "gmock\msvc\2005\gmock"

3, 빌드를 하면 오류가 발생할 것이다. 구글목은 tr1 의 tuple 를 사용하기 때문에 boost 를 설치해 준다. http://extern.tistory.com/37

4, 설치한 boost 의 경로를 include 폴더에 추가한다. "boost_version", "boost_version\boost\tr1\tr1"

5, 신규 프로젝트를 만들어서 구글목 헤더를 폴더에 추가한다.  "mock\gtest\include", "gmock\include"

나머지는 소스로~

#include 

#if defined (_DEBUG)
	#pragma comment (lib, "2005/Debug/gmock.lib")	
#else
	#pragma comment (lib, "2005/Release/gmock.lib")	
#endif


/*start: 메소드 테스트*/

int ReturnMethod()
{
	return 1;
}

//MethodTest, True_Method 는 결과창에서 구분을 위한 설명
TEST(MethodTest, True_Method)
{
	EXPECT_EQ(ReturnMethod(),1);		
}

TEST(MethodTest, False_Method)
{
	EXPECT_EQ(ReturnMethod(),2);		
}

/*end:  메소드 테스트*/



/*start: class 테스트*/

// ::testing::Test 상속 받아야 한다.
class Test_Class : public ::testing::Test
{
public:	
	// TEST_F 통해 class를 테스트 할때 실행되는 함수
	virtual void SetUp()
	{
		test_ptr = new int;
	}
	// TEST_F 통해 class를 테스트 할때 마지막에 실행되는 함수
	virtual void TearDown()
	{
		delete test_ptr;
		test_ptr = NULL;
	}

	//SetUp(), TearDown() 는 기본 생성자 소멸자로 대체 가능하지만 그렇게 사용하지 말자
		
protected:
	int* test_ptr;
};

TEST_F(Test_Class, True_Class)
{
	ASSERT_TRUE(test_ptr != NULL);
}

TEST_F(Test_Class, False_Class)
{
	ASSERT_FALSE(test_ptr != NULL);
}

/*end: class 테스트*/



int _tmain(int argc, _TCHAR* argv[])
{
	testing::InitGoogleMock(&argc, argv);
	return RUN_ALL_TESTS();
}

 

 

Posted by 상현달
Library2010/11/23 19:22

function 은 함수를 일반 변수처럼 사용 가능하게 해준다.

#include "stdio.h"
#include "iostream"

#include "functional"
using std::tr1::function;
using std::type_info;

void print_type(const type_info& info)
{
    std::cout << info.name() << std::endl;
}

void main(void)
{	
   //_CRTIMP int __cdecl atoi(const char *)
   function func_atoi(atoi);
   function func_empty;

   //함수 타입 출력
   print_type(func_atoi.target_type());
   print_type(func_empty.target_type());

   //bool operator 이 정의 되어 있어서 바로 비교 가능하다.
   if(!func_atoi)
	std::cout << "func_atoi is null" << std::endl;	

   if(!func_empty)
	std::cout << "func_empty is null" << std::endl; 

   int num = func_atoi("12345");                       
   std::cout << "Number is " << num << std::endl;


   func_empty.swap(func_atoi); // func_atoi.swap(func_empty); 도 같은 결과이다.

   if(!func_atoi)
        std::cout << "func_atoi is null" << std::endl;	

   if(!func_empty)
        std::cout << "func_empty is null" << std::endl; 
    
}

출력결과:
int (__cdecl*)(char const *)
void
func_empty is null
Number is 12345
func_atoi is null
Press any key to continue
 
 

보너스로 bind() 간단한 예제
#include "iostream"

using std::cout;
using std::endl;

#include 

using std::tr1::function;
using std::tr1::bind;

template 
void Func_call(FUNC func)
{
    cout << func("1234") << endl;
}

void main()
{
    function func(atoi);
    Func_call(func);
    Func_call(bind(atoi, _1));
}
Posted by 상현달
Library2010/11/09 12:18

reference_wrapper 는 클래스, 함수, 변수 등의 참조를 레핑 한다.
참조(포인트)값을 사용할때 명시적으로 지정할수 있다.
클래스에서는 추상화 등에서도 유용하게 사용할수 있을듯 하다.

#include 
using std::tr1::reference_wrapper;
using std::tr1::cref;

#include 
using std::cout;
using std::endl;

class base
{
public:
	virtual void ShowMe()
	{
		cout << "base" << endl;
	}
};

class derived_first	: public base
{
public:
	void ShowMe()
	{
		cout << "derived_first" << endl;
	}
};

class derived_second : public base
{
public:
	void ShowMe()
	{
		cout << "derived_second" << endl;
	}
};

void ShowMe1()
{
	cout << "ShowMe1 func" << endl;
}

void ShowMe2()
{
	cout << "ShowMe2 func" << endl;
}

void main(void)
{
	derived_first	first;
	derived_second	second;
	
	reference_wrapper wr_first(first);	
	reference_wrapper wr_second(second);	

	wr_first.get().ShowMe();
	wr_second.get().ShowMe();

	typedef void(*const FUNC)();	
	reference_wrapper wr_func(&ShowMe1);	//전역 함수의 레퍼런스

	wr_func();

	wr_func = cref(&ShowMe2);			//함수 변경
	wr_func();
}

Posted by 상현달
Library2010/11/08 11:59

mem_fn 의 함수 템플릿은 함수 포인트를 호출할수 있도록 포장한다.
result_of 함수 템플릿을 사용하다면 보면 리턴값의 정의가 애매모호해 지는 경우 사용한다.

#include "stdio.h"

#include 

using std::tr1::mem_fn;
using std::tr1::result_of;

class func_class
{
public:
	void print() const
	{
		printf("Hello world!!!\n");
	}
	void print_arg(char* string)
	{
		printf("%s\n", string);
	}
	int printf_return()
	{
		return 1;
	}

public:
	int mem_;
};

template 
func_print(FN fn, OB ob)
{
	//result_of 은 코딩시 리턴 형식을 정의 할수 없는 애매한 상황에 사용된다.
	typedef typename result_of::type ret;

	ret ret_val = fn(ob);

	printf("Return type of %s when called with %s is %s(%d)\n",
		   typeid(FN).name(), 
		   typeid(OB).name(), 
		   typeid(ret).name(),
		   ret_val);
	
}

void main(void)
{
	typedef void(func_class::*FUN_PRINTF)() const;
	FUN_PRINTF fn = &func_class::print;

	func_class fc;
	// 인자 없는 함수
	mem_fn(fn)(fc);					

	//인자 있는 함수
	mem_fn(&func_class::print_arg)(fc, "Hello world!!!");

	//반환 있는 함수
	func_print(mem_fn(&func_class::printf_return), fc);

	//멤버 변수 사용
	mem_fn(&func_class::mem_)(fc) = 3;
	printf("%d\n", fc.mem_);

}

Posted by 상현달
Library2010/01/27 12:44

TR1 에서 4개의 컨테이너가 추가되었다

- unordered_map
- unordered_multimap
- unordered_set
- unordered_multiset

기존의 STL 에서도 가지고 있던 컨테이너다. 무엇이 다른가 ?

장점
- 일반 정렬 컨테이너는 데이타가 추가될때 값을 정렬시켜서 보관해서 검색하지만, 이것들은 hash 알고리즘을 이용하여 검색한다.

단점
- STL 에 비해 적은 연산자를 지원한다. 아마도 성능에 최적화 하기 위해서 일까 ?(rbegin 등도 사용할수 없다.)

기존에 많이들 쓰던거라 딱히 예제를 보여줄것도 없다.

허전하니 이런거라도 ...


#include 
#include 


int _tmain(int argc, _TCHAR* argv[])
{     
    using namespace std::tr1;    

    unordered_map map;
    unordered_multimap multimap;
    unordered_set set;
    unordered_multiset multiset;    

    return 0;
}
Posted by 상현달