本人原创,转载请注明出处。

目录

学习目标

2.c语言面向对象编程

2.1c语言继承实现

2.1.1子类结构体包含父类结构体

2.1.2子类结构体包含父类结构中的指针

2.1.3结构体和指针有何不同

2.2其他参考

2.2.1宏定义

2.2.2标准库实现StdImpl

3embUnit学习

3.1总体说明

3.2类图

3.3TestRunner调用过程

3.4TestCaller调用过程

3.5TestResult分析

​​​​​​​3.6TestUI分析


  1. 学习目标

以前一直从事底层驱动和应用开发,这几年中一直从事应用开发,采用C++去实现,最近由于工作原因,需要用C语言进行产品开发,想找一个c语言的单元测试框架,网上找了一个embUnit,这个库不依赖于标准库,方便进行移植,可以在嵌入式和PC上运行。在看代码的过程中,发现这个库的C语言编写,采用了类似C++面向对象的编程,面向对象C++上还算比较熟悉,但C实现还需要补补。由此便有了两个目标。

1)学习该开源库的c语言面向对象编程以及其编程习惯

2)学习embUnit,做为后面工作c语言单元测试框架

2.c语言面向对象编程

下面只是自己对简单的c语言面向对象编程做一个简单的总结记录。有不对之处,请提出讨论。

2.1c语言继承实现

我们知道c语言只能用结构体来实现C++语言类的概念。那怎么样才能继承呢。总结一句话。当一个类的结构体开始格式数据与另一个类结构体格式相同时。那这两个类可以作为父子类。

2.1.1子类结构体包含父类结构体

例如:

typedef  void(*aFunc)();typedef  struct __Father{aFunc sFuc;char* sName;
}Father,*pFather;typedef  struct __ChildS{Father sFather;char *sFav;
}ChildS,*pChildS;

ChildS结构体开始格式是Father sFather结构体,那ChildS就可以作为Father子类。

测试一下

static void _helloADo(){printf("helloADo....\r\n");
}static const ChildS ChildSA={{_helloADo,"FatherA"},"ChildA"
};pFather pf=(pFather)&ChildSA;
pf->sFuc();
printf("name=%s\r\n",pf->sName);

运行结果如下:

helloADo....

name=FatherA

说明ChildS,可以作为Father子类

2.1.2子类结构体包含父类结构中的指针

参考embUnit采用了另一种方法实现。我们看其中用的最多的Test.

TestImplement是测试抽象实现函数,有点类似于接口概念,纯虚函数。Test是一个类包含TestImplement指针,这时Test作为父类。子类有两个一个是TestCaller和TestCase.下面抽出部分结构体定义。
struct __Test {TestImplement* isa;
};struct __TestCaller {TestImplement* isa; char *name;  void(*setUp)(void);void(*tearDown)(void);int numberOfFixtuers;TestFixture   *fixtuers;
};struct __TestCase {TestImplement* isa;char *name;void(*setUp)(void);void(*tearDown)(void);void(*runTest)(void);
};

还是记住可以继承的原则。当一个类的结构体开始格式数据与另一个类结构体格式相同时。那这两个类可以作为父子类。这里需要好好理解一下。

所以你看void TestRunner_runTest(Test* test),运行测试都是一个Test对象。这时我们就知道 它可以是TestCaller和TestCase。embUnit顶层测试开始是TestCaller.这些是我们自己由一个个测试用例组成的。

2.1.3结构体和指针有何不同

因为c语言这块面向对象编程才刚开始,c好久不用不太熟悉了。只是谈谈我的个人感觉,这个和c语言特性有关。

指针的好处是方便初始化,可以先把IMP的对象初始化好。再填充。而结构体中结构体初始化填充不是很方便。有兴趣的自己可以测试一下。

2.2其他参考

2.2.1宏定义

embUnit大量用宏定义来生成一个对象。如

#define new_TestFixture(name,test)\

{\

name,\

test,\

}

生成一个TestFixture

其他可以自己研究

2.2.2标准库实现StdImpl

可以参考stdImpl,实现了标准库字符串的操作,其中整形转字符串函数,算法比较简洁可以参考下。

3embUnit学习

简单用UML 做了几个类的分析。但毕竟是C语言的,只能大概示意下。

3.1总体说明

三步调用,Start,RunTest,end.

TestRunner_start();

