您的位置:首页 > 其它

Gtest源码剖析:1.实现一个超级简单的测试框架xtest

2014-06-05 15:32 423 查看
下面的代码模仿gtest实现,主要说明了以下两点:

ASSERT_*
EXPECT_*
系列断言的原理和作用.

gtest是怎样通过宏自动注册测试代码让其自动运行的.

#include <iostream>
#include <string>
#include <memory>
#include <vector>

#define ASSERT_EQ(a,b) if((a) != (b)) \
{ \
std::cout<<"[     FAIL ] "<<#a<<" not equal "<<#b<<std::endl; \
return; \
} else { \
std::cout<<"[       OK ] "<<std::endl; \
}

#define ASSERT_NE(a,b) if((a) == (b)) \
{ \
std::cout<<"[     FAIL ] "<<#a<<" not equal "<<#b<<std::endl; \
return; \
} else { \
std::cout<<"[       OK ] "<<std::endl; \
}

#define EXPECT_EQ(a,b) if((a) != (b)) \
{ \
std::cout<<"[     FAIL ] "<<#a<<" not equal "<<#b<<std::endl; \
} else { \
std::cout<<"[       OK ] "<<std::endl; \
}

#define EXPECT_NE(a,b) if((a) == (b)) \
{ \
std::cout<<"[     FAIL ] "<<#a<<" not equal "<<#b<<std::endl; \
} else { \
std::cout<<"[       OK ] "<<std::endl; \
}

#define MAKE_CLASS_NAME(test_case_name, test_name)  MAKI_CLASS_NAME_I(test_case_name, test_name)
#define MAKI_CLASS_NAME_I(test_case_name, test_name) XTest_##test_case_name##_##test_name##_Test
#define XTEST_TEST(test_case_name,test_name) class MAKE_CLASS_NAME(test_case_name, test_name): \
public ::xtest::Test { \
public: \
MAKE_CLASS_NAME(test_case_name, test_name)(): ::xtest::Test(#test_case_name, #test_name) \
{ \
::xtest::UnitTest::regist(std::shared_ptr<::xtest::Test>(this)); \
} \
virtual void testBody(); \
static MAKE_CLASS_NAME(test_case_name, test_name) * instance; \
}; \
MAKE_CLASS_NAME(test_case_name, test_name) * MAKE_CLASS_NAME(test_case_name, test_name) ::instance \
= new MAKE_CLASS_NAME(test_case_name, test_name) ();\
void MAKE_CLASS_NAME(test_case_name, test_name)::testBody()

#define TEST(test_case_name, test_name) XTEST_TEST(test_case_name, test_name)

namespace xtest {

class Test{
friend class UnitTest;
public:
Test(const std::string &n1, const std::string& n2):test_case_name(n1), test_name(n2){
}
virtual void testBody() = 0;
std::string test_case_name;
std::string test_name;
private:
Test(const Test&) = delete;
Test& operator=(const Test&) = delete;
};

class UnitTest {
public:
static UnitTest* getInstance();
void Run();
static void regist(std::shared_ptr<Test> const& a);
private:
static UnitTest* instance;
std::vector<std::shared_ptr<Test>> all_tests12;
};
}

inline void RUN_ALL_TESTS(){
xtest::UnitTest::getInstance()->Run();
}


#include "xtest.h"
namespace xtest{

UnitTest* UnitTest::instance = NULL;
UnitTest* UnitTest::getInstance(){
if(instance == NULL){
instance = new UnitTest();
}
return instance;
}
void UnitTest::Run(){
std::cout<<"[==========] Start XTest..."<<std::endl;
for(auto i = begin(all_tests12); i!= end(all_tests12); ++i){
std::cout<<"[ RUN      ] "<<(*i)->test_case_name<<"."<<(*i)->test_name<<std::endl;
(*i)->testBody();
std::cout<<std::endl;
}
}
void UnitTest::regist(std::shared_ptr<Test>const& a){
getInstance()->all_tests12.push_back(a);
}
}


现在看看怎么用吧

#include "xtest.h"

TEST(t1,t2){
ASSERT_EQ(1,1);
ASSERT_EQ(1,2);
ASSERT_EQ(2,3);
}
TEST(t3,t4){
EXPECT_EQ(1,1);
EXPECT_EQ(1,2);
EXPECT_EQ(2,3);
}
int main(int argc, char* argv[]) {

RUN_ALL_TESTS();
return 0;
}


输出结果:

[==========] Start XTest...
[ RUN      ] t1.t2
[       OK ]
[     FAIL ] 1 not equal 2

[ RUN      ] t3.t4
[       OK ]
[     FAIL ] 1 not equal 2
[     FAIL ] 2 not equal 3
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: