Как проверить функцию с внутренним состоянием?

Я занимаюсь модульным тестированием следующей функции, используя 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)));
}

Функция имеет внутреннее состояние в виде статической переменной function-scope voltageGoodhyst (потому что выходной сигнал гистерезисный).

Из-за гистерезиса мои тесты должны проходить в определенном порядке. что плохо Я хотел бы избежать необходимости делать переменную более широкой, поскольку это единственная функция, связанная с этой функцией (объект, на который указывает ParametersHandle_t соответствует определенному макету, поэтому я тоже не могу добавить его туда)... Есть ли другой способ настроить это или написать тесты так, чтобы они не требовались для выполнения в определенном порядке?

1 ответ

Одной из тактик будет создание ваших тестов таким образом, чтобы после их запуска статическая переменная имела такое же значение.

Например, так как он инициализирован как static bool voltageGoodHyst = false;каждый раз, когда вы запускаете модульный тест, который меняет его на trueотправить окончательный запрос PRM_inputVoltageIsGood(p, 0) сделать статическую переменную false.

Таким образом, независимо от порядка выполнения модульных тестов, вы будете знать, что статическая переменная имеет значение false, при входе в следующий тест.

Другие вопросы по тегам