3

我正在使用 CUnit 框架来显示测试结果。(我是一个编程和新手,所以一步一步的回答真的很感激)。

当我测试我希望 exit() 的函数时,有什么方法可以使用相同的 CUnit 框架?对我来说似乎不是这样,但我还是很想问 - 它会显示通过/失败结果以及我的其他 CUnit 测试,所以它是理想的。

如果没有,我一直在寻找其他适合新手的解决方案(例如这个 SO post),但我不能使用 GOTO/setjmp/longjmp。该解决方案还需要便携。

我正在使用 Mac & gcc 命令行来运行此代码。

编辑 建议的解决方案之一是使用 C Pre-Processor (CPP) Directive / "mocking",这看起来很理想吗?我在 test.c 文件中使用了以下代码:

#define ERROR(PHRASE) {fprintf(stderr,"Fatal Error %s occurred in %s, line %d\n",PHRASE, FILE, LINE); exit(2);} 
#ifdef ERROR(PHRASE)
#define ERROR(PHRASE) {printf("In test phase");} 
#endif 
#ifndef ERROR(PHRASE #define ERROR(PHRASE) {printf("Not In test phase");} 
#endif

这是终端给我的错误消息:

test.c:30:9: warning: 'ERROR' macro redefined [-Wmacro-redefined]
#define ERROR(PHRASE) {printf("In test phase");}
        ^
test.c:26:9: note: previous definition is here
#define ERROR(PHRASE) {fprintf(stderr,"Fatal Error %s occured in %s, lin...
        ^
test.c:32:14: warning: extra tokens at end of #ifndef directive
      [-Wextra-tokens]
#ifndef ERROR(PHRASE) {printf("Not In test phase");}

删除 (PHRASE) 仍然会产生相同的错误。

编辑 如果对其他人有帮助,使用 #ifdef 进行模拟是最终解决此问题的最简单方法。这个网站也很有帮助。

4

3 回答 3

4

只是为了让您知道要搜索什么,您想要做的是“模拟”exit()呼叫。基本思想是为退出函数选择不同的实现,通常在编译时。坦率地说,C 语言并没有让这变得特别容易,但是有一些选项具有不同程度的可移植性和侵入性。

这篇文章描述了一些非常便携但也相当侵入性的东西。基本上,您使用宏和/或函数指针来回切换,这意味着稍微修改您的代码,但老实说,这没什么大不了的。

对于可能不那么具有侵入性但也不那么便携的东西,这篇文章有几个想法(我相信两者都可以在 MacOS 上工作)。在这里,您可以让链接器将exit()调用重定向到您提供的另一个函数。好消息是它不需要对您的代码进行任何修改。坏消息是它需要你获得链接器的合作,并且不能在任何地方工作(LD_PRELOAD不能在 Windows 上工作,AFAIK--wrap需要 GNU ld 或兼容的东西)。

于 2019-01-17T03:47:22.073 回答
0

如果你想做一些非侵入性的事情,你可以将被测函数作为一个单独的进程运行。您从CreateProcess(Windows) 或fork(可能execv在 Max 和 Linux 上开始。然后,您的测试代码wait用于测试退出代码并在创建的进程正确退出时通过。

于 2021-02-23T19:47:36.137 回答
0

如果在测试方面存在问题/增加工作量,可能会考虑的一个方面是,是否有任何范围可以以某种方式更改正在测试的程序,这将有助于测试,而不会显着增加代码的复杂性。

在这种情况下,是否可以用函数的错误返回代码替换对 exit() 的调用,以便调用者可以在实际退出之前执行诸如整理或记录状态之类的事情?如果是这样,这既简化了测试,也可能简化了在发布/生产中实际使用代码时的故障查找,因为要弄清楚为什么程序会在你身上起死回生可能会非常棘手,特别是如果代码是隐藏在库函数中!

于 2019-01-17T18:39:43.290 回答