I am using gtest to create unit tests to my c++ program. In my tests I have to write a lot of checks like this:
ASSERT_TRUE(myObject.IsValid());
EXPECT_EQ(myObject.GetSomeAttribute(), expectedValue);
I have to write both checks because if I omit the ASSERT_TRUE
and myObject
happened to be not valid, than myObject.GetSomeAttributre()
call crashes. That's not good even in tests.
What I want is to write something like:
EXPECT_XXX_EQ(myObject.GetSomeAttribute(), expectedValue);
This line of code should do approximately the same as the original two lines (with optional bonus that if myObject
is not valid, this will be reported, GetSomeAttribute()
would not be called, but the test will continue running).
How can I write such custom assert/expect?
Handling exceptions Because Google doesn't use exceptions, gtest doesn't handle them. If you're testing code that can throw exceptions, then you need to try/catch them yourself, and then use the ADD_FAILURE and/or FAIL macros as appropriate. ADD_FAILURE records a non-fatal failure, while FAIL records a fatal failure.
To create a test: Use the TEST() macro to define and name a test function. These are ordinary C++ functions that don't return a value. In this function, along with any valid C++ statements you want to include, use the various googletest assertions to check values.
To run only some unit tests you could use --gtest_filter=Test_Cases1* command line option with value that accepts the * and ? wildcards for matching with multiple tests. I think it will solve your problem.
Google test, or gtest is an open source framework for unit testing C\C++ projects. It easily integrates with CMake, has a great assertion engine, and produces XML reports to be for display so that it can be integrated with common CI\CD frameworks.
From the Advanced Guide, we can see that there are a couple ways we could do this.
The easiest way is by using assertions in a subroutine:
template<typename T>
void AssertAttributeEquals(MyObject const& obj, T value) {
ASSERT_TRUE(obj.IsValid());
// googletest has the assumption that you put the
// expected value first
EXPECT_EQ(value, obj.GetAttribute());
}
And you can call it like so:
AssertAttributeEquals(myObject, expectedValue);
Although you may want to use SCOPED_TRACE
to get a better message on failure:
{
SCOPED_TRACE("whatever message you want");
AssertAttributeEquals(myObject, expectedValue);
}
Alternatively, you can use a function that returns an AssertionResult
:
template<typename T>
::testing::AssertionResult AttributeEquals(MyObject const& obj, T value) {
if (!obj.IsValid()) {
// If MyObject is streamable, then we probably want to include it
// in the error message.
return ::testing::AssertionFailure() << obj << " is not valid";
}
auto attr = obj.GetAttribute();
if (attr == value) {
return ::testing::AssertionSuccess();
} else {
return ::testing::AssertionFailure() << attr << " not equal to " << value;
}
}
This can be used like so:
EXPECT_TRUE(AttributeEquals(myObject, expectedValue));
This second technique has the benefit of producing nice error messages even if you don't use SCOPED_TRACE
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With