如何测试具有内部状态的函数?

时间:2016-11-22 15:50:31

标签: c unity-test-framework

我正在使用Ceedling对以下函数进行单元测试。

bool PRM_inputVoltageIsGood(ParameterHandle_t p, float voltage) {
    static bool voltageGoodHyst = false;
    /* Check if voltage has risen above ON point. */
    if ((!voltageGoodHyst) && (voltage > p->vin_on)) {
        voltageGoodHyst = true;
    }
    /* Check if voltage has fallen below OFF point. */
    else if ((voltageGoodHyst) && (voltage < p->vin_off)) {
        voltageGoodHyst = false;
    }
    return voltageGoodHyst;
}

使用以下测试:

void test_PRM_inputVoltageIsGood_should_stayAtFalse_before_risingOverVInOn(void)
{
    float i;
    p->vin_on = 10.0;
    p->vin_off = 5.0;
    for (i = 0; i <= p->vin_on; ++i)
        TEST_ASSERT_FALSE(PRM_inputVoltageIsGood(p, i));
}

void test_PRM_inputVoltageIsGood_should_switchToTrue_when_risingOverVInOn(void)
{
    p->vin_on = 10.0;
    p->vin_off = 5.0;
    TEST_ASSERT_FALSE(PRM_inputVoltageIsGood(p, p->vin_on));
    TEST_ASSERT_TRUE(PRM_inputVoltageIsGood(p, (p->vin_on + 1)));
}

void test_PRM_inputVoltageIsGood_should_stayAtTrue_before_fallingUnderVInOff(void)
{
    float i = 0;
    p->vin_on = 10.0;
    p->vin_off = 5.0;
    for (i = p->vin_on + 1; i >= p->vin_off; --i)
        TEST_ASSERT_TRUE(PRM_inputVoltageIsGood(p, i));
}

void test_PRM_inputVoltageIsGood_should_switchToFalse_when_fallingUnderVInOff(void)
{
    p->vin_on = 10.0;
    p->vin_off = 5.0;
    TEST_ASSERT_TRUE(PRM_inputVoltageIsGood(p, p->vin_off));
    TEST_ASSERT_FALSE(PRM_inputVoltageIsGood(p, (p->vin_off - 1)));
}

该函数具有函数范围静态变量voltageGoodhyst形式的内部状态(因为输出是滞后的)。

由于滞后现象,我的测试必须按一定顺序进行。这很糟糕。我有点想避免让变量有更广泛的范围,因为这是唯一与此功能有关的函数(ParametersHandle_t指向的对象符合特定的布局,所以我不能在那里添加它)...有没有其他方法可以调整或编写测试,以便它们不需要按特定顺序执行?

1 个答案:

答案 0 :(得分:1)

一种策略是创建测试,使之后运行它们,静态变量将具有相同的值。

例如,由于它已初始化为static bool voltageGoodHyst = false;,因此每次运行将其更改为true的单元测试时,请发送最终请求PRM_inputVoltageIsGood(p, 0)以使其成为静态变量错误。

这样,无论单元测试执行的顺序如何,当您进入下一个测试时,您都会知道静态变量是错误的。