我想为我的C库编写黑盒测试,它使用标准的C时间函数(time(),localtime(),gmtime()等)在其输出中使用时间戳。输出是编码的,所以我需要用一些测试模拟或“后门”替换那些时间函数,这样我就可以控制我的库从time()函数而不是当前系统时间获取的值,所以我可以在我的测试中正确编写检查。
实现这一目标的最佳方法是什么?我可以在生产库中使用这样的支持(可能有一些旋钮?),或者我应该以2种形式编译我的库:使用实时()函数进行生产以及使用我自己的受控时间()函数进行测试?
我对跨平台解决方案感兴趣,所以像LD_PRELOAD这样的技巧对我来说不是一个解决方案。
更新:我明白我应该提供一些实时()函数的包装器,我会做那些包装器。我的问题是:我可以在生产库中使用那些并在运行时控制它们,或者我永远不应该这样做并且总是应该编译2个库:一个用于生产,第二个用于测试?
答案 0 :(得分:2)
过去,我为嵌入式C项目完成此操作的方法是创建两个项目/配置 一种配置适用于生产环境,包含所有生产代码(包括依赖项),另一种配置用于单元测试,包含测试驱动程序和所有模拟。这两种配置共享了要测试的代码的来源 在单元测试环境中,我只是链接到被测代码所需的所有外部函数的模拟或伪造。
有几种方法可以将待测代码链接到它所需的模拟:
您可以创建一组包装器宏,您可以使用define切换它们。例如:
#ifdef UNIT_TEST
#define my_time time_mock
#else
#define my_time time
#endif
更新:即使您的生产代码进入库,单元测试配置也应生成(一个或多个)可执行文件。
单元测试代码不应包含在生产库中(尽管您可以考虑将其包含在源代码分发中),因为它只会增加可能导致错误的额外行李。如果您的某个客户意外地在单元测试模式下切换库并开始抱怨它已损坏,您是否愿意?
答案 1 :(得分:1)
我会将调用包装为静态变量(unitTest)。因此,您可以随时从配置文件初始化该行为。
time_t myTime( time_t * timer )
{
if ( unitTest ) {
return TIME_TEST;
}
return time( timer );
}
答案 2 :(得分:1)
(我认为你不是在询问实现细节,而是要让它成为编译时,部署时或运行时配置方面。)
我认为这取决于。
如果你有一个众所周知的配置机制(无论是配置文件,环境变量,命令行参数,等等),我会在那里添加它作为配置项。然后,您可以在生产中使用与测试中完全相同的二进制文件。一些组织非常严格地要求这样做。
由于您在生产中永远不需要该功能,我建议将其作为编译时配置项,以便您可以100%确定您永远不会错误配置生产中的应用程序,因为不支持该功能。 (当然,你必须绝对确保你永远不会将为编译而编译的二进制文件部署到生产中。)我认为条件定义/条件编译是一个不错的选择。
这就是关于它的所有内容,不是吗?