-
-
Notifications
You must be signed in to change notification settings - Fork 11
testing.md
The QB Actor Framework includes a comprehensive suite of unit and system tests designed to ensure correctness, stability, and robustness. These tests are built using the Google Test framework and managed via CTest.
Our testing strategy is divided into two main categories:
-
Unit Tests (typically found in
qb/source/<module>/tests/unit/
):- Focus on testing individual classes, functions, or small, isolated modules in detail.
- Aim for minimal dependencies to verify component logic in isolation.
- Examples: Testing
qb::Timestamp
functionality,qb::io::uri
parsing, or specific cryptographic functions.
-
System/Integration Tests (typically found in
qb/source/<module>/tests/system/
):- Focus on testing the interaction and integration of multiple framework components.
- Often involve creating
qb::Main
engine instances, launching multiple actors (potentially across differentVirtualCore
s), and verifying their collective behavior, message passing, lifecycle management, and concurrency aspects. - Examples: Testing actor event delivery, inter-core communication, service actor resolution, or full client-server interactions using
qb-io
components within actors.
Tests are compiled as part of the standard QB Framework build process if the QB_BUILD_TEST
CMake option is enabled (it is often ON
by default).
-
Ensure
QB_BUILD_TEST=ON
: When configuring CMake:# In your build directory cmake .. -DQB_BUILD_TEST=ON # Add other options as needed (e.g., -DCMAKE_BUILD_TYPE=Debug)
-
Build the Project:
# In your build directory cmake --build . --config Debug # Or Release # Alternatively: make -jN (Linux/macOS) or build the solution in Visual Studio (Windows)
Test executables are typically generated in your build directory, often under a path like build/bin/qb/source/<module>/tests/<type>/
(e.g., build/bin/qb/source/core/tests/system/qb-core-gtest-system-test-actor-event
).
Once built, you have two primary ways to run the tests:
-
Using CTest (Recommended for CI and Full Test Suite Execution): CTest is CMake's testing tool and is the preferred way to run all or a subset of tests.
# Navigate to your build directory first cd build # Run all discovered tests ctest # Run tests with verbose output (shows individual test case results) ctest -V # Run only tests whose names match a regular expression (e.g., all actor event tests) ctest -R test-actor-event # Run tests in parallel (if supported by your CTest version and test properties) # ctest -jN
-
Running Individual Test Executables Directly: You can also navigate to the directory containing a specific test executable and run it directly. This allows you to use Google Test-specific command-line flags.
# Example for a specific core system test cd build/bin/qb/source/core/tests/system/ ./qb-core-gtest-system-test-actor-add --gtest_color=yes # Example: Run only specific tests within that executable using a filter ./qb-core-gtest-system-test-actor-add --gtest_filter=ActorAddTestSuite.SpecificAddTest
Refer to the Google Test documentation for a full list of its command-line options.
-
Location: Test source files (
test-*.cpp
) reside within theqb/source/<module>/tests/unit/
orqb/source/<module>/tests/system/
directories. -
Naming: Test files are generally named
test-<feature_or_component>.cpp
(e.g.,test-actor-event.cpp
,test-uri.cpp
). -
Framework: Google Test (
gtest/gtest.h
) is used. Tests are defined usingTEST(TestSuiteName, TestName)
or, if using a test fixture,TEST_F(TestFixtureClassName, TestName)
. -
System Test Approach: Many system tests involve:
- Instantiating
qb::Main
. - Adding specific test actor configurations to one or more cores.
- Running the engine synchronously for test determinism:
engine.start(false); engine.join();
. - Using
std::atomic
variables, shared counters (protected by mutexes if accessed outside actor context during assertions), or specific response events to gather results or state from actors for assertion. - Asserting expected outcomes using Google Test macros (
EXPECT_EQ
,ASSERT_TRUE
, etc.), often also checkingengine.hasError()
.
- Instantiating
Contributions of new tests are highly encouraged!
- Determine Scope: Decide if it's a unit test (isolating a class/function) or a system/integration test (multiple components, actors).
-
Choose Location: Place your new
test-myfeature.cpp
file in the appropriateunit
orsystem
subdirectory under the relevant module (e.g.,qb/source/core/tests/system/
). -
Include Headers: Always include
<gtest/gtest.h>
. Include necessary QB framework headers and any standard C++ headers your test requires. -
Test Fixtures (Optional): For tests requiring common setup/teardown logic, create a test fixture class inheriting from
public ::testing::Test
. UseSetUp()
andTearDown()
virtual methods. -
Define Test Cases: Use
TEST(MyFeatureTestSuite, DescriptiveTestName)
orTEST_F(MyFixtureClass, DescriptiveTestName)
. -
System Test Specifics:
- Instantiate
qb::Main engine;
. - Add your test actors using
engine.addActor<MyTestActor>(core_id, ...)
orengine.core(core_id).builder()...
. - If your test requires actors to perform a sequence of actions or wait for certain conditions, use
qb::io::async::callback
within your test actors to schedule subsequent steps or self-terminating events. - For verifying state across actors or after the engine run,
std::atomic
variables (declared globally or as static members of a test fixture) are often useful for safe communication of results from actors back to the main test thread for assertions. Use mutexes only if absolutely necessary for more complex shared state between the test and actors. - Run the engine synchronously for deterministic system tests:
engine.start(false); engine.join();
.
- Instantiate
-
Assert Outcomes: Use Google Test assertions (
EXPECT_TRUE
,ASSERT_EQ
,EXPECT_FALSE
,ASSERT_NE
,EXPECT_THROW
, etc.) to verify the behavior and state of your components or the overall system. -
Update CMake: Add your new
.cpp
file to the list of sources in the relevantCMakeLists.txt
file (e.g., inqb/source/core/tests/system/CMakeLists.txt
). The target names are usually derived from the filename. Follow the existing patterns in those files.
By following these guidelines, you can contribute effective tests that help maintain the quality and reliability of the QB Actor Framework.
(Next: Consult the QB Actor Framework: Frequently Asked Questions (FAQ) or the QB Actor Framework: Glossary of Terms for more framework information.**)