我创建了以下代码片段来重现 Unity C 测试框架中的错误处理机制的问题。
通过使用 Unity C 测试框架文档中描述的 TEST_PROTECT(),我无法实现我在以下示例中手动执行的错误处理机制。
但我不知道我错过了什么。
#include <stdio.h>
#include <unity.h>
#include <signal.h>
#include <setjmp.h>
void setUp(void) {}
void tearDown(void) {}
static jmp_buf jump_buffer;
void segfault_handler(int signal)
{
longjmp(jump_buffer, 1); /* should I put UNITY_ABORT() here? */
}
int function_that_crashes(void)
{
int *val = NULL;
return *val;
}
void test_function_crash(void)
{
if (setjmp(jump_buffer) == 0) /* should I put TEST_PROTECT() here? */
{
signal(SIGSEGV, segfault_handler);
TEST_ASSERT_EQUAL_INT32(0, function_that_crashes());
}
else
{
TEST_FAIL_MESSAGE("[ERROR] Segmentation fault caught\n");
}
}
int main(void)
{
UNITY_BEGIN();
RUN_TEST(test_function_crash);
return UNITY_END();
}
如果我使用 TEST_PROTECT 和 TEST_ABORT 并在宏替换后检查代码,一切似乎都与我手动编写的代码相同。但是当我运行代码时,行为有所不同。
Unity C 测试框架有宏
TEST_PROTECT
在幕后调用 setjmp,但在本例中不需要它,因为没有人调用 longjump。
似乎工作正常的解决方案是将函数处理程序附加到信号 SIGSEGV 来终止失败的测试,例如
TEST_FAIL_MESSAGE("[ERROR] Segmentation fault caught");
segfault_handler
通过测试夹具单独连接到每个测试。
#include <signal.h>
#include <unity.h>
void segfault_handler(int signal)
{
TEST_FAIL_MESSAGE("[ERROR] Segmentation fault caught");
}
void setUp(void)
{
signal(SIGSEGV, segfault_handler);
}
void tearDown(void) {}
int function_that_crashes(void)
{
int *val = NULL;
return *val;
}
void test_function_crash(void)
{
TEST_ASSERT_EQUAL_INT32(0, function_that_crashes());
}
int main(void)
{
UNITY_BEGIN();
RUN_TEST(test_function_crash);
RUN_TEST(test_function_crash);
RUN_TEST(test_function_crash);
return UNITY_END();
}