我想用单元测试来覆盖我的代码。这是好事。但我有一个问题 - 我有一个网络代码。该代码确实从主机名解析IPv4和IPv6地址,绑定到接口,侦听,连接等。
我认为存在一些可以部署在几乎任何工作站上的C / C ++测试框架或者允许我使用的编程技术:
主要目标不是与机器上的真实网络接口进行交互或混乱。
你能提出什么建议?
答案 0 :(得分:4)
在ELF系统上,您可以使用elf_hook临时用您自己的模拟版本替换各种功能的真实版本。
它允许您将对共享库中的任何函数的调用重定向到您自己的任意函数。
dlopen
)elf_hook
)此方法的一个优点是您仍然可以在需要时调用原始函数。
getaddrinfo
成功,则可以调用系统版本。mocked_getaddrinfo
,并让它返回您想要的任何内容。mocked_getaddrinfo
函数,以测试多个方案elf_hook具有以下签名:
void* elf_hook(char const* library_filename,
void const* library_address,
char const* function_name,
void const* substitution_address);
您可以这样使用它:
#include <dlfcn.h>
#include "elf_hook.h"
void do_stuff(); // from the library under test (do_stuff calls getaddrinfo)
// our mocked function which will alter the behaviour inside do_stuff()
int mocked_getaddrinfo(const char* node,
const char* service,
const struct addrinfo* hints,
struct addrinfo** res)
{
// return a broken value to test a getaddrinfo failure
return 42;
}
// another version which actually calls the real function
int real_getaddrinfo(const char* node,
const char* service,
const struct addrinfo* hints,
struct addrinfo** res)
{
// the real getaddrinfo is available to us here, we only replace it in the shared lib
return getaddrinfo(node, service, hints, res);
}
int main()
{
const char* lib_path = "path/to/library/under/test.so";
// load the library under test
void* lib_handle = dlopen(lib_path, RTLD_LAZY);
// test 1: getraddrinfo is broken
//--------------------------------
// replace getaddrinfo with our 'mocked_getaddrinfo' version
elf_hook(lib_path, LIBRARY_ADDRESS_BY_HANDLE(lib_handle),
"getaddrinfo", mocked_getaddrinfo);
// call a function in the library under test where getaddrinfo fails
do_stuff();
// test 2: getraddrinfo is the system version
//--------------------------------
// replace getaddrinfo with our 'real_getaddrinfo' version
elf_hook(lib_path, LIBRARY_ADDRESS_BY_HANDLE(lib_handle),
"getaddrinfo", real_getaddrinfo);
// call the same function in the library, now getaddrinfo works
do_stuff();
dlclose(lib_handle);
return 0;
}
现在,在受测试的库中对getaddrinfo
的任何来电都会调用mocked_getaddrinfo
。
elf_hook作者Anthony Shoumikhin的综合文章是here。
答案 1 :(得分:0)
如果您愿意花时间和精力去做,可以对任何代码进行单元测试。基本上,对于单元测试,您有兴趣实现代码覆盖率的目标百分比,并且在一些行业MC / DC覆盖范围内。在某些情况下,您需要编写模拟代码(将类似OS API /套接字API的函数导出到您测试的单元中的模块),这将有助于通过被测单元中的每个角落和裂缝推动执行。 #34; (a .c / .cpp文件)返回你告诉它的值。
您可能需要从测试应用程序的其余部分为您的受测单元指定不同的包含路径以避免名称冲突,并且您可能还必须在测试标头中使用预处理器宏以使模拟API看起来像真实的交易你的&#34;单位&#34;并保持与生产代码中的相同。
您可以测试硬件驱动程序和任何类型的低级代码。
例如,如果您的代码正在编写和读取内存映射寄存器,您希望这些寄存器可以更改基于FPGA的逻辑,并且您没有硬件(或者您实际上很难生成测试条件前往火星),然后您可以编写宏/包装函数来读取和写入将返回模拟值的寄存器。过去曾使用CppUTest过去很容易学习。我想谷歌搜索会出现很多结果。