I have a unit test that I need to run for 200 possible combinations of data. (The production implementation has the data to be tested in configuration files. I know how to mock these values). I prefer nit writing separate test case for each combination and to use some way of looping through the data. Is there some such direct way using Google test for C++?
-
Why don't you use an array of structs to hold your test data, and loop though each entry? You could have just one test case that tests all combinations. – Emile Cormier Nov 03 '12 at 20:13
-
Hi Emile, thanks for the suggestion. When I tried it, if one combination fails, it stops the test case from proceeding further and does not report the success rate properly. At the end of the day, these are different test cases for me. – Karthick S Nov 04 '12 at 04:06
2 Answers
You can make use of gtest's Value-parameterized tests for this.
Using this in conjunction with the Combine(g1, g2, ..., gN)
generator sounds like your best bet.
The following example populates 2 vector
s, one of int
s and the other of string
s, then with just a single test fixture, creates tests for every combination of available values in the 2 vector
s:
#include <iostream>
#include <string>
#include <tuple>
#include <vector>
#include "gtest/gtest.h"
std::vector<int> ints;
std::vector<std::string> strings;
class CombinationsTest :
public ::testing::TestWithParam<std::tuple<int, std::string>> {};
TEST_P(CombinationsTest, Basic) {
std::cout << "int: " << std::get<0>(GetParam())
<< " string: \"" << std::get<1>(GetParam())
<< "\"\n";
}
INSTANTIATE_TEST_CASE_P(AllCombinations,
CombinationsTest,
::testing::Combine(::testing::ValuesIn(ints),
::testing::ValuesIn(strings)));
int main(int argc, char **argv) {
for (int i = 0; i < 10; ++i) {
ints.push_back(i * 100);
strings.push_back(std::string("String ") + static_cast<char>(i + 65));
}
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
-
4"INSTANTIATE_TEST_CASE_P is deprecated, please use " "INSTANTIATE_TEST_SUITE_P" https://github.com/google/googletest/blob/f16d43cd38e9f2e41357dba8445f9d3a32d4e83d/googletest/include/gtest/internal/gtest-internal.h#L1295 – hojin May 28 '21 at 07:33
Use an array of structs (called, say, Combination
) to hold your test data, and loop though each entry in a single test. Check each combination using EXPECT_EQ
instead of ASSERT_EQ
so that the test isn't aborted and you can continue checking other combinations.
Overload operator<<
for a Combination
so that you can output it to an ostream
:
ostream& operator<<(ostream& os, const Combination& combo)
{
os << "(" << combo.field1 << ", " << combo.field2 << ")";
return os;
}
Overload operator==
for a Combination
so that you can easily compare two combinations for equality:
bool operator==(const Combination& c1, const Combination& c2)
{
return (c1.field1 == c2.field1) && (c1.field2 == c2.field2);
}
And the unit test could look something like this:
TEST(myTestCase, myTestName)
{
int failureCount = 0;
for (each index i in expectedComboTable)
{
Combination expected = expectedComboTable[i];
Combination actual = generateCombination(i);
EXPECT_EQ(expected, actual);
failureCount += (expected == actual) ? 0 : 1;
}
ASSERT_EQ(0, failureCount) << "some combinations failed";
}

- 28,391
- 15
- 94
- 122
-
Hi Emile, though this sounds easy, I am getting the count of test cases executed as 1 even for 100s of combinations in expectedComboTable. Due to this, I would need to redo the reporting dashboard et al to give the exact count of combinations that failed for cases which have combinations. Too much of a headache. So, I will not be able to use it. Thanks for the idea. – Karthick S Nov 09 '12 at 04:38