Search code examples
c++googletest

GoogleTest Test Fixture Clarification


When I write Test fixture to test some c code I use the same set up from: https://github.com/google/googletest/blob/master/googletest/docs/primer.md#test-fixtures-using-the-same-data-configuration-for-multiple-tests. The c code to be tested is as such:

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();
}

Now when I write unit tests for this as such:

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());
}

Now I have noticed that when I write different test fixtures for this code the values of the stats struct variables do not reset i.e. if first test is supposed to increment success number then when we start the second test the number of success = 1 not 0 and so on and so forth. I find this behavior odd as I assumed it is supposed to reset everything with each test.

To solve this issue I ended up adding the following function to c code:

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

and add this to the TearDown():

void TearDown(void)
{
    stats_init();
}

This makes sure that all gets reset. The question here is this the correct behavior for gtests when using test fixtures? Am I wrong to assume that it should not require m to define the init() function and add it to TearDown()?


Solution

  • The correct behavior of gtest is to create a new and fresh MyTest instance for each TEST_F you defined.

    So, by defining a member attribute in the test fixture you are sure that you will have a different instance of your member attribute in each TEST_F

    Unfortunetly, you are testing a static variable which is instanciate once. gtest does not magically known about it. So, yes, you have to reset the value of your static structure between each TEST_F.

    Personnally, I will use SetUp() instead of TearDown to call stats_init.