ciel
ciel

Reputation: 81

How to parameterize test group in gtest?

I wrote following sample test:

// g++ t.cpp -I googletest/include -pthread libgtest{,_main}.a
#include <gtest/gtest.h>

class C : public ::testing::TestWithParam<int>
{
public:
    void SetUp(){
        int n=GetParam();
        std::cout<<"SetUp "<<n<<std::endl;
    }
    static void SetUpTestCase(){
#if 0
        // Condition parameter_ != nullptr failed. GetParam() can only be called inside a value-parameterized test -- did you intend to write TEST_P instead of TEST_F?
        int n=GetParam();
        std::cout<<"SetUpTestCase "<<n<<std::endl;
#endif
        std::cout<<"SetUpTestCase"<<std::endl;
    }
};

TEST_P(C,T1){
    int n=GetParam();
    std::cout<<"T1 "<<n<<std::endl;
}
TEST_P(C,T2){
    int n=GetParam();
    std::cout<<"T2 "<<n<<std::endl;
}

INSTANTIATE_TEST_SUITE_P(S, C, ::testing::Values(1,2));

This test prints:

Running main() from gtest_main.cc
[==========] Running 4 tests from 1 test suite.
[----------] Global test environment set-up.
[----------] 4 tests from S/C
SetUpTestCase
[ RUN      ] S/C.T1/0
SetUp 1
T1 1
[       OK ] S/C.T1/0 (0 ms)
[ RUN      ] S/C.T1/1
SetUp 2
T1 2
[       OK ] S/C.T1/1 (0 ms)
[ RUN      ] S/C.T2/0
SetUp 1
T2 1
[       OK ] S/C.T2/0 (0 ms)
[ RUN      ] S/C.T2/1
SetUp 2
T2 2
[       OK ] S/C.T2/1 (0 ms)
[----------] 4 tests from S/C (0 ms total)

[----------] Global test environment tear-down
[==========] 4 tests from 1 test suite ran. (0 ms total)
[  PASSED  ] 4 tests.

I'd like to see "SetUp 1" only once. Is it possible? I tried to call GetParam() in SetUpTestCase(), but it caused error Condition parameter_ != nullptr failed. GetParam() can only be called inside a value-parameterized test -- did you intend to write TEST_P instead of TEST_F?. Actually my real setup process can take up to 60secs for each test parameter (and the process result can be shared among tests (here T1 and T2)), so I'd like to put the process to SetUpTestCase().

Upvotes: 1

Views: 2719

Answers (1)

ciel
ciel

Reputation: 81

workaround can be recording the resource into a map.

// g++ t.cpp -I googletest/include -pthread libgtest{,_main}.a
#include <gtest/gtest.h>

class C : public ::testing::TestWithParam<int>
{
public:
    void SetUp(){
        int n=GetParam();
        if(sharedResource.find(n)==sharedResource.end()){
            std::cout<<"SetUp "<<n<<std::endl;
            std::shared_ptr<char> p(new char[10000000]);
            sharedResource[n] = p;
        }
    }
    static void TearDownTestCase(){
        std::map<int,std::shared_ptr<char>>::iterator it=sharedResource.begin();
        for(;it!=sharedResource.end();){
            std::cout<<"TearDown "<<it->first<<std::endl;
            it = sharedResource.erase(it);
        }
    }
    static std::map<int,std::shared_ptr<char>>sharedResource;
};
std::map<int,std::shared_ptr<char>> C::sharedResource;

TEST_P(C,T1){
    int n=GetParam();
    std::cout<<"T1 "<<n<<std::endl;
    std::shared_ptr<char> p = sharedResource[n];
}
TEST_P(C,T2){
    int n=GetParam();
    std::cout<<"T2 "<<n<<std::endl;
    std::shared_ptr<char> p = sharedResource[n];
}

INSTANTIATE_TEST_SUITE_P(S, C, ::testing::Values(1,2));

Upvotes: 2

Related Questions