C++單元測試

最近寫了一個的C++單元測試工具,在這裏分享一下對測試用例(TestCase)的定義。

其中用到的MDB是用C++寫的內存數據庫,ExpectMDB則是一個僅用set容器實現的簡化版的數據庫。

測試用例的執行函數是一個返回值爲bool類型的無參函數,測試用例執行完後的數據在MDB中,對執行結果的期望數據,通過CSV文件導入到ExpectMDB中,通過check_mdb_tables對兩者中每個表的數據逐一覈對。

test_case.h

#ifndef __h_test_case_h__
#define __h_test_case_h__

#include "expect_mdb.h"
#include "mdb.h"

typedef bool (*TestFunc)();

struct CaseBase
{
	CaseBase(const string& suite_name, const string& case_name, TestFunc test_func)
	{
		m_suite_name = suite_name;
		m_case_name = case_name;
		m_test_func = test_func;
	}
	string m_suite_name;
	string m_case_name;
	TestFunc m_test_func;
};

class TestCase
{
public:
	TestCase(MDB* mdb, const string& suite_name, const string& case_name, const string& init_file_path, const string& expect_file_path, const string& result_file_path, TestFunc test_func);
	TestCase(const TestCase&) = delete;
	TestCase& operator=(const TestCase&) = delete;
	TestCase(TestCase&&);
	TestCase& operator=(TestCase&&);
	~TestCase();

	bool exec_case();

	void report_result();

private:
	void load_case();

	bool check_expect();

	string m_suite_name;
	string m_case_name;
	string m_init_file_path;
	string m_expect_file_path;
	string m_result_file_path;
	bool m_result;
	char m_result_msg[4096];
	MDB* m_mdb;
	ExpectMDB* m_expect_mdb;
	TestFunc m_test_func;
};

TestCase get_case(const CaseBase& case_base);


#endif

test_case.cpp

#include "test_case.h"
#include <iostream>
#include "init.h"
#include "load_init_md.h"
#include "load_init_tables.h"
#include "load_expect_tables.h"
#include "check_mdb_tables.h"
#include "kernel_global.h"

using namespace std;

TestCase::TestCase(MDB* mdb, const string& suite_name, const string& case_name, const string& init_file_path, const string& expect_file_path, const string& result_file_path, TestFunc test_func)
{
	m_mdb = mdb;
	m_expect_mdb = new ExpectMDB();
	m_suite_name = suite_name;
	m_case_name = case_name;
	m_init_file_path = init_file_path;
	m_expect_file_path = expect_file_path;
	m_result_file_path = result_file_path;
	m_test_func = test_func;
}

TestCase::TestCase(TestCase&& test_case)
{
	m_mdb = test_case.m_mdb;
	m_expect_mdb = test_case.m_expect_mdb;
	test_case.m_expect_mdb = nullptr;

	m_suite_name = test_case.m_suite_name;
	m_case_name = test_case.m_case_name;
	m_init_file_path = test_case.m_init_file_path;
	m_expect_file_path = test_case.m_expect_file_path;
	m_result_file_path = test_case.m_result_file_path;
	m_test_func = test_case.m_test_func;
}
TestCase& TestCase::operator=(TestCase&& test_case)
{
	m_mdb = test_case.m_mdb;
	m_expect_mdb = test_case.m_expect_mdb;
	test_case.m_expect_mdb = nullptr;

	m_suite_name = test_case.m_suite_name;
	m_case_name = test_case.m_case_name;
	m_init_file_path = test_case.m_init_file_path;
	m_expect_file_path = test_case.m_expect_file_path;
	m_result_file_path = test_case.m_result_file_path;
	m_test_func = test_case.m_test_func;
	return *this;
}

TestCase::~TestCase()
{
	if (m_expect_mdb)
		delete m_expect_mdb;
}

void TestCase::load_case()
{
	load_init_tables(m_mdb, m_init_file_path.c_str());
	load_init_md(m_init_file_path.c_str());

	load_expect_tables(m_expect_mdb, m_expect_file_path.c_str());
}

bool TestCase::exec_case()
{
	cout << "ExecCase:" << m_case_name << endl;
	load_case();

	m_result = (*m_test_func)();
	m_mdb->dump(m_result_file_path.c_str());
	if (m_result)
	{
		check_expect();
	}
	else
	{
		sprintf(m_result_msg, "Exec Case [%s] failed.", m_case_name.c_str());
	}

	return m_result;
}

bool TestCase::check_expect()
{
	m_result = check_mdb_tables(m_mdb, m_expect_mdb, m_result_msg);
	if (m_result)
		sprintf(m_result_msg, "Exec Case [%s] success.", m_case_name.c_str());
	return m_result;
}

void TestCase::report_result()
{
	cout << endl;
	cout << "TestSuite:" << m_suite_name << endl;
	cout << "TestCase:" << m_case_name << endl;
	cout << "TestResult: " << (m_result ? "Successful" : "Failed") << endl;
	cout << "ResultMessage:" << m_result_msg << endl << endl;
}

TestCase get_case(const CaseBase& case_base)
{
	string init_dir = "../cases/" + case_base.m_suite_name + "/" + case_base.m_case_name + "/init";
	string expect_dir = "../cases/" + case_base.m_suite_name + "/" + case_base.m_case_name + "/expect";
	string result_dir = "../cases/" + case_base.m_suite_name + "/" + case_base.m_case_name + "/result";
	TestCase test_case(g_mdb, case_base.m_suite_name, case_base.m_case_name, init_dir, expect_dir, result_dir, case_base.m_test_func);
	return test_case;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章