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

  1. ASSERT_* 和 EXPECT_*系列断言的原理和作用.
  2. 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() = ;
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(,);
ASSERT_EQ(,);
ASSERT_EQ(,);
}
TEST(t3,t4){
EXPECT_EQ(,);
EXPECT_EQ(,);
EXPECT_EQ(,);
}
int main(int argc, char* argv[]) { RUN_ALL_TESTS();
return ;
}

输出结果:

 [==========] Start XTest...
[ RUN ] t1.t2
[ OK ]
[ FAIL ] not equal [ RUN ] t3.t4
[ OK ]
[ FAIL ] not equal
[ FAIL ] not equal

Gtest源码剖析:1.实现一个超级简单的测试框架xtest的更多相关文章

  1. TreeMap就这么简单【源码剖析】

    前言 声明,本文用得是jdk1.8 前面章节回顾: Collection总览 List集合就这么简单[源码剖析] Map集合.散列表.红黑树介绍 HashMap就是这么简单[源码剖析] LinkedH ...

  2. ConcurrentHashMap基于JDK1.8源码剖析

    前言 声明,本文用的是jdk1.8 前面章节回顾: Collection总览 List集合就这么简单[源码剖析] Map集合.散列表.红黑树介绍 HashMap就是这么简单[源码剖析] LinkedH ...

  3. 【java集合框架源码剖析系列】java源码剖析之TreeSet

    本博客将从源码的角度带领大家学习TreeSet相关的知识. 一TreeSet类的定义: public class TreeSet<E> extends AbstractSet<E&g ...

  4. 【java集合框架源码剖析系列】java源码剖析之HashSet

    注:博主java集合框架源码剖析系列的源码全部基于JDK1.8.0版本.本博客将从源码角度带领大家学习关于HashSet的知识. 一HashSet的定义: public class HashSet&l ...

  5. Netty学习笔记(三)——netty源码剖析

    1.Netty启动源码剖析 启动类: public class NettyNioServer { public static void main(String[] args) throws Excep ...

  6. Ethtool工具源码剖析

    Ethtool工具源码剖析 ethool是一个实用的工具,用来给系统管理员以大量的控制网络接口的操作.可以用来控制接口参数,速度,介质类型,双工模式,DMA环设置,硬件校验和,LAN唤醒操作等.本人经 ...

  7. C# Dictionary源码剖析---哈希处理冲突的方法有:开放定址法、再哈希法、链地址法、建立一个公共溢出区等

    C# Dictionary源码剖析 参考:https://blog.csdn.net/exiaojiu/article/details/51252515 http://www.cnblogs.com/ ...

  8. 一个Python开源项目-腾讯哈勃沙箱源码剖析(上)

    前言 2019年来了,2020年还会远吗? 请把下一年的年终奖发一下,谢谢... 回顾逝去的2018年,最大的改变是从一名学生变成了一位工作者,不敢说自己多么的职业化,但是正在努力往那个方向走. 以前 ...

  9. 跨站请求伪造(csrf),django的settings源码剖析,django的auth模块

    目录 一.跨站请求伪造(csrf) 1. 什么是csrf 2. 钓鱼网站原理 3. 如何解决csrf (1)思路: (2)实现方法 (3)实现的具体代码 3. csrf相关的装饰器 (1)csrf_p ...

随机推荐

  1. Android学习之散乱的知识点

    1. 安卓广告知名平台:有米,哇棒,架势,admob(国外,但效果不好)等,推荐用有米 2. src目录为源文件目录,所有可以被用户修改和创建的Java文件将被存放在这个目录下 3. xml中引用st ...

  2. Code-first示例

    首先创建一个空数据库 在vs2013中添加数据库类,按提示操作一直下一步   添加完以后,数据库类的代码 namespace mvctest.Models { using System; using ...

  3. 写好Hive 程序的五个提示

    转自http://www.alidata.org/archives/622 使用Hive可以高效而又快速地编写复杂的MapReduce查询逻辑.但是某些情况下,因为不熟悉数据特性,或没有遵循Hive的 ...

  4. 遵守GPL的开源软件能用于商用吗?

    遵守GPL的开源软件能用于商用吗? 比较经典的开源协议有 GPL,BSD 等等. GPL 软件可以用于商业用途,甚至说,RMS 撰写 GPL 协议的目的就是为了让自己的 GPL 软件 emacs 可以 ...

  5. String - 兴趣解读

    个优点: . 以下代码的HashCode是否相同,它们是否是同个对象: . 以下代码的HashCode是否相同,他们是否是同个对象:        . 以下代码的HashCode是否相同,他们是否是同 ...

  6. hadoop 伪分布模式的配置

    转自 http://blog.csdn.net/zhaogezhuoyuezhao/article/details/7328313 centos系统自带ssh,版本为openssh4.3 免密码ssh ...

  7. show index 之Cardinality (mysql)

    show index  之Cardinality 官方文档的解释: Cardinality An estimate of the number of unique values in the inde ...

  8. C#操作Access的一些小结

    C#操作Access的一些小结 好久没有写blog,感觉今年一年都没怎么真正开心过,整天有一些事围绕在身边,使心情难以平静下来,真正写点有意义的东西.博客园是天天看的,看得多,写的少,偶尔也是Copy ...

  9. cvc-elt.1: Cannot find the declaration of element 'beans'

    @(编程) 现象描述 导入的一个eclipse项目报错,各种方法都无法解决,报错信息如下: cvc-elt.1: Cannot find the declaration of element 'bea ...

  10. JUnit 4 如何正确测试异常

    本篇讲述如何在 JUnit 4 下正确测试异常,我会从 try..catch 的方式谈起,然后说到 @Test(expected=Exception.class), 最后论及 @Rules publi ...