aby*_*s.7 12 c c++ linux unit-testing network-programming
我想用单元测试来覆盖我的代码.这是好事.但我有一个问题 - 我有一个网络代码.该代码确实从主机名解析IPv4和IPv6地址,绑定到接口,侦听,连接等.
我假设存在一些可以部署在几乎任何工作站或某些编程技术上的C/C++测试框架,它允许我:
主要目标不是与机器上的真实网络接口进行交互或混乱.
你有什么建议吗?
在 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);
Run Code Online (Sandbox Code Playgroud)
你会像这样使用它:
#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;
}
Run Code Online (Sandbox Code Playgroud)
getaddrinfo来自被测库内的任何调用现在都将调用mocked_getaddrinfo.
elf_hook 作者 Anthony Shoumikhin 的综合文章在这里。
如果您愿意花费时间和精力,您可以对任何代码进行单元测试。基本上,通过单元测试,您有兴趣实现代码覆盖率的目标百分比以及某些行业的 MC/DC 覆盖率。在某些情况下,您需要编写模拟代码(将类似于操作系统 API / 套接字 API 的函数导出到被测单元的模块),这将有助于驱动“被测单元”中每个角落和缝隙的执行(a .c/.cpp 文件)通过返回您告诉它的值。
您可能需要为被测单元指定与测试应用程序其余部分不同的包含路径,以避免名称冲突,并且您可能还必须在测试标头中使用预处理器宏,以使模拟 API 看起来像真实的 API到您的“单位”并保持与生产代码中的相同。
您可以测试硬件驱动程序和任何类型的低级代码。
例如,如果您的代码正在写入和读取内存映射寄存器,您希望基于 FPGA 的逻辑能够更改这些寄存器,但您没有硬件(或者您很难在不实际前往火星的情况下生成测试条件),然后您可以编写宏/包装函数来读取和写入寄存器,这些寄存器将返回您的模拟值。以前用过CppUTest,很容易学。我想谷歌搜索会出现很多结果。
| 归档时间: |
|
| 查看次数: |
872 次 |
| 最近记录: |