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

使用Check框架测试C语言中调用printf的无返回值void函数

C语言测试仅输出到stdout的void函数方案

核心思路是将标准输出(stdout)临时重定向到内存缓冲区,调用待测函数后恢复标准输出,再比对缓冲区内容与预期值即可实现这类无返回值函数的测试。

具体实现步骤

  • 备份原始stdout的流指针,避免重定向后无法恢复正常输出
  • 创建关联动态内存缓冲区的内存流,将stdout重定向到该内存流
  • 调用待测试的void函数,此时函数内所有printf输出都会写入内存缓冲区
  • 刷新流确保所有输出完全写入缓冲区,恢复原始stdout
  • 对比缓冲区内容与预期输出,调用check框架的断言接口做校验
  • 测试完成后释放内存缓冲区,避免内存泄漏

代码示例(结合check框架)

首先是待测试的目标函数:

// 待测无返回值输出函数
void print_info(void) {
    printf("user id: %d\n", 1001);
    printf("user role: admin\n");
}

对应的check单元测试用例:

#include <check.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

START_TEST(test_print_info_output)
{
    // 备份原始stdout
    FILE *old_stdout = stdout;
    char *output_buf = NULL;
    size_t buf_len = 0;

    // 创建内存流并重定向stdout
    stdout = open_memstream(&output_buf, &buf_len);
    ck_assert_ptr_ne(stdout, NULL);

    // 调用待测函数
    print_info();

    // 刷新流并恢复stdout
    fflush(stdout);
    fclose(stdout);
    stdout = old_stdout;

    // 校验输出是否符合预期
    const char *expected = "user id: 1001\nuser role: admin\n";
    ck_assert_str_eq(output_buf, expected);

    // 释放缓冲区内存
    free(output_buf);
}
END_TEST

注意事项

  • 上述方案适用于POSIX兼容系统(Linux、macOS等),Windows环境可通过CreatePipe结合文件描述符替换实现相同逻辑,核心思路一致
  • 必须在测试逻辑结束后立刻恢复stdout,否则后续测试日志、程序输出都会写入缓冲区,导致控制台无正常输出
  • 若待测函数输出包含动态内容(如时间戳、随机值),可先对缓冲区内容做正则匹配或局部校验,不需要完全匹配整段字符串
  • 若编译环境不支持open_memstream,可改用管道实现:创建管道后将stdout的文件描述符替换为管道写端,从管道读端读取输出内容到缓冲区即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.08 20:57:04