You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Unity C测试框架中使用TEST_PROTECT实现示例中的错误处理?

Unity C测试框架错误处理问题:手动实现与TEST_PROTECT行为不一致

我写了一段代码复现Unity C测试框架的错误处理问题——手动用setjmp/longjmp捕获段错误并标记测试失败的逻辑能正常工作,但按照文档使用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); /* 这里是否应该调用UNITY_ABORT()? */
}

int function_that_crashes(void)
{
    int *val = NULL;
    return *val;
}

void test_function_crash(void)
{
    if (setjmp(jump_buffer) == 0) /* 这里是否应该替换成TEST_PROTECT()? */
    {
        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();
}

问题原因分析

  1. 信号处理的完整性差异
    手动代码只处理了SIGSEGV信号,但Unity的TEST_PROTECT内部会通过UNITY_SETUP_SIGNAL_HANDLERS()注册多个崩溃信号的处理(比如SIGABRT、SIGILL、SIGFPE等),覆盖更多崩溃场景。

  2. 信号处理的恢复逻辑缺失
    手动注册的信号处理函数没有在测试结束后恢复默认行为,可能导致测试退出后程序的信号处理异常;而TEST_PROTECT会在保护块执行完成后自动恢复原有的信号处理配置。

  3. Jump Buffer的上下文差异
    Unity的TEST_PROTECT使用框架内部维护的jump buffer,而非用户自定义的,避免了上下文冲突或保存不完整的问题。手动实现的jump buffer可能没有考虑Unity框架的内部状态,导致跳转后框架无法正确处理测试结果。

  4. 宏的隐藏逻辑
    宏展开看起来等价,但TEST_PROTECT还包含了对Unity测试状态的维护(比如标记测试进入保护模式、处理失败后的状态流转),这些细节是手动代码没有覆盖的。

正确使用TEST_PROTECT的示例

直接使用Unity提供的宏即可实现预期的崩溃捕获效果,无需手动编写信号处理和跳转逻辑:

#include <stdio.h>
#include <unity.h>

void setUp(void) {}
void tearDown(void) {}

int function_that_crashes(void)
{
    int *val = NULL;
    return *val;
}

void test_function_crash(void)
{
    TEST_PROTECT()
    {
        TEST_ASSERT_EQUAL_INT32(0, function_that_crashes());
    }
    TEST_ON_FAILURE
    {
        TEST_FAIL_MESSAGE("[ERROR] 程序崩溃(如段错误)被捕获");
    }
}

int main(void)
{
    UNITY_BEGIN();
    RUN_TEST(test_function_crash);
    return UNITY_END();
}

关键注意事项

  • 不要混合使用手动的setjmp/longjmp和Unity的TEST_PROTECT,框架已经封装了完整的崩溃处理逻辑
  • TEST_PROTECT块内的代码发生崩溃时,会自动跳转到TEST_ON_FAILURE块执行,无需手动处理信号和跳转
  • 框架会自动处理信号恢复、测试状态维护等细节,确保测试流程的正确性

内容的提问来源于stack exchange,提问作者Sam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 06:31:12