C++单元测试框架

新写了一个简单的单元测试框架,测试用例抽象为TestCase对象,包含两个接口:bool exec_case();与void report_result();

调用exec_case时,执行测试用例的单元测试函数(由具体的测试用例给出),将测试结果和相关信息记录下来;

调用report_result时,将测试结果与相关信息输出。

 

test_case.h

#ifndef __h_test_case_h__
#define __h_test_case_h__
#include 
#include 
#include "test_common.h"

typedef bool (*TestFunc)(std::string& error_msg);

class TestCase
{
public:
	TestCase(const std::string& suite_name, const std::string& case_name, TestFunc test_func);
	~TestCase();

	bool exec_case();

	void report_result();

private:
	std::string m_suite_name;
	std::string m_case_name;
	bool m_result;
	std::string m_result_msg;
	TestFunc m_test_func;
};

int exec_cases(std::vector& test_case_vec);


#endif

test_case.cpp

#include "test_case.h"
#include 

using namespace std;

TestCase::TestCase(const std::string& suite_name, const std::string& case_name, TestFunc test_func)
{
	m_suite_name = suite_name;
	m_case_name = case_name;
	m_test_func = test_func;
}

TestCase::~TestCase()
{
}

bool TestCase::exec_case()
{
	cout << "ExecCase:[" << m_suite_name << "]\t\t[" << m_case_name << "]" << endl;

	try
	{
		m_result = (*m_test_func)(m_result_msg);
	}
	catch (exception e)
	{
		m_result = false;
		m_result_msg = e.what();
	}
	return m_result;
}

void TestCase::report_result()
{
	cout << endl;
	cout << "TestSuite:\t" << m_suite_name << endl;
	cout << "TestCase:\t" << m_case_name << endl;
	cout << "TestResult:\t " << (m_result ? "Success" : "Fail") << endl;
	cout << "ResultMessage:\t" << m_result_msg << endl << endl;
}


int exec_cases(std::vector& test_case_vec)
{
	int passed_count = 0;
	int failed_count = 0;
	cout << endl << "-------------------Exec Cases-------------------" << endl;
	for (auto it = test_case_vec.begin(); it != test_case_vec.end(); it++)
	{
		if (it->exec_case())
		{
			passed_count++;
		}
		else
		{
			failed_count++;
		}
	}

	cout << endl << "-------------------Report Result-------------------" << endl;
	for (auto it = test_case_vec.begin(); it != test_case_vec.end(); it++)
	{
		it->report_result();
	}

	cout << "Exec " << test_case_vec.size() << " cases, " << passed_count << " passed, " << failed_count << " failed." << endl;

	return failed_count;
}

test_common中定义了几个断言宏,在测试用例中用于检查变量值与预期是否符合。

test_common.h

#ifndef __h_test_common_h__
#define __h_test_common_h__

extern char message_buffer[4096];

void throw_exception(const char* msg);

#define ASSERT_NOT_EQUAL(value1, value2)	\
	if ((value1) == (value2)){				\
		::memset(message_buffer, 0, sizeof(message_buffer));	\
		sprintf(message_buffer, "%s(%d), (%s) == (%s)\n", __FILE__, __LINE__, #value1, #value2);\
		throw_exception(message_buffer);	\
	}

#define ASSERT_EQUAL(value1, value2)		\
	if ((value1) != (value2)){				\
		::memset(message_buffer, 0, sizeof(message_buffer));	\
		sprintf(message_buffer, "%s(%d), (%s) != (%s)\n", __FILE__, __LINE__, #value1, #value2);\
		throw_exception(message_buffer);	\
	}

#define ASSERT_LESS(value1, value2)			\
	if ((value1) >= (value2)){				\
		::memset(message_buffer, 0, sizeof(message_buffer));	\
		sprintf(message_buffer, "%s(%d), (%s) >= (%s)\n", __FILE__, __LINE__, #value1, #value2);\
		throw_exception(message_buffer);	\
	}

#define ASSERT_LESS_EQUAL(value1, value2)	\
	if ((value1) > (value2)){				\
		::memset(message_buffer, 0, sizeof(message_buffer));	\
		sprintf(message_buffer, "%s(%d), (%s) > (%s)\n", __FILE__, __LINE__, #value1, #value2);	\
		throw_exception(message_buffer);	\
	}

#define ASSERT_GREAT(value1, value2)		\
	if ((value1) <= (value2)){				\
		::memset(message_buffer, 0, sizeof(message_buffer));	\
		sprintf(message_buffer, "%s(%d), (%s) <= (%s)\n", __FILE__, __LINE__, #value1, #value2);\
		throw_exception(message_buffer);	\
	}

#define ASSERT_GREAT_EQUAL(value1, value2)	\
	if ((value1) < (value2)){				\
		::memset(message_buffer, 0, sizeof(message_buffer));	\
		sprintf(message_buffer, "%s(%d), (%s) < (%s)\n", __FILE__, __LINE__, #value1, #value2);	\
		throw_exception(message_buffer);	\
	}


#endif

test_common.cpp

#include "test_common.h"
#include 

char message_buffer[4096];


void throw_exception(const char* msg)
{
	std::exception e(msg);
	throw e;
}

test_login中写了一个简单的测试用例

test_login.h

#ifndef __h_test_login_h__
#define __h_test_login_h__

#include "test_case.h"


namespace test_login
{
	bool test_login(std::string& error_msg)
	{
		int i = 0;
		ASSERT_GREAT_EQUAL(i, 0);
		return true;
	}

	struct TestLogin : public TestCase
	{
	public:
		TestLogin(const std::string& suite_name = "MDLL_SWSSL_Step_test", const std::string& case_name = "test_login", TestFunc test_func = test_login)
			:TestCase(suite_name, case_name, test_func)
		{

		}
	};
}
#endif

测试入口,main函数所在

test.cpp

#include "test_case.h"
#include "test_login/test_login.h"
#include 
#include 

using namespace std;
int main()
{
	std::vector test_case_vec;
	test_case_vec.push_back(test_login::TestLogin());

	return exec_cases(test_case_vec);
}

 

你可能感兴趣的:(C++,紫云的程序人生,UnitTest)