userver test helpers live in userver::utest
CMake target:
When being limited to userver::universal
, you can use a subset of the helpers that don't require coroutine environment via userver::universal-utest
CMake target:
To include gtest and userver-specific macros, do:
As usual, gmock is available in <gmock/gmock.h>
.
utest.hpp
header provides alternative gtest-like macros that run tests in a coroutine environment:
To test code that uses coroutine environment (e.g. creates tasks or uses synchronization primitives), use UTEST
instead of TEST
in the test header:
There are U
-versions for all gtest macros that declare tests and test groups: UTEST_F
, UTEST_P
, INSTANTIATE_UTEST_SUITE_P
etc. Test fixture's constructor, destructor, SetUp
and TearDown
are executed in the same coroutine environment as the test body.
By default, a single-threaded TaskProcessor
is used. It is usually enough, because userver engine enables concurrency even on 1 thread. However, some tests require actual parallelism, e.g. torture tests that search for potential data races. In such cases, use _MT
macro versions:
The specified thread count is available in U
-tests as GetThreadCount()
method.
For DEATH-tests (when testing aborts or assertion fails) use UTEST_DEATH
. It configures gtest-DEATH-checks to work in multithreaded environment. Also it disables using of ev_default_loop
and catching of SIGCHLD
signal to work with gtest's waitpid()
calls.
Standard gtest exception assertions provide poor error messages. Their equivalents with proper diagnostics are available in <userver/utest/assert_macros.hpp>
(which gets pulled in by <userver/utest/utest.hpp>
automatically):
Example usage:
utils::datetime::Now()
and utils::datetime::SteadyNow()
from <userver/utils/datetime.hpp>
instead of std::chrono::system_clock::now()
and std::chrono::steady_clock::now()
, respectively.<userver/utils/mock_now.hpp>
See utest::PrintTestName for info on how to simplify writing parametrized tests and official gtest documentation.
You can fill dynamic config with custom config values using dynamic_config::StorageMock
.
If you don't want to specify all configs used by the tested code, you can use default dynamic config.
To use default dynamic config values in tests, add DEFAULT_DYNAMIC_CONFIG_FILENAME
preprocessor definition to your test CMake target, specifying the path of a YAML file with dynamic_config::DocsMap
contents.
Default dynamic config values can be accessed using <dynamic_config/test_helpers.hpp>
:
dynamic_config::GetDefaultSnapshot()
dynamic_config::GetDefaultSource()
dynamic_config::MakeDefaultStorage(overrides)
API for capturing userver logs can be found in userver/utest/default_logger_fixture.hpp
It can be used for testing that a certain piece of code produces logs with the given text (which is brittle, but sometimes needs to be done). It can also be used for testing logging::LogHelper serialization functions.
Log level in the unit tests can be controlled via log-level
parameter. For example, the following command outputs the debug logs for all the *Log*
tests for the CMake built binary:
Userver uses signals for internal matters to identify coroutine stack usage Coroutine stack. If you see too much "caught signal X" in debugger, you may disable stack usage monitor via environment variable:
USERVER_GTEST_ENABLE_STACK_USAGE_MONITOR=1
Now you should not be annoyed by extra "caught signal X" events.
All userver benchmark helpers live in userver::ubench
CMake target:
As usual, google-benchmark is available in <benchmark/benchmark.h>
.
See also official google-benchmark documentation.
Use engine::RunStandalone
to run parts of your benchmark in a coroutine environment:
See the equivalent utest section.
Default dynamic configs are available in in <userver/dynamic_config/test_helpers.hpp>
.