TestRunner_runTest(assertTest_tests());

TestRunner_end();

主要是准备Test对象,

3.2类图

3.3TestRunner调用过程

这里不过多解释,根据代码分析一下就可以

​​​​​​​3.4TestCaller调用过程

TestCaller运行中,生成一个TestCase,然后根据我们应用做好的TestFixture,作为runTest函数,然后在依次启动TestCase Run函数依次运行我们的测试用例

3.5TestResult分析

注意我assertTest,只加了一个testASSERT_EQUAL_STRING,打印结果如下

***********************************************************

**************      Unit Test Start         ***************

***********************************************************

OK (1 tests)

***********************************************************

**************       Unit Test End          ***************

***********************************************************

问题:

运行assertTest时,明明它有失败的为什么不打印出来呢?

带着问题我们来分析。

  new_TestFixture("testASSERT_EQUAL_STRING",testASSERT_EQUAL_STRING),

是调用testASSERT_EQUAL_STRING该函数

  static void testASSERT_EQUAL_STRING(void)

{

//接口函数的实现都用TestCaseImplement

//#define new_TestCase(name,setUp,tearDown,runTest)\

//    {\

//        (TestImplement*)&TestCaseImplement,\

//        name,\

//        setUp,\

//        tearDown,\

//        runTest,\

//    }

TestCase tcase = new_TestCase("assert_equal_string",NULL,NULL,assert_equal_string_runTest);

verify(&tcase);

}

它会生成TestCase,就是一个Test对象,再看verify

static void verify(TestCaseRef test)

{

TestResult result = new_TestResult(NULL);

test->isa->run(test,&result);

if (result.failureCount == 0) {

TEST_FAIL("fail");

}

}

生成一个TestResult,注意它没有Listner接口。这时再分析TestCase的Run函数

它的result有POP和PUSH的过程,此处自己体会。由于Listner接口。所以

TEST_ASSERT_EQUAL_STRING("123","456"); 此时用的TestResult没有addfail接口。自然没有失败打印。

那如何才能有呢。

两种方法:

  1. 直接用TestRunner中的TestResult,
  2. 自己定义TestReult,增加Listener接口。
  1. 很简单,在添加时如下

new_TestFixture("testASSERT_EQUAL_STRING",assert_equal_string_runTest), 直接添加该运行函数。注意结果如下。

***********************************************************

**************      Unit Test Start         ***************

***********************************************************

AssertTest.testASSERT_EQUAL_STRING (..\emb\Tests\assertTest.c 95) exp "123" was "456"

run 1 failures 1

***********************************************************

**************       Unit Test End          ***************

***********************************************************

失败结果打印出来了。

第二种,可以自行添加代码。我加了也可以实现。

​​​​​​​3.6TestUI分析

调用方式如下。

先设置Outputer对象可以是Text和XML,格式。这里又是面向对象的应用。

   TextUIRunner_setOutputter(TextOutputter_outputter());

TextUIRunner_start();

TextUIRunner_runTest(assertTest_tests());

TextUIRunner_runTest(stdImplTest_tests());

TextUIRunner_runTest(TestCaseTest_tests());

TextUIRunner_runTest(TestCallerTest_tests());

TextUIRunner_runTest(TestResultTest_tests());

TextUIRunner_runTest(RepeatedTestTest_tests());

TextUIRunner_end();

使用方式差不多 ,不做具体分析,

