4.5 KiB
Testing Logos Modules
Unit Tests with logos-test-framework
Universal modules have a plain C++ impl class. Test it using the logos-test-framework, which is provided automatically by logos-module-builder.
Test File Structure
tests/
├── main.cpp # LOGOS_TEST_MAIN() entry point
├── test_my_module.cpp # Test cases using LOGOS_TEST()
└── CMakeLists.txt # logos_test() macro
Writing Tests
// tests/main.cpp
#include <logos_test.h>
LOGOS_TEST_MAIN()
// tests/test_my_module.cpp
#include <logos_test.h>
#include "../src/my_module_impl.h"
LOGOS_TEST(hash_returns_nonempty_string) {
MyModuleImpl impl;
LOGOS_ASSERT_FALSE(impl.hash("hello").empty());
}
LOGOS_TEST(verify_matches_hash) {
MyModuleImpl impl;
auto hash = impl.hash("hello");
LOGOS_ASSERT_TRUE(impl.verify("hello", hash));
}
CMakeLists.txt for Tests
# tests/CMakeLists.txt
cmake_minimum_required(VERSION 3.14)
project(MyModuleTests LANGUAGES CXX)
include(LogosTest)
logos_test(
NAME my_module_tests
MODULE_SOURCES ../src/my_module_impl.cpp
TEST_SOURCES
main.cpp
test_my_module.cpp
)
The logos_test() CMake macro handles all framework wiring: Qt dependencies, SDK mock headers, include paths, and CTest registration.
Mocking Other Modules
Use LogosTestContext when your module calls other modules:
LOGOS_TEST(calls_waku_publish) {
auto t = LogosTestContext("chat_module");
t.mockModule("waku_module", "relayPublish").returns(true);
ChatImpl impl;
t.init(&impl);
impl.sendMessage("hello");
LOGOS_ASSERT(t.moduleCalled("waku_module", "relayPublish"));
}
Mocking C Libraries
For modules wrapping external C/C++ libraries, write mock stubs:
// tests/mocks/mock_libcalc.cpp
#include <logos_clib_mock.h>
extern "C" { #include "libcalc.h" }
extern "C" int calc_add(int a, int b) {
LOGOS_CMOCK_RECORD("calc_add");
return LOGOS_CMOCK_RETURN(int, "calc_add");
}
Reference them in CMake:
logos_test(
NAME calc_module_tests
MODULE_SOURCES ../src/calc_module_impl.cpp
TEST_SOURCES main.cpp test_calc.cpp
MOCK_C_SOURCES mocks/mock_libcalc.cpp
)
Running Unit Tests
nix build .#unit-tests -L # Build and run unit tests
nix flake check -L # All Nix checks including tests
logos-module-builder auto-detects tests/CMakeLists.txt and adds checks.<system>.unit-tests and packages.<system>.unit-tests automatically.
Integration Tests with logoscore
Test the module as a loaded plugin via the headless runtime:
logoscore -m ./result/lib -l my_module \
-c "my_module.doSomething(test_input)"
logoscore -m ./result/lib -l my_module \
-c "my_module.init(config)" \
-c "my_module.process(data)"
logoscore -m ./result/lib -l my_module,other_module \
-c "my_module.callOther(hello)"
logoscore arguments:
-m <path>-- Directory to scan for module plugins (repeatable)-l <mod1,mod2>-- Comma-separated modules to load-c "<module>.<method>(args)"-- Call a method (repeatable, sequential)--quit-on-finish-- Exit after calls complete (for CI)
Type auto-detection in -c args: true/false -> bool, 42 -> int, 3.14 -> double, else -> string. Use @filename to load file content as an argument.
TEST_GROUPS
The test runner supports groups for selective testing:
TEST_GROUPS=basic ws test logos-test-modules --auto-local
TEST_GROUPS=ipc ws test logos-test-modules --auto-local
TEST_GROUPS=basic,ipc,errors ws test logos-test-modules --auto-local
Running Tests via Nix
nix build .#unit-tests -L # Run unit tests
nix flake check -L # Run all checks defined in the flake
ws test my-module # In the workspace
ws test my-module --auto-local # With local dep overrides
ws test --all --type cpp # All C++ repos
Key Testing Rules
- Unit tests use
LOGOS_TEST()andLOGOS_ASSERT_*macros from<logos_test.h> - Unit tests should NOT require logoscore -- instantiate the impl class directly
tests/CMakeLists.txtmust useinclude(LogosTest)+logos_test()- Use
LogosTestContextfor mocking module calls and C library functions - Integration tests verify the full plugin lifecycle (load, call, response)
- Always test with
--quit-on-finishin CI to ensure the process exits - 30-second timeout per
-ccall; exit code 1 on failure - After adding
checksto a repo'sflake.nix, runws sync-graphso the workspace discovers them