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 native validation for an engine change or when adding/removing Catch2 tests. The source-tree README at Source/Tests/README.md is a short entry point; this page is the maintained full test map. For deterministic script, content, server, and client process tests in an embedding game, continue with Gameplay and Integration Testing.
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/cmake/helpers/RunAndLog.cmakeBuildTools/codecoverage.pyBuildTools/validate.shBuildTools/validate.cmd
Test runner model
Source/Applications/TestingApp.cpp is the test application entry point. It requires FO_TESTING_APP, initializes the application layer with InitAppForTesting(), 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):
BuildTools/check_windows7_imports.py <binary> [...] is the standalone PE-level regression check for Windows 7 artifacts. It accepts one or more PE files and fails closed on unreadable or malformed input. It rejects a curated set of Windows 8+ kernel32, user32, dxgi, and d3d11 exports (including CreateFile2 and GetCurrentThreadStackLimits), libraries absent from Windows 7 (shcore.dll, combase.dll, d3d12.dll, dcomp.dll, d3dcompiler_47.dll), and API-set contracts except Universal CRT forwarders (api-ms-win-crt-*). Add any newly discovered incompatible export to the list with its import fix. Static third-party libraries, including the managed runtime, contribute to the same final PE import table. Embedding-project CI should check every linked Win7 executable and DLL after linking and before packaging; this static gate does not prove runtime behavior on a real Windows 7 SP1 host. See the Windows 7 compatibility lane.
UnitTestswhenFO_UNIT_TESTSis enabled;CodeCoveragewhenFO_CODE_COVERAGEis enabled.
The standard generated names use the embedding project’s development-name prefix: <ProjectDevName>_UnitTests, RunUnitTests, <ProjectDevName>_CodeCoverage, RunCodeCoverage, GenerateCodeCoverageReport, and AnalyzeCodeCoverage. Treat the prefix as project-generated, not universal.
Running tests
Test_ClientEntityLifetime.cpp covers repeated map unloads with retained handles, pending item owners, failed construction and atlas cleanup with live/empty pages. Test_MapSprite.cpp pins holder detachment and reuse after Clear(); Test_ResourceIndex.cpp pins decoded-vector ownership transfer. The destroyed-map storage bound requires debug/profiling allocator statistics. Headless ownership checks do not qualify physical GPU memory, working-set trends or a platform’s long-session OOM behavior.
The repeated-unload storage comparison warms one complete map load/unload cycle before reading rpmalloc’s committed active-page counter. Twelve destroyed maps retained by native handles must then stay within the same 8 MiB bound. Render-target ownership is checked on every cycle, including warm-up; this separates allocator initialization from repeated retained-map storage, not GPU memory or process working-set acceptance.
MapViewItemHitTesting* and TransparentEgg* cover native sprite picking and
egg classification. Test_MapViewHitTesting.cpp owns its prototypes, baked
sprites and optional AngelScript fixture, so it runs with either scripting
backend. It checks a faded wall over a floor, both ignore_transparent_egg
policies, alpha hit testing, an empty point and clearing the egg. These native
queries do not certify an embedding game’s cursor input or tool effects.
Preferred local baseline from a configured build:
cmake --build . --config RelWithDebInfo --target RunUnitTests
With FO_EFFEKSEER_PARTICLES enabled, the focused [particle] Catch2 cases
invoke the published helper through the production ParticleBaker path. They
cover text compilation, dependency invalidation, malformed XML, and rejection
of cooked files presented as authored inputs.
The executable target can also be invoked directly when you need Catch2 arguments. Test binaries are emitted under Binaries/Tests-*, for example Binaries/Tests-Windows-win64/<ProjectDevName>_UnitTests.exe or Binaries/Tests-Linux-x64/<ProjectDevName>_UnitTests.
Atlas and render-target dump tests use TexDumpArtifacts from
Source/Tests/Test_DumpArtifacts.h. A test snapshots the existing
TexDump_* directories before it invokes production dumping, then removes only
new directories created by that run. This prevents parallel or interrupted
test sessions from deleting pre-existing diagnostic evidence and keeps cleanup
scoped to artifacts the test can prove it owns.
With Visual Studio/MSBuild generators, RunUnitTests writes the test process output to <build-dir>/<ProjectDevName>_UnitTests.log and uses the test process exit code as the pass/fail signal. This keeps expected negative-case diagnostics such as compiler error lines from being reclassified as MSBuild errors. On failure the helper also echoes the captured output before stopping, so CI logs name the failing test/assertion even when the runner workspace and file log are discarded.
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
The ordinary unit-tests validator resolves native to the host toolchain:
MSVC/Visual Studio on Windows, Xcode on macOS, and Clang on Linux. It rejects a
cached non-Visual-Studio generator when the Windows configure command requires
-A, while accepting any cached Visual Studio version rather than pinning the
generator display name. Sanitizer validators remain explicitly Linux-specific.
BuildTools/tests/test_native_unit_validation.py covers platform resolution,
configure forwarding, generator-cache checks, and unsupported hosts.
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 crash handlers are disabled under
MSan and TSan so the sanitizer runtimes own their reports. Bundled LLVM libunwind
and libbacktrace are built without instrumentation because their crash paths read
other frames and debug data. 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.
Applications that load BakerLib while running under a sanitizer must use a baker
built with the same San_* configuration. Hiding the plugin’s ELF exports prevents
direct symbol interposition, but calls implemented inside the shared C++ runtime may
still allocate through the host and return to an inline deallocator in the plugin.
Matching configurations keep the sanitizer runtime and allocator contract identical
on both sides of that module boundary.
On MSVC, the San_Address/Debug_San_Address configs additionally link executables with
/STACK:8388608 (AddExecutableApplication in BuildTools/cmake/helpers/Build.cmake):
ASan’s stack-frame inflation overflows the 1 MiB Windows executable default on recursion
depths that fit every production configuration, so sanitizer runs get the same 8 MiB
reserve that Linux runs already have from the default rlimit. Production configs keep the
1 MiB default.
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:
- Linux libbacktrace (
Source/Essentials/StackTrace.cpp) retains debug information in its own mapped memory for the life of the process. Its state remains reachable through process-lifetimeStackTraceState, serialized byNativeResolverLocker; a module is read once and LSan has no allocated orphan to report. - The AngelScript backend deletes the preprocessor line-number translator during engine userdata
cleanup, and each SPARK context frees its
IOManagerconverters at context shutdown. - Owning containers free their contents transitively: e.g.
EntityTypeDesc::PropRegistraris aunique_ptrso everyPropertyRegistrar(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>/.
The isolated Applications-stage fixtures in
BuildTools/tests/test_codecoverage_llvm_objects.py include the real resource-pack
hash helper sources and prove that native host platforms build the helper without
LLVM coverage flags. They also retain actual instrumented-process collection, core
library reuse and quick-exit flush assertions.
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.
Coverage is platform- and environment-specific. Sources not compiled in the current build have no mapping and are reported separately as untouched. Sources that compile but cannot execute in a headless test process belong in ENVIRONMENT_EXCLUDED_SOURCES with a written reason; currently this covers device-backed audio/video, Mongo/updater infrastructure, and the deliberately process-killing diagnostic self-test. Loopback sockets and the debugger endpoint remain in the headline. The report shows scoped, all-source, and excluded buckets independently. An exclusion is a routing decision: the owning platform, windowed run, or real-endpoint integration lane must cover it.
Focused harness patterns
- ImGui panels: create a backend-less context, set
ImGuiBackendFlags_RendererHasTextures, and useImGui::LogToBuffer(depth)to auto-open tree nodes and prove nested text rendered. Collapsing headers opt out and need their IDs seeded inStateStorage. Destroy the context at scope exit. To cover widget branches,ImGuiTestHarness::ActivateItemneeds two frames; address controls under child windows withActivateChildItem, draw only the owning panel so another window’s focus request cannot erase activation, and clear stale active IDs between presses. - Server diagnostics: a sync point does not itself cover entities. Snapshot not-logged-in players under the publication lock, release it before entity locks, and then acquire one replacement cover for the snapshot and registered world. Keep a real not-logged-in fixture in the test.
- Inbound remote calls: entry covers the calling player and its controlled critter. Any second entity needs explicit
Game.Sync; do not probe an operation expected to violate cover behind scripttry/catch, because the session is torn down before the next probe arrives. - Crash reporting: test non-terminating crash-stream formatting through a private log file, then restore logging to
NULor/dev/null. Test terminating reporters out of process withDiagnosticSelfTest;main_basic_strong_assert,main_fatal_exit, andmain_failure_exitdistinguish early fatal reporting from raw status-only exit. - Fonts without assets: synthesize
.fofnttext or BMFontBMF\3blocks in memory, provide a matching sprite, and bind with scale in(0..1].SplitLinesemits rect-sized pages, so use a short rectangle when a test needs multiple outputs. - Logged-in client/server: declare login remote calls in both metadata blobs with opposite directions and the correct subsystem/namespace, add at least one project-owned persistent
Playerproperty before login insertion, then create/switch a critter and transfer it into a location/map to reach world-entry replication. Both.fomap-bin-*blobs start withBAKED_MAP_FILE_MAGICandBAKED_MAP_FILE_VERSION; after the header, the client layout ends after the hash-table and static-item counts. - World reload: use file-backed JSON, mark expected entities persistent, shut down one server, and start another on the same directory. Reload reaches critters through their owning map or global-map membership; an off-map runtime critter is not restored.
- Headless 3D: bake a non-degenerate triangle, build the description with
ModelInfoBaker, provide both source and baked mesh entries plusMetadata.fometa-clientandModelAnimationInfo.foinfo, then instantiate through the null renderer. Build fixture metadata withBakerTests::MakeMetadataBloborMakeEmptyMetadataBlob; registration rejects a blob without the required metadata version. - Static maps and mapper disk writes: write the baked-map format header first, then serialize real
Properties::StoreAllData()payloads for server map records; zero length is invalid. The server payload continues with hashes, critters, and items, while the shorter client payload contains hashes and static items. Mapper save tests need an actualInputDirsMaps root containing a reference.fomap; preferSaveMapToDir, because plainSaveMapmay otherwise write into the process working directory. A per-map static item removal is only observable end to end when the same static item id appears in both payloads — the server needs it inStaticItemsByIdto remove and the client needs a view built from it to drop — soTest_ClientServerIntegrationcarries one such item in both map blobs.
Current test inventory
The authoritative test-file count and complete sorted filename list are generated from Source/Tests/Test_*.cpp into source-inventory.json. Do not copy the total or full list into prose.
Regenerate and verify it from the engine root:
python BuildTools/docs_inventory.py --write
python BuildTools/docs_inventory.py --check
Use these ownership groups to choose a starting area; the filenames are representative, while the generated JSON is exhaustive:
Configuration and data sources
Source/Tests/Test_CacheStorage.cppSource/Tests/Test_ConfigFile.cppSource/Tests/Test_DataSource.cppSource/Tests/Test_FileSystem.cppSource/Tests/Test_Settings.cppSource/Tests/Test_SettingsStorage.cpp
Common runtime model
-
Source/Tests/Test_ApplicationHeadless.cpp 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_ModelAnimation.cppSource/Tests/Test_NetBuffer.cppSource/Tests/Test_NoiseProtocol.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.cppSource/Tests/Test_SecureChannel.cpp
Scripting and script-visible APIs
Source/Tests/Test_AngelScriptAlignment.cppSource/Tests/Test_AngelScriptAttributes.cppSource/Tests/Test_AngelScriptBytecode.cppSource/Tests/Test_AngelScriptCall.cppSource/Tests/Test_ManagedScriptBaker.cppSource/Tests/Test_CommonScriptMethods.cppSource/Tests/Test_ScriptBuiltins.cppSource/Tests/Test_ScriptEntityOps.cppSource/Tests/Test_ServerScriptMethods.cpp
The AngelScript suites cover its compiler/runtime, bytecode, call bridge, attributes, builtins, and baker. Managed C# has separate evidence layers: Test_ManagedScriptBaker.cpp covers native baker generation; BuildTools/tests/test_managed_*.py covers runtime setup, payloads, platforms, callbacks, GC roots, and packaging; Source/Scripting/Managed/Analyzers/Tests exercises the Roslyn synchronization analyzer; and Source/Scripting/Managed/Tests exercises CoreScripts and generated API bootstrap. Run CompileManagedScripts and then a real Managed resource bake to prove the embedding project’s configured sources, target assemblies, and ManagedRuntime/ payload. These layers complement rather than substitute for the backend-neutral entity/script-method tests.
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_Mapper.cppSource/Tests/Test_MetadataBaker.cppSource/Tests/Test_ModelBaker.cppSource/Tests/Test_ModelBounds.cppSource/Tests/Test_ModelMeshData.cppSource/Tests/Test_ModelAnimationData.cppSource/Tests/Test_ModelAnimationConverter.cppSource/Tests/Test_ModelAnimationPoseProcedural.cppSource/Tests/Test_ModelAnimationRuntime.cppSource/Tests/Test_ModelSpriteLayout.cppSource/Tests/Test_ModelSkeletonCompatibility.cppSource/Tests/Test_ModelSourceLoader.cppSource/Tests/Test_OzzAnimation.cppSource/Tests/Test_ProtoBaker.cppSource/Tests/Test_ProtoTextBaker.cppSource/Tests/Test_RawCopyBaker.cppSource/Tests/Test_TextBaker.cppSource/Tests/Test_TextureAtlas.cpp
The model-animation tests divide the production contract explicitly.
Test_ModelMeshData.cpp exercises the mandatory LFMODMSH schema-1 mesh-only
header and complete recursive payload codec. It covers geometry, skin palettes,
children, structural validation, trailing data, every truncated header size,
rejection of old headerless data, and exact byte compatibility with the original
schema-1 writer layout.
Test_ClientEngine.cpp also bakes a position-only OBJ through ModelMeshBaker
and preloads the resulting bytes through the real ModelManager parser. This
crosses the BakerLib/ClientLib boundary and catches payload-layout drift that
a second test-only parser could reproduce instead of detecting.
Test_ModelSourceLoader.cpp covers complete source validation, real minimal
OBJ/ASCII-FBX extraction, per-call cache single-flight behavior, shared results,
exception fan-out, and missing inputs. Test_ModelAnimationData.cpp exercises the
little-endian archive, joint-remap, and rig-manifest contracts, including
truncation, count/length bombs, ordering, metadata mismatches, and bindings.
Test_ModelAnimationConverter.cpp covers canonical conversion and the per-instance
runtime pose: unaligned/owned loading, body blending, movement replacement,
reverse and nearest sampling, stable storage, canonical resolution, and numeric
limits. Test_ModelAnimationPoseProcedural.cpp covers bounded procedural pre-rotations
and exact world-matrix overrides; Test_ModelAnimationRuntime.cpp covers the
validated direct-model rest path, canonical contributed-joint lookup, and
cross-model joint-link resolution without physical bones.
Test_ModelBaker.cpp covers source-backed model-info generation,
dependency-mtime invalidation, exact animation-geometry exceptions, Base,
reverse, case-insensitive lookup, and clip deduplication. Test_ModelAnimation.cpp
is the timeline/binding behavior gate: controller copies own mutable event state
while sharing only immutable Ozz clip metadata.
After source-loader, mesh-wire, or converter changes, ForceBakeResources is
the positive real-content gate: it must parse the project’s actual selected FBX
sources and extract their animations successfully. Run ordinary
BakeResources afterward to check that the dependency-mtime contract leaves an
unchanged tree incremental-clean.
Rendering/frontend smoke tests
-
Source/Tests/Test_ImGui.cpp— pins the backend-less widget-activation and window-state harness used for diagnostic-panel coverage. Source/Tests/Test_EffekseerParticleRuntime.cpp— runs cooked legacy and modern Effekseer effects through the native runtime’s real Sprite/Ring callbacks and validates deterministic multi-instance topology, FOnline geometry, atlas UVs, all three Z-sort modes, Ring index-budget chunking, and facade-level scale reapplication without respawn or timing reset.Source/Tests/Test_ParticleBaker.cpp— covers.efkprojsource discovery,.spark/.efkprojoutput-key mapping, generated binary validation, and rejection of authored.spk/.efkruntime inputs. The build/integration bake path exercises the native fixed-profile exporter on real XML projects.Source/Tests/Test_Rendering.cpp
Ownership summary
| Area | Typical coverage and starting points |
|---|---|
| Essentials and low-level utilities | Logging, containers, serialization, filesystem, exceptions, memory, platform, smart pointers, stack traces, strings, time, and worker primitives. |
| Configuration and data sources | Cache storage, config parsing, data sources, filesystems, and Test_Settings.cpp. |
| Common runtime model | Metadata, entities/prototypes, geometry, map loading, movement, line tracing, and path finding. |
| Networking and server/client integration | Network buffers, connection flows, ordered UDP, server engine/map operations, client runtime ABI, updater, and database behavior. |
| Scripting and script-visible APIs | AngelScript and Managed C# backends, bakers, generated APIs, callbacks/async behavior, entity ops, exports, script methods, synchronization, and value semantics. |
| Bakers and tools | Baker, metadata/resource packers, mapper/editor tools, asset processors, and tool-side regressions. |
| Frontend and rendering | Application init, frontend/rendering smoke cases, headless behavior, and renderer-facing contracts. |
Managed interop changes require both generated-shape and live-runtime evidence.
Test_ManagedScriptBaker.cpp pins dense ABI ids, typed settings and scalar/value
property routes, raw-byte fixed-value arrays, FillInnerEntities, generated
callback adapters and wrapper factories, and inclusion of *Abi.gen.cs in the
bake stamp. The native frame test deliberately passes an unaligned packed buffer
through ManagedAbiNativeFrame and verifies aligned arguments, selective
mutable/result copy-back, bounds checks, and value preservation.
CoreScripts/InteropProbe.cs is the reusable live probe. It compares runtime
invoke, classic thunk, and UnmanagedCallersOnly callback transports where
dynamic code exists; exercises enum/bool/int64/value/hstring, exceptions,
collections, nested entries, native threads, instance and virtual targets; and
reports managed bytes plus per-thread native counters for handles, lookups,
objects, and wrappers. Native allocation counts are available only in Tracy
builds. Latency is observational rather than a CI threshold, but allocations,
delivery counts, and transport checks are assertions. On browser and device
clients set ManagedScript.InteropProbeOnStart=True and require the closing
INTEROP-TRANSPORT summary to report zero failures; interpreter-only Web tests
runtime invoke and skips transports that need compiled code.
Validation routing by change type
- Essentials utilities: start with Essentials.md and the essentials tests listed above.
- Config, file lookup, caches, resource packs: Configuration and Data Sources, parser/filesystem/cache tests, and affected bake/runtime consumers.
- BuildTools/CMake/generation: BuildTools Pipeline, GeneratedApiAndMetadata.md, codegen/property/metadata tests, and at least one generated target.
- Bakers/resources: Baking Pipeline and the matching baker tests.
- Runtime entity/map/persistence/networking: Entity Model, Maps and Movement, Persistence, Networking, and the focused runtime tests.
- Client/frontend/server: Client Runtime, Frontend and Rendering, Server Runtime, and the matching integration/smoke tests.
- Scripting: Scripting, Managed C# Scripting, Script Lifecycle and Concurrency, AngelScript Style and Refactoring, Script Methods Map, Nullability, and the script/baker/method tests. Route AngelScript attributes and mutable globals to its dedicated suites; route Managed generation, indexed ABI/native-frame transport, analyzers, async callbacks, runtime payloads, and packaging to the matching native, Python, and C# suites; route shared server cover/lock behavior to
Test_EntitySyncplus the affected script-method/entity 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. - Run
python BuildTools/docs_inventory.py --writeso the generated filename list and count stay current. - Update this page only when the new test changes an ownership group or validation route.
- Run the focused test binary and, when practical,
RunUnitTests. - If coverage behavior changed, verify the relevant coverage target.
Validation checklist
python BuildTools/docs_inventory.py --checkproves the generated filename list and count matchSource/Tests/.python BuildTools/docs_validate.pyproves the generated artifact and documentation links are current.- Target names are described as generated from
FO_DEV_NAME, not hard-coded as universal engine names. - If
TestingApp.cpp,FO_TESTS_SOURCE, ownership groups, or coverage target wiring changes, update this page in the same change.
See also
- Profiling for Tracy build modes, workload isolation, and performance captures.
- Native, AngelScript, and Managed C# Debugging for backend-specific diagnosis.