C语言单元测试embUnit入门学习相关推荐

  1. R语言基础知识入门学习(一)

    目录 系列文章目录 一.软件下载 二.基本知识 1. 对象 2. 向量 3. 向量化 4. 因子 总结 系列文章目录 R语言基础知识入门学习(一) 一.软件下载 我们可以通过这个网址对R语言软件进行下 ...

  2. proteus8单片机c语言仿真教程,入门学习Proteus 8仿真软件以及C51单片机的LED点亮(C语言)——实例...

    入门学习Proteus 8仿真软件以及C51单片机LED的点亮(C语言)--实例 一.点亮LED的程序编译 1.打开Keil uVision 4新建一个工程 2.在Atmel下寻找AT89C52芯片并 ...

  3. stm32f103c8t6c语言教程,STM32f103C8T6入门学习记录.doc

    STM32f103C8T6入门学习记录 STM32 自 学 笔 记 作者:忙碌的小姚 新浪微博:@忙碌的小姚 新浪博客: /mlxiaoyao222 目录 STM32 自 学 笔 记1 第一章3 我与 ...

  4. c语言EasyX库入门学习

    直接搬运朋友的 https://blog.csdn.net/sandalphon4869/article/details/80862023 下面是我将几个例子结合运行的总代码,并进行了一些改进和实现方 ...

  5. 如何零基础学习python语言_零基础如何入门Python语言?有哪些学习建议?

    众所周知,Python目前是最受欢迎的编程语言之一,尤其是对于零基础的初学者来说,Python语言更是十分的友好.因此,不少初学者常常会有这样一个共同的疑惑,零基础如何入门Python语言?本文就来给 ...

  6. 零基础学python语言_零基础如何入门Python语言?有哪些学习建议?

    众所周知,Python目前是最受欢迎的编程语言之一,尤其是对于零基础的初学者来说,Python语言更是十分的友好.因此,不少初学者常常会有这样一个共同的疑惑,零基础如何入门Python语言?本文就来给 ...

  7. python语言怎么学-如何学习Python,以及新手如何入门?

    蟹妖... 首先当然是买一个游标卡尺啊,哈哈哈... 而且有了游标卡尺之后你就不寂寞了,因为游标卡尺不估读... 最近据说python还加入了小学课本,这说明 python 是一门小学生都能学会的语言 ...

  8. python交互式编程入门先学什么_为什么 Python 对于编程入门学习来说,是一门很棒的语言...

    在这篇文章里,我会来阐述下为什么我觉得 Python 对于计算机编程入门教学来说是一门很棒的编程语言(对基础编程课程更多观点可以查看这篇文章).这也是从我针对初学者Python 编程教学过程中获得并总 ...

  9. c语言10个人 三向成绩,C语言入门学习精华:这样学习C语言最有效

    C语言入门学习精华:这样学习C语言最有效 c语言死了吗? 本材料描述了使用C语言的高级技能,并努力将您的C语言能力从"基本"提升到"高级".然而,学习态度比学习 ...

最新文章

  1. 春愁(shunshu)—Mrs. Green Apple (歌词、汉译、罗马音)
  2. biopython有什么用_BioPython学习笔记
  3. 2.1.Python字符串处理(去掉空格或者特殊字符、替换操作、查找操作、判断操作、分割合并操作、字符串文档)
  4. Using jQuery to add a dynamic “Back To Top” floating button with smooth scroll
  5. Centos下mysql数据库备份与恢复的方法
  6. python代码该怎么简化_Python开发简化代码的六大技巧
  7. 05-按钮的基本使用-开发步骤
  8. Selenium UI自动化测试(一)环境配置
  9. php让符合条件的复选框选中,多条件查询(复选框条件)
  10. IIS 7.0与ASP.NET
  11. header元素 footer元素 hgroup元素
  12. 优雅的断开连接--shutdown()
  13. 冒泡法排序c语言源程序,冒泡排序算法实例程序(C语言)
  14. 怎么把office卸载干净?
  15. 计算机打开不显示桌面,电脑启动后不显示桌面怎么办
  16. 国防科大 计算机原理考研试题,国防科技大学考研2003年计算机原理试题
  17. [南阳OJ-No.33]蛇形填数|在n*n方陈里填入1,2,...,n*n,要求填成蛇形。
  18. css中flex设置为1是什么意思
  19. Poi导入校验因单元格格式产生的空对象问题
  20. Unity说明文档翻译-Time Manager

热门文章

  1. 小米6系统 android版本是多少合适,“告别”安卓!小米6用上最新国产系统?
  2. 超越BERT、GPT------屏蔽序列到序列预训练MASS(原理篇)
  3. css3特效(上下左右晃动效果)
  4. react组件中的constructor和super小知识
  5. Luogu P3054 [USACO12OPEN]跑圈Running Laps
  6. 问道手游服务器找不到,问道手游安卓苹果互通服怎么不显示 鹊桥相会不能互通解决方法...
  7. oracle 窗口函数查询条件,62.Oracle数据库SQL开发之 高级查询——使用分析函数之窗口函数...
  8. 去了北京大兴机场后,我果断抛弃首都机场,去北京,首选大兴
  9. python rot13解密_牛刀小试——Python 2.7下的rot13编码与解码
  10. 程序员的另一条出路:在赚够钱后,35 岁考公上岸。