Gtest Global Variables

0 views
Skip to first unread message

Jennifer Curtis

unread,
Aug 4, 2024, 1:24:55 PM8/4/24
to aplecoli
Ifyou already have a function or functor that returns bool (or a type thatcan be implicitly converted to bool), you can use it in a predicateassertion to get the function arguments printed for free. SeeEXPECT_PRED* in the AssertionsReference for details.

If you want informative messages in EXPECT_FALSE and ASSERT_FALSE as well(one third of Boolean assertions in the Google code base are negative ones), andare fine with making the predicate slower in the success case, you can supply asuccess message:


If you find the default message generated byEXPECT_PRED* andEXPECT_TRUE unsatisfactory, or somearguments to your predicate do not support streaming to ostream, you caninstead use predicate-formatter assertions to fully customize how themessage is formatted. SeeEXPECT_PRED_FORMAT* in theAssertions Reference for details.


Some floating-point operations are useful, but not that often used. In order toavoid an explosion of new macros, we provide them as predicate-format functionsthat can be used in the predicate assertion macroEXPECT_PRED_FORMAT2, forexample:


to assert that types T1 and T2 are the same. The function does nothing ifthe assertion is satisfied. If the types are different, the function call willfail to compile, the compiler error message will say that T1 and T2 are not thesame type and most likely (depending on the compiler) show you the actualvalues of T1 and T2. This is mainly useful inside template code.


If you need to use fatal assertions in a function that returns non-void, oneoption is to make the function return the value in an out parameter instead. Forexample, you can rewrite T2 Foo(T1 x) to void Foo(T1 x, T2* result). Youneed to make sure that *result contains some sensible value even when thefunction returns prematurely. As the function now returns void, you can useany assertion inside of it.


Related to the assertions SUCCEED() and FAIL(), you can prevent further testexecution at runtime with the GTEST_SKIP() macro. This is useful when you needto check for preconditions of the system under test during runtime and skiptests in a meaningful way.


As mentioned earlier, the printer is extensible. That means you can teach itto do a better job at printing your particular type than to dump the bytes. Todo that, define an AbslStringify() overload as a friend function templatefor your type:


Sometimes, AbslStringify() might not be an option: your team may wish to printtypes with extra debugging information for testing purposes only. If so, you caninstead define a PrintTo() function like this:


In many applications, there are assertions that can cause application failure ifa condition is not met. These consistency checks, which ensure that the programis in a known good state, are there to fail at the earliest possible time aftersome program state is corrupted. If the assertion checks the wrong condition,then the program may proceed in an erroneous state, which could lead to memorycorruption, security holes, or worse. Hence it is vitally important to test thatsuch assertion statements work as expected.


Since these precondition checks cause the processes to die, we call such testsdeath tests. More generally, any test that checks that a program terminates(except by throwing an exception) in an expected fashion is also a death test.


When built with Bazel and using Abseil, GoogleTest uses theRE2 syntax. Otherwise, for POSIXsystems (Linux, Cygwin, Mac), GoogleTest uses thePOSIX extended regular expressionsyntax. To learn about POSIX syntax, you may want to read thisWikipedia entry.


To help you determine which capability is available on your system, GoogleTestdefines macros to govern which regular expression it is using. The macros are:GTEST_USES_SIMPLE_RE=1 or GTEST_USES_POSIX_RE=1. If you want your deathtests to work in all cases, you can either #if on these macros or use the morelimited syntax only.


You can do this in main() to set the style for all death tests in the binary,or in individual tests. Recall that flags are saved before running each test andrestored afterwards, so you need not do that yourself. For example:


The statement argument of ASSERT_EXIT() can be any valid C++ statement. Ifit leaves the current function via a return statement or by throwing anexception, the death test is considered to have failed. Some GoogleTest macrosmay return from the current function (e.g. ASSERT_TRUE()), so be sure to avoidthem in statement.


Since statement runs in the child process, any in-memory side effect (e.g.modifying a variable, releasing memory, etc) it causes will not be observablein the parent process. In particular, if you release memory in a death test,your program will fail the heap check as the parent process will never see thememory reclaimed. To solve this problem, you can


If a test sub-routine is called from several places, when an assertion inside itfails, it can be hard to tell which invocation of the sub-routine the failure isfrom. You can alleviate this problem using extra logging or custom failuremessages, but that usually clutters up your tests. A better solution is to usethe SCOPED_TRACE macro or the ScopedTrace utility:


where message can be anything streamable to std::ostream. SCOPED_TRACEmacro will cause the current file name, line number, and the given message to beadded in every failure message. ScopedTrace accepts explicit file name andline number in arguments, which is useful for writing test helpers. The effectwill be undone when the control leaves the current lexical scope.


To alleviate this, GoogleTest provides three different solutions. You could useeither exceptions, the (ASSERTEXPECT)_NO_FATAL_FAILURE assertions or theHasFatalFailure() function. They are described in the following twosubsections.


HasFatalFailure() in the ::testing::Test class returns true if anassertion in the current test has suffered a fatal failure. This allowsfunctions to catch fatal failures in a sub-routine and return early.


In your test code, you can call RecordProperty("key", value) to log additionalinformation, where value can be either a string or an int. The last valuerecorded for a key will be emitted to theXML output if you specify one. For example, thetest


GoogleTest creates a new test fixture object for each test in order to maketests independent and easier to debug. However, sometimes tests use resourcesthat are expensive to set up, making the one-copy-per-test model prohibitivelyexpensive.


Note that SetUpTestSuite() may be called multiple times for a test fixtureclass that has derived classes, so you should not expect code in the functionbody to be run only once. Also, derived classes still have access to sharedresources defined as static members, so careful consideration is needed whenmanaging shared resources to avoid memory leaks if shared resources are notproperly cleaned up in TearDownTestSuite().


Calling SetUp() and TearDown() for each iteration depends on the flaggtest_recreate_environments_when_repeating. SetUp() and TearDown() arecalled for each environment object when the object is recreated for eachiteration. However, if test environments are not recreated for each iteration,SetUp() is called only on the first iteration, and TearDown() is called onlyon the last iteration.


You should call AddGlobalTestEnvironment() before RUN_ALL_TESTS() is called,probably in main(). If you use gtest_main, you need to call this beforemain() starts for it to take effect. One way to do this is to define a globalvariable like this:


The parameter generator expression is not evaluated until GoogleTest isinitialized (via InitGoogleTest()). Any prior initialization done in themain function will be accessible from the parameter generator, for example,the results of flag parsing.


You can instantiate a test pattern more than once, so to distinguish differentinstances of the pattern, the instantiation name is added as a prefix to theactual test suite name. Remember to pick unique prefixes for differentinstantiations. The tests from the instantiation above will have these names:


Additionally, by default, every TEST_P without a correspondingINSTANTIATE_TEST_SUITE_P causes a failing test in test suiteGoogleTestVerification. If you have a test suite where that omission is not anerror, for example it is in a library that may be linked in for other reasons orwhere the list of test cases is dynamic and may be empty, then this check can besuppressed by tagging the test suite:


In the above, we define and instantiate FooTest in the same source file.Sometimes you may want to define value-parameterized tests in a library and letother people instantiate them later. This pattern is known as abstract tests.As an example of its application, when you are designing an interface you canwrite a standard suite of abstract tests (perhaps using a factory function asthe test parameter) that all implementations of the interface are expected topass. When someone implements the interface, they can instantiate your suite toget all the interface-conformance tests for free.


Once they are defined, you can instantiate them by including foo_param_test.h,invoking INSTANTIATE_TEST_SUITE_P(), and depending on the library target thatcontains foo_param_test.cc. You can instantiate the same abstract test suitemultiple times, possibly in different source files.


The optional last argument to INSTANTIATE_TEST_SUITE_P() allows the user tospecify a function or functor that generates custom test name suffixes based onthe test parameters. The function should accept one argument of typetesting::TestParamInfo, and return std::string.


Providing a custom functor allows for more control over test parameter namegeneration, especially for types where the automatic conversion does notgenerate helpful parameter names (e.g. strings as demonstrated above). Thefollowing example illustrates this for multiple parameters, an enumeration typeand a string, and also demonstrates how to combine generators. It uses a lambdafor conciseness:


Now the tricky part: you need to register all test patterns using theREGISTER_TYPED_TEST_SUITE_P macro before you can instantiate them. The firstargument of the macro is the test suite name; the rest are the names of thetests in this test suite:

3a8082e126
Reply all
Reply to author
Forward
0 new messages