Testing
Engine-owned documentation. This page maps the current engine test executable, generated test targets, coverage targets, and every
Source/Tests/Test_*.cppsuite currently present in the checkout.
Purpose
Use this page when choosing validation for an engine change or when adding/removing tests. The source-tree README at ../Source/Tests/README.md is a short entry point; this page is the maintained full test map.
Source paths inspected
Source/Applications/TestingApp.cppSource/Tests/README.md- all current
Source/Tests/Test_*.cppfiles BuildTools/cmake/stages/EngineSources.cmakeBuildTools/cmake/stages/Applications.cmakeBuildTools/cmake/stages/Init.cmakeBuildTools/codecoverage.pyBuildTools/validate.shBuildTools/validate.cmd- parent VS Code task references where available
Test runner model
Source/Applications/TestingApp.cpp is the test application entry point. It requires FO_TESTING_APP, initializes the application layer with InitApp(-1, nullptr), marks IsTestingInProgress, and delegates execution to Catch::Session().run(argc, argv).
BuildTools/cmake/stages/EngineSources.cmake owns FO_TESTS_SOURCE, the explicit list of test source files compiled into test builds. BuildTools/cmake/stages/Applications.cmake builds test executables through SetupTestBuild(name):
UnitTestswhenFO_UNIT_TESTSis enabled;CodeCoveragewhenFO_CODE_COVERAGEis enabled.
For an embedding project with dev name LF, the standard generated names are LF_UnitTests, RunUnitTests, LF_CodeCoverage, RunCodeCoverage, GenerateCodeCoverageReport, and AnalyzeCodeCoverage. Treat the prefix as project-generated, not universal.
Running tests
Preferred local baseline from a configured build:
cmake --build . --config RelWithDebInfo --target RunUnitTests
The executable target can also be invoked directly when you need Catch2 arguments. In Last Frontier-style layouts, test binaries are emitted under Binaries/Tests-*, for example Binaries/Tests-Windows-win64/LF_UnitTests.exe or Binaries/Tests-Linux-x64/LF_UnitTests.
For broad validation scenarios, the BuildTools validators can run selected scenarios:
Engine/BuildTools/validate.sh unit-tests
Engine/BuildTools/validate.sh android-arm64-client linux-client linux-server
Use the smallest focused tests first, then the broader run target when the change crosses subsystem boundaries.
Unit tests under sanitizers
The unit tests also run under Clang sanitizers via dedicated validators, which select
the matching San_* build type and run RunUnitTests instrumented:
Engine/BuildTools/validate.sh unit-tests-san-address # AddressSanitizer (+LeakSanitizer)
Engine/BuildTools/validate.sh unit-tests-san-memory # MemorySanitizer (requires Workspace/msan-libcxx)
Engine/BuildTools/validate.sh unit-tests-san-undefined # UndefinedBehaviorSanitizer
Engine/BuildTools/validate.sh unit-tests-san-thread # ThreadSanitizer
The validate.yml workflow runs these as a unit-tests-sanitizers matrix job.
ASan/MSan/UBSan/TSan are blocking legs. The unit-tests-san-memory validator prepares
Workspace/msan-libcxx by building LLVM’s libc++, libc++abi, and libunwind
with MSan instrumentation, then configures San_Memory with FO_MSAN_LIBCXX_ROOT.
The runtime build applies a narrow libunwind ignorelist so C++ exception and
sanitizer-report unwinding do not self-report on ABI register snapshots. Engine
native stack capture and the backward-cpp signal handler are disabled under
FO_MEMORY_SANITIZER so MSan owns fatal reports. unit-tests-san-memory-with-origins
is available locally as the slower diagnostic variant when a future MSan finding
needs origin tracking. San_DataFlow remains
intentionally unwired: DataFlowSanitizer is a taint-tracking framework, not a
defect detector.
Vendored third-party libraries are excluded from UBSan’s -fsanitize=function and
-fsanitize=alignment checks (the rest of -fsanitize=undefined still applies to them).
DisableLibWarnings adds -fno-sanitize=function,alignment on the
San_Undefined/San_Address_Undefined configs because several vendored libraries trip
those two checks by design:
function: AngelScript’s script-call dispatch invokes registered C functions throughbool(*)(void*,void*)and similar signatures, and C callback APIs do the same.alignment: AngelScript builds its bytecode in anasDWORD[](4-byte) buffer and packs pointer-sizedasPWORDoperands at 4-byte-aligned slots (*(asPWORD*)(bc+1) = ...inGenerateFactoryStubForTemplateObjectInstance), which UBSan reports as a misaligned store even though it is correct on every architecture the engine targets.
Both are third-party idioms, not undefined behaviour in engine code, so they must not fail
the UBSan leg (which CI runs with halt_on_error=1). First-party engine code keeps both
checks fully active.
LeakSanitizer runs as part of the address-sanitizer leg (CI sets ASAN_OPTIONS=detect_leaks=1).
It runs with no suppression list — every leak it can report is fixed at the source rather than
masked. Notable cases:
- backward-cpp’s libbfd stack-trace resolver (
Source/Essentials/StackTrace.cpp) caches each binary’s ELF symbol table and DWARF debug info inside libbfd, hung off the openbfdhandle, and never fully frees it onbfd_close. The resolver is therefore a single process-lifetime instance (GetNativeTraceResolver, serialized byStackTraceState::NativeResolverLocker): it is created once, never destroyed, and stays reachable from a static root, so each binary is symbolized once and those libbfd caches remain reachable — LSan does not report them. - The AngelScript backend deletes the preprocessor line-number translator during engine userdata
cleanup, and SPARK’s
IOManagerfrees its registered converters at shutdown. - Owning containers free their contents transitively: e.g.
EntityTypeDesc::PropRegistratoris aunique_ptrso everyPropertyRegistrator(and thePropertyobjects it holds) is freed whenEngineMetadata’s type maps are destroyed.
Code coverage
When FO_CODE_COVERAGE is enabled, BuildTools/cmake/stages/Init.cmake selects the backend from the compiler:
- MSVC / clang-cl: MSVC-style coverage output;
- Clang: LLVM profile/coverage mapping;
- GCC: GCC/lcov-style coverage flags.
BuildTools/cmake/stages/Applications.cmake wires coverage command targets through BuildTools/codecoverage.py:
CleanCodeCoverageDataRunCodeCoverageGenerateCodeCoverageReportAnalyzeCodeCoverage
Coverage output is rooted under CodeCoverage/<Toolchain>/<Platform-Config>/.
BuildTools/codecoverage.py reports first-party production engine sources under
Engine/Source/; it excludes Source/Tests/, ThirdParty/,
GeneratedSource/, and Applications/ from the denominator. See
../Source/Tests/README.md for current local task
notes.
Current test inventory
Current count: 81 Test_*.cpp suites.
Essentials and low-level utilities
Source/Tests/Test_BaseLogging.cppSource/Tests/Test_BasicCore.cppSource/Tests/Test_CommonHelpers.cppSource/Tests/Test_Compressor.cppSource/Tests/Test_Containers.cppSource/Tests/Test_DataSerialization.cppSource/Tests/Test_DiskFileSystem.cppSource/Tests/Test_ExceptionHandling.cppSource/Tests/Test_ExtendedTypes.cppSource/Tests/Test_GenericUtils.cppSource/Tests/Test_GlobalData.cppSource/Tests/Test_HashedString.cppSource/Tests/Test_Logging.cppSource/Tests/Test_MemorySystem.cppSource/Tests/Test_NetSockets.cppSource/Tests/Test_Platform.cppSource/Tests/Test_SafeArithmetics.cppSource/Tests/Test_SmartPointers.cppSource/Tests/Test_StackTrace.cppSource/Tests/Test_StringUtils.cppSource/Tests/Test_StrongType.cppSource/Tests/Test_TimeRelated.cppSource/Tests/Test_WorkThread.cppSource/Tests/Test_WorkerPool.cpp
Configuration, data sources, files, and caches
Source/Tests/Test_CacheStorage.cppSource/Tests/Test_ConfigFile.cppSource/Tests/Test_DataSource.cppSource/Tests/Test_FileSystem.cppSource/Tests/Test_Settings.cpp
Common runtime model
Source/Tests/Test_AnyData.cppSource/Tests/Test_Common.cppSource/Tests/Test_EngineMetadata.cppSource/Tests/Test_EntityLifecycle.cppSource/Tests/Test_EntityProtos.cppSource/Tests/Test_Geometry.cppSource/Tests/Test_LineTracer.cppSource/Tests/Test_MapLoader.cppSource/Tests/Test_Movement.cppSource/Tests/Test_PathFinding.cppSource/Tests/Test_Properties.cppSource/Tests/Test_ProtoManager.cppSource/Tests/Test_TextPack.cppSource/Tests/Test_Timer.cppSource/Tests/Test_TwoDimensionalGrid.cpp
Networking and server/client integration
Source/Tests/Test_ClientDataValidation.cppSource/Tests/Test_ClientEngine.cppSource/Tests/Test_ClientRuntimeApi.cppSource/Tests/Test_ClientServerIntegration.cppSource/Tests/Test_DataBase.cppSource/Tests/Test_EntitySync.cppSource/Tests/Test_FogOfWar.cppSource/Tests/Test_LocationAndEntityMgmt.cppSource/Tests/Test_NetBuffer.cppSource/Tests/Test_NetworkClient.cppSource/Tests/Test_NetworkServer.cppSource/Tests/Test_NetworkUdp.cppSource/Tests/Test_ServerAdvancedOps.cppSource/Tests/Test_ServerEngine.cppSource/Tests/Test_ServerEventContracts.cppSource/Tests/Test_ServerItems.cppSource/Tests/Test_ServerMapOperations.cpp
Scripting and script-visible APIs
Source/Tests/Test_AngelScriptAttributes.cppSource/Tests/Test_AngelScriptBytecode.cppSource/Tests/Test_CommonScriptMethods.cppSource/Tests/Test_ScriptBuiltins.cppSource/Tests/Test_ScriptEntityOps.cppSource/Tests/Test_ServerScriptMethods.cpp
Bakers and tools
Source/Tests/Test_AngelScriptBaker.cppSource/Tests/Test_BakerSetup.cppSource/Tests/Test_ConfigBaker.cppSource/Tests/Test_EffectBaker.cppSource/Tests/Test_ImageBaker.cppSource/Tests/Test_MapBaker.cppSource/Tests/Test_MetadataBaker.cppSource/Tests/Test_ModelBaker.cppSource/Tests/Test_ProtoBaker.cppSource/Tests/Test_ProtoTextBaker.cppSource/Tests/Test_RawCopyBaker.cppSource/Tests/Test_TextBaker.cppSource/Tests/Test_TextureAtlas.cpp
Rendering/frontend smoke tests
Source/Tests/Test_Rendering.cpp
Validation routing by change type
- Essentials utilities: start with Essentials.md and the essentials tests listed above.
- Config, file lookup, caches, resource packs: ConfigurationAndDataSources.md, parser/filesystem/cache tests, and affected bake/runtime consumers.
- BuildTools/CMake/generation: BuildToolsPipeline.md, GeneratedApiAndMetadata.md, codegen/property/metadata tests, and at least one generated target.
- Bakers/resources: BakingPipeline.md and the matching baker tests.
- Runtime entity/map/persistence/networking: EntityModel.md, MapsMovementGeometry.md, Persistence.md, Networking.md, and the focused runtime tests.
- Client/frontend/server: ClientRuntime.md, FrontendAndRendering.md, ServerRuntime.md, and the matching integration/smoke tests.
- Scripting: Scripting.md, ScriptMethodsMap.md, Nullability.md, and the script/baker/method tests.
Adding or removing tests
- Add the new
Source/Tests/Test_*.cppfile with deterministic Catch2 tests. - Add it to
FO_TESTS_SOURCEinBuildTools/cmake/stages/EngineSources.cmake. - Update this page and ../Source/Tests/README.md so the inventory stays complete.
- Run the focused test binary and, when practical,
RunUnitTests. - If coverage behavior changed, verify the relevant coverage target.
Validation checklist
- Every current
Source/Tests/Test_*.cppfile should appear in this page. - No deleted/nonexistent test file should be listed.
- Target names should be described as generated from
FO_DEV_NAME, not hard-coded as universal engine names. - If
TestingApp.cpp,FO_TESTS_SOURCE, or coverage target wiring changes, update this page in the same change.