GoogleTest
repository·main·Indexed 12 days ago
https://github.com/google/googletestA C++ testing framework based on the xUnit architecture that provides a rich set of assertions, test discovery, and support for death tests and parameterized tests. It includes GoogleMock, a framework for creating and using mock classes with a declarative syntax for defining behavior and validating arguments. Version 1.18.x requires at least C++17.
What's inside GoogleTest
- GoogleTest is a C++ testing and mocking framework. If you are new to the project, start with the GoogleTest Primer to learn how to write simple tests. Once you are comfortable with the basics, you can progress to advanced features, sample implementations, and mocking capabilities.
Overview of the gMock Framework
maingMock is Google's C++ framework for creating and using mock classes. It is designed to help developers derive better system designs and write more effective tests by providing a declarative syntax for defining mocks and controlling their behavior.
Key capabilities include:
- Declarative Mock Definition: Define mock objects using a specialized syntax.
- Partial (Hybrid) Mocks: Create objects that combine real implementation with mocked behavior.
- Complex Function Support: Handles overloaded functions and functions of arbitrary types.
- Rich Matcher Set: Validate function arguments using a wide variety of built-in matchers.
- Behavior Control: Use intuitive syntax to specify how mocks should respond to calls.
- Automatic Verification: Expectations are verified automatically (no manual record-and-replay required).
- Ordering Constraints: Express arbitrary (partial) ordering constraints on function calls.
- Extensibility: Users can define custom matchers and actions.
- No Exceptions: The framework does not rely on C++ exceptions.
What is a mock object and how does it differ from a fake?
mainIn testing, a mock object is an object that implements the same interface as a real object but is pre-programmed with expectations. These expectations specify the calls the mock is expected to receive (e.g., which methods are called, in what order, how many times, and with what arguments).
It is important to distinguish mocks from fake objects:
- Fakes: Have working implementations but use shortcuts (like an in-memory file system) to make them faster or simpler, making them unsuitable for production.
- Mocks: Focus on verifying the interaction between the code under test and the dependency by specifying expected behaviors and call patterns.
Handle uninteresting mock calls
mainAn uninteresting call occurs when a mock method is called, but no
EXPECT_CALLhas been defined for it. By default, gMock performs a default action and prints a warning, but does not fail the test.To manage these:
- Suppress warnings: Use
NiceMock<MockClass>to wrap your mock object. This suppresses all uninteresting call warnings. - Allow specific calls: If you want to allow certain calls without strict verification, use
EXPECT_CALL(...).Times(AnyNumber()). - Avoid over-specification: Do not add
EXPECT_CALLjust to silence a warning; this makes tests harder to maintain.
using ::testing::NiceMock; TEST(MyTest, Example) { NiceMock<MockDomainRegistry> mock_registry; // No warnings will be printed for calls to mock_registry that aren't explicitly expected ... }- Suppress warnings: Use
Choose between Typed Tests and Value-Parameterized Tests
mainWhen testing multiple implementations of the same interface, choose based on how instances are created and how you want failure information reported:
Feature Typed Tests Value-Parameterized Tests Creation Easier if implementations use the same constructor/factory (e.g., new TypeParam).Easier if implementations require different constructor arguments (e.g., new Foovsnew Bar(5)).Failure Output Shows the name of the failing type automatically. Shows the iteration number by default (requires custom name function for better output). Safety Requires explicit casting to the interface type to ensure correct testing. Less prone to mistakes regarding interface vs. concrete type testing. Tip: If using value-parameterized tests, pass a function that returns an iteration name as the third parameter to
INSTANTIATE_TEST_SUITE_Pto improve debuggability.Verify Mock Expectations on Destruction
maingMock automatically verifies that all expectations set via
EXPECT_CALL()have been satisfied when the mock object is destroyed.Warning for Heap Allocation: If you allocate mock objects on the heap and they are never deleted, the final verification will not occur. To ensure leaks are caught and mocks are properly verified, it is recommended to use the
gtest_mainlibrary, which enables the heap checker automatically.How type-parameterized tests work
mainType-parameterized tests allow you to define test logic once and instantiate it with different sets of types later. This is useful for verifying that different implementations of an interface or concept all satisfy the same requirements without duplicating test code.
To implement them:
- Define a fixture class template.
- Declare the suite using
TYPED_TEST_SUITE_P(FixtureName). - Define tests using
TYPED_TEST_P(FixtureName, TestName). Inside these tests, useTypeParamto refer to the current type. - Register the test patterns using
REGISTER_TYPED_TEST_SUITE_P(FixtureName, Test1, Test2, ...). - Instantiate the suite with specific types using
INSTANTIATE_TYPED_TEST_SUITE_P(Prefix, FixtureName, TypeList).
// 1. Define fixture template template <typename T> class FooTest : public testing::Test { void DoSomethingInteresting(); }; // 2. Declare suite TYPED_TEST_SUITE_P(FooTest); // 3. Define tests TYPED_TEST_P(FooTest, DoesBlah) { TypeParam n = 0; this->DoSomethingInteresting(); } // 4. Register patterns REGISTER_TYPED_TEST_SUITE_P(FooTest, DoesBlah); // 5. Instantiate using MyTypes = ::testing::Types<char, int, unsigned int>; INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes);Use NiceMock and StrictMock to control uninteresting calls
mainAn "uninteresting call" is a call to a mock method that has no corresponding
EXPECT_CALL. By default, gMock prints a warning for these. You can change this behavior on a per-mock-object basis:NiceMock<T>: Suppresses warnings for uninteresting calls. Use this most of the time to keep tests clean.StrictMock<T>: Treats uninteresting calls as failures. Use this only as a last resort, as it makes tests brittle.- Default (Naggy): Prints a warning for uninteresting calls. Useful during active development/debugging.
Note: These modifiers only work if the
MOCK_METHODis defined directly in the mock class (not in a base class) and if the mock class has a virtual destructor.using ::testing::NiceMock; using ::testing::StrictMock; TEST(MyTest, Example) { NiceMock<MockFoo> nice_foo; StrictMock<MockFoo> strict_foo; // nice_foo will not warn if methods other than those expected are called. // strict_foo will fail if any method other than those expected is called. }Avoid underscores in TEST and TEST_F names
mainTo prevent invalid C++ identifiers and name collisions, do not use underscores (
_) inTestSuiteNameorTestNamewithinTEST()orTEST_F()macros.Why this matters:
Reserved Identifiers: GoogleTest uses
DISABLED_as a prefix. Additionally, C++ reserves identifiers starting with an underscore followed by an uppercase letter (e.g.,_Foo) or containing double underscores (__).Name Collisions: Using underscores in the middle of names can cause different tests to generate the same internal class name. For example:
TEST(Time, Flies_Like_An_Arrow)TEST(Time_Flies, Like_An_Arrow)
Both would generate the class
Time_Flies_Like_An_Arrow_Test, leading to compilation errors.
Use Matchers to specify expected arguments
mainMatchers are predicates used within
EXPECT_CALL()to validate the arguments passed to a mock method.- Wildcard (
_): Use_to indicate that any value for that argument is acceptable. This helps prevent brittle tests by avoiding over-specification. - Equality: Providing a literal value (e.g.,
100) is implicitly treated asEq(100), meaning the argument must equal that value. - Comparison Matchers: Use built-in matchers like
Ge(value)(Greater than or equal to) to express ranges or bounds.
If a method is overloaded, you must specify the arguments (or matchers) to help gMock resolve which overload you are targeting.
using ::testing::_; using ::testing::Ge; ... // Matches any value for the second argument EXPECT_CALL(turtle, GoTo(50, _)); // Matches any value greater than or equal to 100 EXPECT_CALL(turtle, Forward(Ge(100)));- Wildcard (
Handle fatal failures in sub-routines
mainA common pitfall is assuming
ASSERT_*orFAIL*aborts the entire test. In reality, they only abort the current function. If anASSERT_*fails inside a subroutine, the caller will continue execution, which can lead to crashes (e.g., dereferencing a null pointer).To handle this, you have three main options:
- Use
ASSERT_NO_FATAL_FAILURE(statement): This macro checks if thestatementgenerated any fatal failures in the current thread. If it did, the assertion fails and aborts the current test. - Use
HasFatalFailure(): Manually check if a fatal failure has occurred and return early from the caller. - Use Exceptions: Implement a custom
testing::EmptyTestEventListenerthat throws atesting::AssertionExceptionwhen a fatal failure occurs.
// Option 1: Using ASSERT_NO_FATAL_FAILURE ASSERT_NO_FATAL_FAILURE(Foo()); // Option 2: Using HasFatalFailure() to return early TEST(FooTest, Bar) { Subroutine(); if (HasFatalFailure()) return; // The following won't be executed if Subroutine() had a fatal failure. }- Use
Perform Death Tests to verify process termination
mainDeath tests verify that a piece of code causes the process to terminate. GoogleTest executes the code in a child process to prevent the main test runner from dying.
Key Assertions
EXPECT_DEATH(statement, matcher): Verifiesstatementcauses the process to terminate with a nonzero exit status and producesstderroutput matchingmatcher. A bare stringmatcheris treated as a regex (ContainsRegex).EXPECT_DEATH_IF_SUPPORTED(statement, matcher): Behaves likeEXPECT_DEATHif supported by the platform; otherwise, does nothing.EXPECT_DEBUG_DEATH(statement, matcher): Behaves likeEXPECT_DEATHin debug mode; inNDEBUGmode, it simply executes the statement.EXPECT_EXIT(statement, predicate, matcher): Verifiesstatementterminates with an exit status satisfyingpredicateandstderrmatchingmatcher.
Exit Status Predicates
::testing::ExitedWithCode(exit_code): Returns true if the program exited normally with the given code.::testing::KilledBySignal(signal_number): Returns true if the program was killed by a specific signal (not available on Windows).
Death Test Styles
Controlled by the
--gtest_death_test_styleflag (default is"fast"):"fast": (POSIX) Usesfork()/clone()and executes the statement immediately in the child."threadsafe": (POSIX/Windows) Re-executes the test binary in the child to ensure a clean environment.
// Verify process dies with specific error message EXPECT_DEATH(DoSomething(42), "My error"); // Verify process exits with code 0 and specific message EXPECT_EXIT(NormalExit(), testing::ExitedWithCode(0), "Success"); // Compound statements in death tests EXPECT_DEATH({ int n = 5; DoSomething(&n); }, "Error on line .* of DoSomething()");