googletest学习(二)

二、了解gtest的实现原理

代码参考:GitHub - zchrissirhcz/cpp-moments: Records of learning/practising C++

1、断言的实现

断言的可以用宏定义实现

#define MyTEST_EXPECT(x, y, cond) \
    if (!((x)cond(y))) \
    { \
        printf("%s:%u: Failure\n", __FILE__, __LINE__); \
        if (strcmp(#cond, "==") == 0) \
        { \
            printf("Expected equality of these values:\n"); \
            printf("  %s\n", #x); \
            qtest_evaluate_if_required(#x, x); \
            printf("  %s\n", #y); \
            qtest_evaluate_if_required(#y, y); \
        } \
        else \
        { \
            printf("Expected: (%s) %s (%s), actual: %s vs %s\n", #x, #cond, #y, std::to_string(x).c_str(), std::to_string(y).c_str()); \
        } \
    }

template<typename T>
void qtest_evaluate_if_required(const char* str, T value)
{
    if (strcmp(str, std::to_string(value).c_str()) != 0)
    {
        std::cout << "    Which is: " << value << std::endl;
    }
}

#define EXPECT_EQ(x, y) MyTEST_EXPECT(x, y, ==)
#define EXPECT_NE(x, y) MyTEST_EXPECT(x, y, !=)
#define EXPECT_LT(x, y) MyTEST_EXPECT(x, y, <)
#define EXPECT_LE(x, y) MyTEST_EXPECT(x, y, <=)
#define EXPECT_GT(x, y) MyTEST_EXPECT(x, y, >)
#define EXPECT_GE(x, y) MyTEST_EXPECT(x, y, >=)


#define EXPECT_TRUE(x) \
    if (!((x))) \
    { \
        printf("%s:%u: Failure\n", __FILE__, __LINE__); \
        printf("Value of: %s\n", #x); \
        printf("  Actual: false\n"); \
        printf("Expected: true\n"); \
    }

#define EXPECT_FALSE(x) \
    if (((x))) \
    { \
        printf("%s:%u: Failure\n", __FILE__, __LINE__); \
        printf("Value of: %s\n", #x); \
        printf("  Actual: true\n"); \
        printf("Expected: false\n"); \
    }

2、TEST功能的实现

用静态类的add方法将测试用例添加到map中

#define GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) \
  test_suite_name##_##test_name##_Test
#define GTEST_MARK_CLASS_NAME_(test_suite_name, test_name) \
  test_suite_name##_##test_name##_Mark

#define STR(R) #R

#define GTEST_TEST(test_suite_name, test_name)                                 \
  class GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)                     \
    : public testParent  {                                                     \
   public:                                                                     \
    GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)() = default;            \
   private:                                                                    \
    void TestBody();                                                           \
  };                                                                           \
  int GTEST_MARK_CLASS_NAME_(test_suite_name, test_name) = TestEntity::get_instance().addTest(#test_suite_name, new GTEST_TEST_CLASS_NAME_(test_suite_name, test_name));            \
  void GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)::TestBody()

#define MyTEST(test_suite_name, test_name) GTEST_TEST(test_suite_name, test_name)

静态类的写法

class testParent
{
public:
    virtual void TestBody(){}
};

class TestEntity
{
public:
    TestEntity(){}
    static TestEntity& get_instance(){
        static TestEntity defaultTestEntity;
        return defaultTestEntity;
    }
    int addTest(string suitname, testParent* p){
        test_sets[suitname].push_back(p);
        return 0;
    }
    void run_all_test_functions(){
        for(std::map<std::string, std::vector<testParent*> >::iterator miter = test_sets.begin(); miter != test_sets.end(); ++miter){
            std::cout<< "Now run the suitcase:\t" << miter->first << endl;
            for(std::vector<testParent*>::iterator viter = miter->second.begin(); viter != miter->second.end(); ++viter){
                (*viter) -> TestBody();
            }
        }
    }

private:
    std::map<std::string, std::vector<testParent*> > test_sets; // suitname
};

本质思想就是创建一个静态类TestEntity,在宏定义展开TEST时会生成一个全局变量int,这个int的生成调用静态类的add方法将测试用例添加到map中。

  • 9
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

玟林禹

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值