This document consolidates AAMP's testing approach, including L1 unit tests, test infrastructure, and DRM testing requirements.
In AAMP, test levels classify automated tests by scope and dependencies: L1 refers to fast, fully isolated unit tests suitable for frequent and CI runs, while L1.5 refers to unit tests that additionally depend on DRM-related headers or libraries and may require extra environment setup.
Purpose: Fast, lightweight tests for individual components
Characteristics:
- Run in isolation without external dependencies
- Execute in seconds
- Use Google Test (gtest) and Google Mock (gmock)
- Located in
test/utests/
Running L1 Tests:
cd build
cmake -DENABLE_UNIT_TESTS=ON ..
make
ctest --verboseKey Directories:
test/utests/- Core unit teststest/utests/tests/tsb/- TSB (Time Shift Buffer) specific teststest/utests/drm/- DRM-related tests
Purpose: Tests requiring DRM header dependencies
Location: test/utests/drm/
Special Setup: May require additional header installation. See test/utests/drm/README.md.
AAMP uses Google Test (gtest) for unit testing and Google Mock (gmock) for mocking dependencies:
#include <gtest/gtest.h>
#include <gmock/gmock.h>
class MyComponentTest : public ::testing::Test {
protected:
void SetUp() override {
// Setup before each test
}
};
TEST_F(MyComponentTest, ShouldDoSomething) {
// Arrange
// Act
// Assert
EXPECT_EQ(expected, actual);
}AAMP provides fake implementations for testing components in isolation:
Location: test/fakes/
Usage Pattern:
#include "test/fakes/FakeDownloader.h"
FakeDownloader fakeDownloader;
ComponentUnderTest component(&fakeDownloader);
// Test component behaviorAll public functions must have unit tests. Aim for:
- Minimum 80% code coverage for new code
- 100% coverage for critical paths
// Arrange: Set up test data and expectations
// Act: Call the function under test
// Assert: Verify the result
EXPECT_EQ(expected, actual);Use Google Mock for:
- External dependencies (network, filesystem, DRM)
- Abstract interfaces
- Hard-to-create objects
class MockDownloader : public IDownloader {
public:
MOCK_METHOD(DownloadResult, download, (const std::string&), (override));
};
// In test:
MockDownloader mock;
EXPECT_CALL(mock, download).WillOnce(Return(expected_result));Tests are automatically discovered and registered:
enable_testing()
add_executable(my_test my_test.cpp)
target_link_libraries(my_test ${GTEST_LIBRARIES} gmock)
add_test(NAME my_test COMMAND my_test)All tests must pass in the CI pipeline:
# Local verification before PR
make test
ctest --verboseDRM tests may require special headers or dependencies:
See: test/utests/drm/README.md
Key Points:
- Identify header dependencies
- Document acquisition method
- Provide setup automation where possible
Time Shift Buffer specific tests:
Location: test/utests/tests/tsb/
Includes:
- In-memory tests
- Filesystem-based tests (RealFilesystemTests)
- See individual README files for details
cd build
ctest --verbosectest -R "TestName" --verbosecmake -DENABLE_COVERAGE=ON ..
make
make test
make coverage_report- Follows Google Test structure
- Uses mocks for dependencies (from
test/fakes/) - Has descriptive test name
- Tests both success and failure paths
- Includes edge cases
- No hardcoded timeouts without justification
- Cleans up resources
- One Assertion per Test (ideally) or logical grouping
- Descriptive Names: Use pattern
Test<Component><Behavior><Expectation> - Test Data: Use realistic but minimal test data
- Isolation: Tests must pass in any order
- No Network Calls: Use mocks instead
- Deterministic: No flaky tests due to timing
Critical: Before writing tests, review:
- .github/instructions/testing.instructions.md - L1 test structure and framework details
- .github/instructions/cpp.instructions.md - C++ coding standards
- CONTRIBUTING.md - Code review and PR standards
ctest --verbose
# or run directly:
./test_executable --gtest_filter="TestName"gdb ./test_executable
(gdb) run./test_executable --gtest_list_testsFor performance-critical components:
- Add microbenchmark tests
- Set realistic performance expectations
- Profile before and after changes
- Document any performance trade-offs