下面的代码模仿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. DOM笔记(十):JavaScript正则表达式

    一.RegExp ECMAScript通过RegExp类型类支持正则表达式,语法和Perl类似: var exp = /pattern/flags; patternb部分是任何简单的或复杂的正则表达式 ...

  2. 数往知来 ADO.NET <八>

    ADO.NET基础 学习目的:通过程序访问数据库 ,ADO.NET就是一组类库, -->connection   用来连接数据库的类 语法:首先需要一个连接字符串 -->以SQL serv ...

  3. ubuntu ip

    一.使用命令设置Ubuntu IP地址 1.修改配置文件blacklist.conf禁用IPV6 sudo vi /etc/modprobe.d/blacklist.conf 在文档最后添加 blac ...

  4. 30个有关Python的小技巧

    从我开始学习python的时候,我就开始自己总结一个python小技巧的集合.后来当我什么时候在Stack Overflow或者在某个开源软件里看到一段很酷代码的时候,我就很惊讶:原来还能这么做!,当 ...

  5. pku3277 City Horizon

    http://poj.org/problem?id=3277 线段树,离散化,成段更新 #include <stdio.h> #include <stdlib.h> #defi ...

  6. Axis2在Web项目中整合Spring

    一.说明: 上一篇说了Axis2与Web项目的整合(详情 :Axis2与Web项目整合)过程,如果说在Web项目中使用了Spring框架,那么又改如何进行Axis2相关的配置操作呢? 二.Axis2 ...

  7. js实现异步循环

    @(编程) 问题 实现异步循环时,你可能会遇到问题. 让我们试着写一个异步方法,每秒打印一次循环的索引值. for(var i = 0; i < 5; i++) { setTimeout(fun ...

  8. Java中的BASE64

    located in rt.jar... public class sun.misc.BASE64Encoder extends sun.misc.CharacterEncoder{ //.. } p ...

  9. HDU 3696 Farm Game(dp+拓扑排序)

    Farm Game Problem Description “Farm Game” is one of the most popular games in online community. In t ...

  10. [转]ViewPager onPageChangeListener总结

    android ViewPager滑动事件讲解 首先ViewPager在处理滑动事件的时候要用到OnPageChangeListener OnPageChangeListener这个接口需要实现三个方 ...