包装 open() 进行单元测试将使 gcov 无法打开 gcda 文件
Wrapping open() for unit testing will make gcov not able to open gcda file
我正在为某些 C 程序实施使用测试。为此,我使用 GCC 的 -Wl,--wrap=open
来模拟 stdlib 的 open()
函数并检查它是否已使用正确的选项调用。
然而,这样做时 gcov 在写入其 .gcda
文件时遇到了一些问题。我想我定义的 mock 不仅被我的测试使用,也被 gcov 使用。下面是一个如何重现这个的小例子:
#include <stdio.h>
int __wrap_open(const char *path, int flags, int mode)
{
printf("hello from __wrap_open\n");
return -1;
}
int main(void)
{
return 0;
}
并用gcc main.c -Wl,--wrap=open -fprofile-arcs -ftest-coverage -lgcov
编译。为了使示例保持简单,我使用 CMocka 删除了单元测试部分,以显示我遇到的错误。
当 运行 可执行文件 a.out
我使用 GCC 和 gcov 6.3.0 得到以下输出:
$ ./a.out
hello from __wrap_open
hello from __wrap_open
profiling:/home/romain/wrap-bug/main.gcda:Cannot open
有没有办法为我的单元测试目的模拟 open()
函数 和 以便能够使用 gcov 来生成代码覆盖率数据?也许有办法告诉 gcov 使用 __real_open()
?
一个简单的方法是:
- 检查传递给
open()
的文件路径是否是您的分析文件
- 如果是,将调用传递给
__real_open()
即
int __real_open(const char *path, int flags, int mode);
int __wrap_open(const char *path, int flags, int mode)
{
if (strlen(path) > 5 && !strcmp(path + strlen(path) - 5, ".gcda"))
return __real_open(path, flags, mode);
printf("hello from __wrap_open\n");
return -1;
}
使用这种方式,您当然可以轻松添加更多文件,这些文件不应被篡改。
我正在为某些 C 程序实施使用测试。为此,我使用 GCC 的 -Wl,--wrap=open
来模拟 stdlib 的 open()
函数并检查它是否已使用正确的选项调用。
然而,这样做时 gcov 在写入其 .gcda
文件时遇到了一些问题。我想我定义的 mock 不仅被我的测试使用,也被 gcov 使用。下面是一个如何重现这个的小例子:
#include <stdio.h>
int __wrap_open(const char *path, int flags, int mode)
{
printf("hello from __wrap_open\n");
return -1;
}
int main(void)
{
return 0;
}
并用gcc main.c -Wl,--wrap=open -fprofile-arcs -ftest-coverage -lgcov
编译。为了使示例保持简单,我使用 CMocka 删除了单元测试部分,以显示我遇到的错误。
当 运行 可执行文件 a.out
我使用 GCC 和 gcov 6.3.0 得到以下输出:
$ ./a.out
hello from __wrap_open
hello from __wrap_open
profiling:/home/romain/wrap-bug/main.gcda:Cannot open
有没有办法为我的单元测试目的模拟 open()
函数 和 以便能够使用 gcov 来生成代码覆盖率数据?也许有办法告诉 gcov 使用 __real_open()
?
一个简单的方法是:
- 检查传递给
open()
的文件路径是否是您的分析文件 - 如果是,将调用传递给
__real_open()
即
int __real_open(const char *path, int flags, int mode);
int __wrap_open(const char *path, int flags, int mode)
{
if (strlen(path) > 5 && !strcmp(path + strlen(path) - 5, ".gcda"))
return __real_open(path, flags, mode);
printf("hello from __wrap_open\n");
return -1;
}
使用这种方式,您当然可以轻松添加更多文件,这些文件不应被篡改。