Google Test
Page Contents
Read The Docs!
Installing
To download the source files and install [Ref]:
sudo apt-get install libgtest-dev cd /usr/src/gtest # Might also be /usr/src/googletest/googletest sudo mkdir build cd build sudo cmake -DCMAKE_BUILD_TYPE=RELEASE .. sudo make sudo cp libg* /usr/lib cd .. sudo rm -fr build
Skeleton main()
int main(int argc, char **argv) { ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); }
Basic Test Structure
Simple Tests
When there is nothing to do to prepare for your tests, i.e., no setup or tear down,
just use the TEST()
macro to define the tests:
TEST(TestCaseName, ThisTestName) { ... }
Test Fixtures
If you have some preparation for each test, i.e., you require some test setup and tear down,
then use the TEST_F()
macro. To use this macro you need to create a test-fixture
object that inherits from public testing::Test
:
// Class is created for each test and destroyed after class MyTestFixture : public testing::Test { protected: MyTestFixture() { // Can do setup here too } ~MyTestFixture() { // Can do tear down here too } // Called before each test is run virtual void SetUp() override { ... } // Called after each test. Don't neeed to define if no tear down required. virtual void TearDown() override { ... } int m_dummy; }; ... TEST_F(MyTestFixture, ThisTestName) { // You can refer to all the members and functions in the class MyTestFixture here directly. // For example: std::cout << "Dummy is " << m_dummy << "\n"; }
Parameterised Tests
Replace for loops that repeat a test over a data range with parameterised tests. Loops stop each test case being independent as when one fails the loop stops so that latter cases are not tested.
INSTANTIATE_TEST_CASE_P( // OR INSTANTIATE_TEST_SUITE_P?? MyTests, MyParameterizedTestFixture, ::testing::Values( 1, 2, 3, 4, 5,... ) ); class MyParameterizedTestFixture : public ::testing::TestWithParam<int> { ... }; TEST_P(MyParameterizedTestFixture, SomeTestCase) { int test_value = GetParam(); ... ASSERT_TRUE(some_predicate(..., test_value, ...)); ... }
To pass multiple values just used std::make_tuple
for the data items
and then use std::get<n>(GetParam())
, where n
is the
index into the parameter tuple.
Basic Test Assertions
The test macros are ASSERT_*
or EXPECT_*
. The former is a fatal
error and returns from the current function and the latter prints out a warning, continues
in the current function and the error is logged only after it completes.
All the macros return a stream-like object that you can stream a message to that will be printed out on error. For example:
ASSERT_GT(1,2) << "1 is not greater than 2";
Also note that when test macros fail, they only abort the current function, not the entire test,
so if you call functions from your TEST[_F]
macro-function and the sub function errors, your
main test function will still continue. See Google's advanced guide for more info. Probably the easiest solution is to wrap subroutine calls with ASSERT_NO_FATAL_FAILURE()
.
Here are some common test macros:
Check booleans: | ASSERT_(TRUE|FALSE) |
Check numbers: | ASSERT_(EQ|NE|LT|LE|GT|GE) |
Check C-style strings: | ASSERT_STR(EQ|NE) and ASSERT_STRCASE(EQ|NE) to ignore case. |
Check floats: | ASSERT_NEAR or ASSERT_(FLOAT|DOUBLE)_EQ . |
Check exceptions: | ASSERT_THROW or ASSERT_(ANY|NO)THROW .Eg: ASSERT_THROW(Foo(5), bar_exception); Eg: EXPECT_NO_THROW({ .. body of code... });
|
Matchers: |
These make use of GMock matchers, so you must include "gmock/gmock.h" in your test code.
Examples:
|
Passing Arguments To Your Test Program
When you compile your Google Test application it includes code that parses the command line options to enable things like filtering tests etc. So, how then, do you pass command line options through to your test code?
The answer is that after parsing all the Google Test relevant command line options, they are
removed from argv
and argc
is updated appropriately so that in your
main()
function you can just parse argv
. The remaining arguments
will be all those that Google Test didn't recognise.
To parse command line options there are several options including Boost, getopt()
,
or to roll-your-own parser [Ref]. Some examples, taken from the reference and modified slightly:
static std::string getCmdOption(char **begin, char **end, const std::string &option) { char **itr = std::find(begin, end, option); if (itr != end && ++itr != end) { return std::string(*itr); } return std::string(); } static bool cmdOptionExists(char** begin, char** end, const std::string& option) { return std::find(begin, end, option) != end; }
Often, if all or many tests need to query your own test options it can be a nice idea to base all of your tests off a base class that inherits from ::testing::Test
and contains
functions to get any options. E.g. base your test classes on this:
#include <gtest/gtest.h> ... class TestBase : public ::testing::Test { public: static void Initialise(int exOpt1, const std::string ∓exOpt2) { exampleCommandLineOption1 = exOpt1; exampleCommandLineOption2 = exOpt2; } static int GetExampleCommandLineOption1(void) { return exampleCommandLineOption1; } ... private: static int exampleCommandLineOption1; static std::string exampleCommandLineOption2; };
Just call the Initialise()
function before you call RUN_ALL_TESTS()
and all your test classes will have access to the
command line options you parsed.
Filtering Tests
To list your tests run with --gtest_list_tests
.
Just run your test executable with the --gtest_filter=test-name(s)
option. The filter
accepts file-globbing syntax so you can use, for example, --gtest_filter=my_new_test*
to
run all tests who's name is prefixed with "my_new_test".
Scoped Traces
GTest has a useful macro SCOPED_TRACE(streamable)
. It is useful because it creates a stack of messages that will automatically printed out with any error trace. This can be handy to a) see the path through the test that failed and b) see loop iteration numbers that fail.
One useful little macro follows. SCIPED_TRACE
accepts a streamable object but sometimes you may want to build up a string, so the following can be used.
#define SCOPED_TRACE_STR(x) \ SCOPED_TRACE( \ static_cast<std::stringstream &>( \ (std::stringstream().flush() << x) \ ).str())