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

下面的代码模仿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

复制代码

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是一个使用gtest测试框架实现快速排序的示例代码: ```c++ #include <gtest/gtest.h> void quickSort(int arr[], int left, int right) { int i = left, j = right; int tmp; int pivot = arr[(left + right) / 2]; // partition while (i <= j) { while (arr[i] < pivot) i++; while (arr[j] > pivot) j--; if (i <= j) { tmp = arr[i]; arr[i] = arr[j]; arr[j] = tmp; i++; j--; } }; // recursion if (left < j) quickSort(arr, left, j); if (i < right) quickSort(arr, i, right); } TEST(QuickSortTest, PositiveNos) { int arr[] = { 5, 2, 3, 1, 4 }; int n = sizeof(arr) / sizeof(arr[0]); quickSort(arr, 0, n - 1); ASSERT_EQ(arr[0], 1); ASSERT_EQ(arr[1], 2); ASSERT_EQ(arr[2], 3); ASSERT_EQ(arr[3], 4); ASSERT_EQ(arr[4], 5); } TEST(QuickSortTest, NegativeNos) { int arr[] = { -5, -2, -3, -1, -4 }; int n = sizeof(arr) / sizeof(arr[0]); quickSort(arr, 0, n - 1); ASSERT_EQ(arr[0], -5); ASSERT_EQ(arr[1], -4); ASSERT_EQ(arr[2], -3); ASSERT_EQ(arr[3], -2); ASSERT_EQ(arr[4], -1); } TEST(QuickSortTest, MixedNos) { int arr[] = { -5, 2, -3, 1, 0 }; int n = sizeof(arr) / sizeof(arr[0]); quickSort(arr, 0, n - 1); ASSERT_EQ(arr[0], -5); ASSERT_EQ(arr[1], -3); ASSERT_EQ(arr[2], 0); ASSERT_EQ(arr[3], 1); ASSERT_EQ(arr[4], 2); } int main(int argc, char **argv) { testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } ``` 在这个示例代码中,我们使用了gtest测试框架测试快速排序函数quickSort。我们定义了三个测试用例,分别测试了正数、负数和混合数的情况。在每个测试用例中,我们使用ASSERT_EQ宏来断言排序后数组的每个元素是否与预期值相等。如果不相等,则测试失败。 注意,这里的示例代码仅供参考,实际实现中可能需要根据具体情况进行相应修改。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值