1

为了对我的一个程序实施单元测试,我添加了一个 makefile 规则,以便在运行“make check”时将程序构建为静态库。我用#ifndef TEST_LIB#endif包装 main() (TEST_LIB在构建为库时定义)。

然后我创建了一些小的 C 文件来测试该库中的一些函数。

库中的一些函数是静态声明的。

当我尝试编译测试时,您可能会猜到会产生如下警告:

/../test/config_test.c:15:3:警告:函数“realize_home”的隐式声明 [-Wimplicit-function-declaration]

因为realize_home是在程序的源代码(一个.c 文件)中静态声明的。

我尝试的一种解决方案是将#include config_rmw.c(包含静态函数)添加到.c 单元文件(config_test)中。这实际上有效并且在我编译时不会给我任何警告,即使 config_rmw.c 已经内置到库中。

我想到的另一个解决方案是

#ifndef TEST_LIB
static
#endif
void function()
{
    definition
}

并将原型添加到标题中,即#ifdef 语句。

#ifdef TEST_LIB
function prototype
#endif

但是这样做感觉不太对,尤其是当我继续实施更多单元测试时,必须为更多功能完成它时。

我最近在一本书中读到静态函数应该放在头文件中。我试过了,但它只是部分地解决了我的问题。我结束了编译器警告,例如:

在 ../../src/rmw.c:38:0: ../../src/config_rmw.h:86:1 中包含的文件中:警告:“realize_home”已定义但未使用 [-Wunused-function ] implementation_home (char **str) ^~~~~~~~~~~~

我做了一些阅读,我有点理解为什么会发生这种情况。基本上这意味着我会在每个 .c 文件中获得该函数的单独副本,其中 #includes 定义了它的头文件。我不需要。我静态声明一些函数的原因是因为它们只需要在一个文件中。

然后我读了一些评论,人们说静态函数永远不应该在头文件中定义!

所以......我一直想知道最好的方法和其他选择。我更喜欢让我的程序井井有条,并练习良好的编码技能。

我只使用基于脚本的方法编写了一些测试,这不需要将我的程序构建为库,但我认为使用这两种方法会有优势,具体取决于正在测试的函数。

更新(添加)该程序有 20 个源文件(包括标题)和约 4K 行代码。

4

1 回答 1

0

我会按照这里的建议做

我认为#include .c 文件对于测试会很好。如果由于某种原因导致了麻烦,pan64 建议的“包装函数”方法应该是一个可以接受的折衷方案。

static void realize_home(char **)
{
    implementation
}
#ifdef UNITTEST
void test_realize_home(char **v)
{
    realize_home(v);
}
#endif
于 2018-12-18T19:22:40.510 回答