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

如何使用Ceedling测试含静态全局变量的函数并实现全面测试覆盖?

Testing a Function with Static Global Variables in Ceedling

Testing functions that depend on static global variables can feel like a headache at first—since those variables are locked to their source file, your test code can't normally access them. But don't worry, Ceedling (built on Unity and CMock) has a couple of clean ways to handle this so you can test every possible value of global_var and hit full coverage.

Approach 1: Expose the Variable for Testing with Preprocessor Macros

This is the most straightforward method if you don't mind a tiny, non-intrusive tweak to your production code. The idea is to conditionally remove the static qualifier when building for tests, turning the variable into a global that your test code can modify.

Step 1: Modify the Source File (file_under_test.c)

Wrap the static variable in a preprocessor check for a test-specific define:

#ifdef TESTING
int global_var;  // Global when testing
#else
static int global_var;  // Static in production
#endif

int func_under_test(){
 switch(global_var){
 case X: return SOME_VALUE;
 case Y: return SOME_OTHER_VALUE;
 // ... other cases
 default: return DEFAULT_VALUE;
 }
}

Step 2: Configure Ceedling to Define TESTING

Add the TESTING define to your project.yml so it's automatically set when building tests:

:test_build:
  :compile_definitions:
    - TESTING

Step 3: Write Your Test Cases (test_file_under_test.c)

Now you can directly access and modify global_var in your tests:

#include "unity.h"
#include "file_under_test.h"

// Declare the variable (since it's global in test builds)
extern int global_var;

void setUp(void) {
    // Reset the variable before each test to avoid cross-test contamination
    global_var = 0;
}

void test_func_under_test_case_X(void) {
    global_var = X;
    TEST_ASSERT_EQUAL(SOME_VALUE, func_under_test());
}

void test_func_under_test_case_Y(void) {
    global_var = Y;
    TEST_ASSERT_EQUAL(SOME_OTHER_VALUE, func_under_test());
}

void test_func_under_test_default_case(void) {
    global_var = 999;  // A value not covered by any case
    TEST_ASSERT_EQUAL(DEFAULT_VALUE, func_under_test());
}

Approach 2: Add a Test-Only Setter Function (No Global Exposure)

If you prefer not to make the variable global even in test builds, add a lightweight setter function that's only compiled during testing. This keeps your production code's encapsulation intact.

Step 1: Add the Setter to file_under_test.c

static int global_var;

#ifdef TESTING
// Test-only function to set the static variable
void set_global_var(int value) {
    global_var = value;
}
#endif

int func_under_test(){
 // ... same as before
}

Step 2: Declare the Setter in Your Test File

Add a prototype for the setter in your test file (or create a test-only header if you have multiple tests needing this):

#include "unity.h"
#include "file_under_test.h"

// Declare the test-only setter
void set_global_var(int value);

void setUp(void) {
    // Reset the variable before each test
    set_global_var(0);
}

void test_func_under_test_case_X(void) {
    set_global_var(X);
    TEST_ASSERT_EQUAL(SOME_VALUE, func_under_test());
}

// ... repeat for other cases and default

Verifying Coverage

Once your tests are written, run ceedling test:all to execute them. Ceedling will generate a coverage report (look in the build/reports/coverage directory) that shows you which parts of func_under_test are covered. As long as you've written a test for every case in the switch statement (including the default), you'll hit 100% branch coverage for that function.


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 16:47:32