GoogleTest 测试夹具说明

GoogleTest Test Fixture Clarification

当我编写测试夹具来测试一些 C 代码时,我使用相同的设置: https://github.com/google/googletest/blob/master/googletest/docs/primer.md#test-fixtures-using-the-same-data-configuration-for-multiple-tests。待测c代码如下:

static struct {
    uint32_t success;
    uint32_t errors;
}stats;

uint32_t get_errors(void)
{
    return stats.errors;
}
uint32_t get_success(void)
{
    return stats.success;
}

void increment_errors(void)
{
    stats.errors++;
}
void increment_success(void)
{
    stats.success++;
}

void main_function(int arg)
{
    if (arg >=0)
        increment_success();
    else
        increment_errors();
}

现在,当我为此编写单元测试时:

class MyTest : public ::testing::Test
{
protected:

    void SetUp(void)
    {
    }

    void TearDown(void)
    {
    }
};

TEST_F(MyTest, Test1)
{
        main_function(1);
    EXPECT_EQ(1, decoder_get_success());
    EXPECT_EQ(0, decoder_get_errors());
}

TEST_F(MyTest, Test2)
{
        main_function(40);
    EXPECT_EQ(1, decoder_get_success()); //This is a fail as number ends up being 2 not 1 which includes prev. test results
    EXPECT_EQ(0, decoder_get_errors());
}

现在我注意到,当我为此代码编写不同的测试装置时,stats 结构变量的值不会重置,即如果第一个测试应该增加成功数,那么当我们开始第二个测试时,成功数= 1 不是 0 等等。我发现这种行为很奇怪,因为我认为它应该在每次测试时重置所有内容。

为了解决这个问题,我最终在 C 代码中添加了以下函数:

void stats_init(void)
{
    decoder_stats.errors = 0;
    decoder_stats.success = 0;
}

并将其添加到 TearDown():

void TearDown(void)
{
    stats_init();
}

这可以确保所有内容都被重置。这里的问题是在使用测试夹具时这是 gtests 的正确行为吗?我认为不应该要求 m 定义 init() 函数并将其添加到 TearDown() 是错误的吗?

gtest 的正确行为是为您定义的每个 TEST_F 创建一个新的 MyTest 实例。

因此,通过在测试夹具中定义成员属性,您可以确保在每个 TEST_F

中将拥有不同的成员属性实例

不幸的是,您正在测试一个实例化一次的静态变量。 gtest 并没有神奇地知道它。所以,是的,您必须在每个 TEST_F.

之间重置静态结构的值

就我个人而言,我将使用 SetUp() 而不是 TearDown 来调用 stats_init。