1. Glib 单元测试框架

Glib 为单元测试提供了一套完整的测试框架,每个测试运行包括以下几个部分

  • 测试数据结构
  • 测试 setup 与 teardown 函数
  • 测试函数

2. 单元测试数据结构

在一组测试中使用的元素称为一个 fixture,Glib 要求每个 fixture 都是一个结构,所以我们需要声明一个结构体,包含我们测试数据或是对象。

/** fixture for Glib test */
typedef struct Matrix2dTest
{Matrix2d mat; ///< test objectdouble TOL;   ///< maximum error
} Matrix2dTest;

如上代码中定义了我们测试所需结构体 Matrix2dTest,结构体中元素 mat 即为后面进行测试的对象(结构体)。

3. 测试环境构建

在每个测试函数运行前,可能都需要进行一系列初始化和后处理操作。Glib 运行时将这两个过程函数作为参数传给测试函数,如此一来,每个测试函数都可以生成一个新的程序来运行,并且互不影响。

添加测试函数的语句是

g_test_add("/MatUtils/Test_inverseMatrix2d",  // test labelMatrix2dTest,                     // test structureNULL,                             // input user dataSetup_Matrix2dTest,               // setup functionTest_inverseMatrix2d,             // test functionTeardown_Matrix2dTest);           // teardown function

其中,Matrix2dTestNULL 为测试函数输入参数,Test_inverseMatrix2d 为测试函数,Setup_Matrix2dTestTeardown_Matrix2dTest 为测试初始化和后处理函数。

在调用测试函数时候,Glib 通过 fork 系统调用生成新的线程来测试失败。运行 g_test_run() 语句即可运行所有测试,具体执行命令可参见第5节。

4. 单元测试函数

由于测试框架是确定的,因此单元测试函数参数也是固定的。在上面测试中,我们添加测试函数名为 Test_inverseMatrix2d,函数完整定义为

static void
Test_inverseMatrix2d(Matrix2dTest* mattest, const void* test_data)
{Matrix2d mat1;mallocMatrix2d(3, 3, &mat1);copyMatrix2d(mattest->mat, &mat1);inverseMatrix2d(mat1);Matrix2d mat2;mallocMatrix2d(3, 3, &mat2);multiplyMatrix2d(mattest->mat, mat1, 1.0, 0.0, mat2);g_assert(fabs(mat2.ets[0][0] - 1.0) < mattest->TOL);g_assert(fabs(mat2.ets[1][1] - 1.0) < mattest->TOL);g_assert(fabs(mat2.ets[2][2] - 1.0) < mattest->TOL);freeMatrix2d(mat1);freeMatrix2d(mat2);
}

可以看到,由于函数只有文件内测试用,因此声明为 static 函数。函数有两个参数,第一个为 mattest 类型指针,第二个为传入用户数据,由于我们不需要其他数据,因此调用时传入 NULL

这个测试主要用来测试矩阵求逆过程,计算完成后将逆矩阵与矩阵相乘,看结果是否为单元矩阵。最后的判断采用如下语句

  g_assert(fabs(mat2.ets[0][0] - 1.0) < mattest->TOL);g_assert(fabs(mat2.ets[1][1] - 1.0) < mattest->TOL);g_assert(fabs(mat2.ets[2][2] - 1.0) < mattest->TOL);

5. 完整测试函数

#include <stdio.h>
#include <math.h>
#include "MatUtils.h"
#include <glib.h>/** fixture for Glib test */
typedef struct Matrix2dTest
{Matrix2d mat; ///< test objectdouble TOL;   ///< maximum error
} Matrix2dTest;static void
Setup_Matrix2dTest(Matrix2dTest* mattest, const void* test_data)
{mallocMatrix2d(3, 3, &(mattest->mat));double vt[] = {3.0, -1.0, -1.0, 4.0, -2.0, -1.0, -3.0, 2.0, 1.0,};mattest->TOL = 1e-6;setMatrix2dFromArray(vt, mattest->mat);
}static void
Teardown_Matrix2dTest(Matrix2dTest* mattest, const void* test_data)
{freeMatrix2d(mattest->mat);
}static void
Test_inverseMatrix2d(Matrix2dTest* mattest, const void* test_data)
{Matrix2d mat1;mallocMatrix2d(3, 3, &mat1);copyMatrix2d(mattest->mat, &mat1);inverseMatrix2d(mat1);Matrix2d mat2;mallocMatrix2d(3, 3, &mat2);multiplyMatrix2d(mattest->mat, mat1, 1.0, 0.0, mat2);g_assert(fabs(mat2.ets[0][0] - 1.0) < mattest->TOL);g_assert(fabs(mat2.ets[1][1] - 1.0) < mattest->TOL);g_assert(fabs(mat2.ets[2][2] - 1.0) < mattest->TOL);freeMatrix2d(mat1);freeMatrix2d(mat2);
}int
main(int argc, char** argv)
{g_test_init(&argc, &argv, NULL);g_test_add("/MatUtils/Test_inverseMatrix2d", // test labelMatrix2dTest,                     // test structureNULL,                             // input user dataSetup_Matrix2dTest,               // setup functionTest_inverseMatrix2d,             // test functionTeardown_Matrix2dTest);           // teardown functionreturn g_test_run();
}

编译时由于需要链接 Glib 函数库所以需要添加一些附加命令。这里我采用的是 cmake 软件编译,在工程根目录的 CMakeLists.txt 中直接添加如下命令添加 Glib 头文件和库文件目录,

find_package(PkgConfig REQUIRED)
pkg_check_modules(GLIB REQUIRED glib-2.0>=2.23)
include_directories(${GLIB_INCLUDE_DIRS})
link_directories(${GLIB_LIBRARY_DIRS})

在测试函数所在的文件夹内 CMakeLists.txt 中,则添加如下命令编译测试函数

target_link_libraries(MatUtilsTest matutils ${GLIB_LIBRARIES})

如此便可对测试函数进行正确的编译和链接了。

获得可执行的测试函数后,用过命令

gtester -k -o=test.xml ./MatUtilsTest

生成测试结果文件 test.xml,再利用语句 gtester-report 命令即可将 XML 文件转化为 html 文件,并用留浏览器打开。

gtester-report test.xml > test.html

但是不知什么原因,在我的 Macbook 笔记本上出现错误

➜  build gtester-report test.xml > test.html
Traceback (most recent call last):File "/usr/local/bin/gtester-report", line 490, in <module>main()File "/usr/local/bin/gtester-report", line 484, in mainHTMLReportWriter(rr.get_info(), rr.binary_list()).printout()File "/usr/local/bin/gtester-report", line 348, in printoutself.handle_info ()File "/usr/local/bin/gtester-report", line 242, in handle_infoself.oprint ('<h3>Package: %(package)s, version: %(version)s</h3>\n' % self.info)
KeyError: 'package'

通过搜索我发现是 xml 文件缺少内容所致 Running gtester-report on gtester output raises KeyError。打开 xml 文件,在 <gtester> 字段内添加

<info>
<package>PACKAGENAME</package>
<version>VERSION</version>
<revision>REVISION</revision>

语句,声明软件名和软件版本。如此便可得到可视化的测试结果,如图所示:

参考文献

理解 GLib 的单元测试框架

https://segmentfault.com/a/1190000003996312

Ben Klemens. C程序设计新思维[M]. 人民邮电出版社, 2015.

转载于:https://www.cnblogs.com/li12242/p/8419527.html

Glib 对 C 函数进行单元测试相关推荐

  1. SylixOS下移植glib时clock_gettime函数分析

    1. 问题分析 移植glib中间件时,运行测试用例出现异常错误,定位问题为g_clock_gettime函数获取的时间和系统API获取的时间不一致导致. glib中间件中g_get_monotonic ...

  2. 深入理解Go语言中的函数【单元测试】14

    文章目录 go test工具 测试函数 测试函数的格式 测试函数示例 测试组 子测试 测试覆盖率 基准测试 基准测试函数格式 基准测试示例 性能比较函数 重置时间 并行测试 Setup与TearDow ...

  3. 绘制图形可以使用什么python函数_如何对绘制PDF图形的Python函数进行单元测试?...

    (另请参阅下面的更新!) 我在Linux上用一个shell脚本做同样的事情ImageMagick的compare命令 pdftk实用程序 Ghostscript(可选) (将其移植到DOS/Windo ...

  4. 如何在单元测试中测试异步函数,block回调这种

    大概有四种方法: runloop 阻塞主进程等待结果 semphaore 阻塞主进程等待结果 使用XCTestExpectation 阻塞主线程等待(我用这个,xcode自带的,为啥不用) 使用第三方 ...

  5. 并发Goroute、定时器、信号处理、单元测试

    Goroutine(轻量级的线程,开线程没有数量限制) 1.进程和线程 A.进程是程序在操作系统中的一次执行过程,系统进行资源分配和调度的一个独立单位. B.线程是进程的一个执行实体,是CPU调度和分 ...

  6. 结对编程2——单元测试

    码市地址:https://git.coding.net/cjz113/jiedui2.git 结对成员:201421123111 201421123113 题目描述: 上一周大家为四则运算程序设计了2 ...

  7. Qt高级——QTestLib单元测试框架

    一.QTestLib简介 1.QTestLib简介 QTestLib是Qt提供的一种针对基于Qt编写的程序或库的单元测试框架.QTestLib提供了单元测试框架的基本功能,并提供了针对GUI测试的扩展 ...

  8. C指针原理(39)-GLIB

    一.简述与配置 GLib是一个跨平台的.用C语言编写的库,起初是GTK+的一部分,但到了GTK+第二版,开发者决定把跟图形界面无关的代码分开,这些代码于是就组装成了GLib.因为GLib具有跨平台特性 ...

  9. ​手把手教你如何进行 Golang 单元测试

    作者:stevennzhou,腾讯 PCG 前端开发工程师 本篇是对单元测试的一个总结,通过完整的单元测试手把手教学,能够让刚接触单元测试的开发者从整体上了解一个单元测试编写的全过程.最终通过两个问题 ...

最新文章

  1. 藤本植物和攀爬植物模型包 Globe Plants – Bundle 23 – Vines and Creepers 03 (3D Models)
  2. 迈出编程第一步!必知必会的10个编程技巧及查错方法
  3. 使用Python的库qrcode生成二维码
  4. 高职扩招有计算机专业吗,高职扩招计算机专业
  5. linux samba代码,Linux下Samba服务器源码安装及配置
  6. S5PV210开发 -- 开发板配置
  7. CentOS密码忘记后的操作
  8. 微型计算机最怕的是什么,为什么以前学生上“微机课”都要穿鞋套?老师:怕电脑中病毒...
  9. oracle rac 高并发性能_高并发业务下 JVM 涉及的垃圾回收与性能问题分析与定位...
  10. [转贴] PHP 编程标准
  11. 150W光速秒充!realme真我GT Neo3正式发布 售价1999元起
  12. 如何在vue项目中修改less变量,多主题项目解决方案
  13. VC++ SetLayeredWindowAttributes 部分窗口透明鼠标穿透
  14. php 如何去除说有空格,php怎么去除所有空格
  15. 达梦数据库连接工具简介
  16. Netron可视化网络结构
  17. word2016用尾注引用参考文献
  18. FTP、TFTP 实现 NAT ALG 访问
  19. 致我们终将远离的子女
  20. 有哪些wordpress企业网站主题推荐?

热门文章

  1. 每天一道LeetCode-----从有序数组中删除重复元素
  2. 1029 旧键盘 (20 分)(c语言)
  3. caffe源码解析—image_data_layer层
  4. 嵌入式Linux系统BSP的设计与实现
  5. 爬虫 - HDU题目信息
  6. OpenVINO 从yml处提取model下载链接,以mobile-ssd为例
  7. 关于数据库与LoaderManager的联合使用,节流???。。。。。
  8. Windows平台下安装Hadoop
  9. 在Excel中如何引用其他的工作表或者工作簿
  10. Use the Shapes window to organize and find shapes