C++

   :: 首页  :: 新随笔  ::  :: 订阅 订阅  :: 管理

下面的代码模仿gtest实现,主要说明了以下两点:

  1. ASSERT_* 和 EXPECT_*系列断言的原理和作用.
  2. gtest是怎样通过宏自动注册测试代码让其自动运行的.
 1 #include <iostream>
 2 #include <string>
 3 #include <memory>
 4 #include <vector>
 5 
 6 
 7 #define ASSERT_EQ(a,b) if((a) != (b)) \
 8     { \
 9         std::cout<<"[     FAIL ] "<<#a<<" not equal "<<#b<<std::endl; \
10         return; \
11     } else { \
12         std::cout<<"[       OK ] "<<std::endl; \
13     }
14 
15 #define ASSERT_NE(a,b) if((a) == (b)) \
16     { \
17         std::cout<<"[     FAIL ] "<<#a<<" not equal "<<#b<<std::endl; \
18         return; \
19     } else { \
20         std::cout<<"[       OK ] "<<std::endl; \
21     }
22 
23 #define EXPECT_EQ(a,b) if((a) != (b)) \
24     { \
25         std::cout<<"[     FAIL ] "<<#a<<" not equal "<<#b<<std::endl; \
26     } else { \
27         std::cout<<"[       OK ] "<<std::endl; \
28     }
29 
30 #define EXPECT_NE(a,b) if((a) == (b)) \
31     { \
32         std::cout<<"[     FAIL ] "<<#a<<" not equal "<<#b<<std::endl; \
33     } else { \
34         std::cout<<"[       OK ] "<<std::endl; \
35     }
36 
37 #define MAKE_CLASS_NAME(test_case_name, test_name)  MAKI_CLASS_NAME_I(test_case_name, test_name)
38 #define MAKI_CLASS_NAME_I(test_case_name, test_name) XTest_##test_case_name##_##test_name##_Test
39 #define XTEST_TEST(test_case_name,test_name) class MAKE_CLASS_NAME(test_case_name, test_name): \
40     public ::xtest::Test { \
41     public: \
42         MAKE_CLASS_NAME(test_case_name, test_name)(): ::xtest::Test(#test_case_name, #test_name) \
43         { \
44             ::xtest::UnitTest::regist(std::shared_ptr<::xtest::Test>(this)); \
45         } \
46         virtual void testBody(); \
47         static MAKE_CLASS_NAME(test_case_name, test_name) * instance; \
48 }; \
49 MAKE_CLASS_NAME(test_case_name, test_name) * MAKE_CLASS_NAME(test_case_name, test_name) ::instance \
50     = new MAKE_CLASS_NAME(test_case_name, test_name) ();\
51 void MAKE_CLASS_NAME(test_case_name, test_name)::testBody()
52 
53 #define TEST(test_case_name, test_name) XTEST_TEST(test_case_name, test_name)
54 
55 
56 namespace xtest {
57 
58     class Test{
59         friend class UnitTest;
60     public:
61         Test(const std::string &n1, const std::string& n2):test_case_name(n1), test_name(n2){
62         }
63         virtual void testBody() = 0;
64         std::string test_case_name;
65         std::string test_name;
66     private:
67         Test(const Test&) = delete;
68         Test& operator=(const Test&) = delete;
69     };
70 
71     class UnitTest {
72     public:
73         static UnitTest* getInstance();
74         void Run();
75         static void regist(std::shared_ptr<Test> const& a);
76     private:
77         static UnitTest* instance;
78         std::vector<std::shared_ptr<Test>> all_tests12;
79     };
80 }
81 
82 inline void RUN_ALL_TESTS(){
83     xtest::UnitTest::getInstance()->Run();
84 }

 

 1 #include "xtest.h"
 2 namespace xtest{
 3 
 4     UnitTest* UnitTest::instance = NULL;
 5     UnitTest* UnitTest::getInstance(){
 6         if(instance == NULL){
 7             instance = new UnitTest();
 8         }
 9         return instance;
10     }
11     void UnitTest::Run(){
12         std::cout<<"[==========] Start XTest..."<<std::endl;
13         for(auto i = begin(all_tests12); i!= end(all_tests12); ++i){
14             std::cout<<"[ RUN      ] "<<(*i)->test_case_name<<"."<<(*i)->test_name<<std::endl;
15             (*i)->testBody();
16             std::cout<<std::endl;
17         }
18     }
19     void UnitTest::regist(std::shared_ptr<Test>const& a){
20         getInstance()->all_tests12.push_back(a);
21     }
22 }

 

 

现在看看怎么用吧

 

 1 #include "xtest.h"
 2 
 3 TEST(t1,t2){
 4     ASSERT_EQ(1,1);
 5     ASSERT_EQ(1,2);
 6     ASSERT_EQ(2,3);
 7 }
 8 TEST(t3,t4){
 9     EXPECT_EQ(1,1);
10     EXPECT_EQ(1,2);
11     EXPECT_EQ(2,3);
12 }
13 int main(int argc, char* argv[]) {
14 
15     RUN_ALL_TESTS();
16     return 0;
17 }

 

输出结果:

1 [==========] Start XTest...
2 [ RUN      ] t1.t2
3 [       OK ]
4 [     FAIL ] 1 not equal 2
5 
6 [ RUN      ] t3.t4
7 [       OK ]
8 [     FAIL ] 1 not equal 2
9 [     FAIL ] 2 not equal 3

 

 

posted on 2014-06-05 15:32  xusd-null  阅读(1040)  评论(0编辑  收藏  举报