有关C语言单元测试的探讨(一)

来源:互联网 发布:java http编程实例 编辑:程序博客网 时间:2024/05/18 03:29

我做的项目是用纯C语言写的,一直以来都没有做单元测试。一来鲜有适合纯C语言单元测试的成熟框架,二来公司也没有硬性要求。突然有一天,领导要求我们给出单元测试代码覆盖率。

下面简单介绍下这个项目的基本情况和特殊之处:

该项目是运行在一个Frimware上面的,我对Firmware的理解是软件+硬件。就想苹果手机一样,特定的操作系统运行在特定的硬件上。效率和安全性都有一定的保证。

可以理解为该软件运行在一个私有的操作系统之上,由8个module(DLL) 组成。当Firmware启动后,首先boot loader调用操作系统,然后操作系统再依次调用这8个module,至此启动完成。

这8个module之间存在复杂的依赖关系。比如,某个module可能依赖其他多个module, 同时它又被其他多个module所依赖。但是限制条件是:两个module不能相互依赖。

虽然软件运行在特殊的操作系统上,但是我们一直在Windows上开发,因为厂家提供了一套SDK (Software development kit). 这个工具在Windows上安装之后,可以模拟实际的软件运行环境。好处就是我们可以在这套环境下调试代码,代价就是我们必须遵循特定的编码规范。SDK为我们解决了一个重要问题:多个module(DLL)之间的相互依赖问题。

但是SDK的致命缺点就是:无法统计代码覆盖率!SDK对于我们来说就是个黑盒,它是如何调用这8个module,以及如何让它们之间可以相互访问,我们不得而知。

所以我们无法借助SDK这套框架去做单元测试!

 

几经辗转,我们发现VS2012里集成了一个轻量级的CPPUnit, 或许我们可以尝试一下!

以前我对CPPUnit的看法是只支持C++代码的单元测试,不知道C语言是否适用。

 

上网查了一下,单元测试大概要遵循一下几个原则:

1. 测试代码与被测代码分开。

被测代码是一个Solution里包含了8个VCProject, 所以我打算至少单独建一个测试工程。

2. 被测代码对测试代码可见。

被测代码可以生成静态库或者动态库,链接到测试工程。

3. 对产品代码(被测代码)的改动尽量少。

不改动产品代码几乎是不可能的。所以我们用一个宏UNIT_TEST来控制编译条件。

4. 减少或者消除module间的相互依赖。

消除依赖的方法就是用桩函数代替其他module的依赖函数。缺点是要写大量的桩函数。

为了减轻工作量,我们决定暂时不消除module间依赖。

目前每个module都是以动态链接库的形式存在,如果相互调用的话,有两种方法:

(1) DLL动态调用DLL, 用LoadLibrary, GetProcAddress 等方法,而且还需要定义每个DLL的导出函数。缺点是需要在产品代码里注入大量代码。

(2) DLL静态调用DLL, 需要导入DLL的导入库,比如pragma comment(lib, "mylib.dll"), 缺点同上。

如果把module编成静态库的话,就无需在产品代码中注入新代码,因为只要将待测module和关联module的lib文件连接到测试工程中即可。注意测试工程将生成一个动态库,被测试程序调用。这部分是由CPPUnit实现的。


基于以上的分析,我们决定将每个module都编成静态库,链接到测试工程里。待续。。。

 

0 0
原创粉丝点击