Тестирование
Документация принадлежит движку. Страница описывает текущий test executable, сгенерированные test/coverage targets и полный набор suites из
Source/Tests/Test_*.cpp.
Назначение
Используйте эту страницу, чтобы подобрать native-проверку для изменения движка или добавить Catch2-тест. Краткая точка входа находится в Source/Tests/README.ru.md, а здесь поддерживается полная карта. Для детерминированных script/content/server/client процессов проекта продолжайте с Gameplay и integration testing.
Проверенные исходные пути
Source/Applications/TestingApp.cppSource/Tests/README.mdи все текущиеSource/Tests/Test_*.cppBuildTools/cmake/stages/EngineSources.cmakeBuildTools/cmake/stages/Applications.cmakeBuildTools/cmake/stages/Init.cmakeBuildTools/cmake/helpers/RunAndLog.cmakeBuildTools/codecoverage.pyBuildTools/validate.shиBuildTools/validate.cmd
Модель test runner
Source/Applications/TestingApp.cpp является entry point тестового приложения.
Он требует FO_TESTING_APP, вызывает InitAppForTesting(), выставляет
IsTestingInProgress и передает выполнение в
Catch::Session().run(argc, argv).
EngineSources.cmake владеет явным списком FO_TESTS_SOURCE.
Applications.cmake строит executable через SetupTestBuild(name):
UnitTests, когда включенFO_UNIT_TESTS;CodeCoverage, когда включенFO_CODE_COVERAGE.
Стандартные имена используют development-префикс проекта:
<ProjectDevName>_UnitTests, RunUnitTests,
<ProjectDevName>_CodeCoverage, RunCodeCoverage,
GenerateCodeCoverageReport, AnalyzeCodeCoverage. Префикс генерирует проект,
он не является универсальным именем движка.
Отдельный BuildTools/check_windows7_imports.py <binary> [...] проверяет один
или несколько PE-файлов, fail-closed обрабатывает поврежденный ввод и запрещает
поддерживаемый список экспортов Windows 8+ из kernel32, user32, dxgi,
d3d11 (включая CreateFile2 и GetCurrentThreadStackLimits), отсутствующие
в Windows 7 библиотеки (shcore.dll, combase.dll, d3d12.dll, dcomp.dll,
d3dcompiler_47.dll)
и API-set contracts, кроме Universal CRT forwarders (api-ms-win-crt-*). Новый
несовместимый экспорт добавляют в список одновременно с исправлением импорта.
Статически связанные библиотеки, включая managed runtime, попадают в таблицу
импортов итогового PE. Проектная CI-ветка Windows 7 должна проверять каждый
связанный executable и DLL после линковки и до упаковки. Статическая проверка
не доказывает работу на настоящей Windows 7 SP1; см.
Windows 7 compatibility lane.
Запуск тестов
Сравнение памяти при повторных unload сначала прогревает один полный цикл загрузки/выгрузки карты, затем читает счётчик committed active pages rpmalloc. Двенадцать уничтоженных карт, сохранённых через native handles, должны остаться в прежнем лимите 8 MiB. Владение render targets проверяется на каждом цикле, включая прогрев: инициализация allocator отделена от памяти удержанных карт, но это не проверка GPU memory или process working set.
Test_ClientEntityLifetime.cpp проверяет повторную выгрузку карт с удерживаемыми handles, отложенных владельцев предметов, ошибку конструктора и очистку atlas с занятыми/пустыми pages. Test_MapSprite.cpp закрепляет отсоединение holders и повторное использование после Clear(); Test_ResourceIndex.cpp — передачу владения decoded vector. Предел памяти уничтоженных карт требует debug/profiling allocator statistics. Headless проверки владения не являются приёмкой памяти физического GPU, working-set trends или долгого сеанса с OOM на целевой платформе.
MapViewItemHitTesting* и TransparentEgg* проверяют native sprite picking и
классификацию «яйца». Test_MapViewHitTesting.cpp содержит собственные прототипы,
baked sprites и optional AngelScript fixture, поэтому работает с обоими
скриптовыми backend. Проверяются полупрозрачная стена над полом, обе политики
ignore_transparent_egg, alpha hit testing, пустая точка и сброс «яйца». Native
queries не подтверждают ввод курсора или эффекты инструмента встраивающей игры.
Предпочтительная локальная проверка из настроенной build directory:
cmake --build . --config RelWithDebInfo --target RunUnitTests
При включенном FO_EFFEKSEER_PARTICLES focused [particle] cases вызывают
публичный helper через production-путь ParticleBaker: проверяются text
compilation, dependency invalidation, malformed XML и запрет cooked-файлов как
authored inputs.
Executable можно вызвать напрямую с аргументами Catch2. Он находится под
Binaries/Tests-*, например
Binaries/Tests-Windows-win64/<ProjectDevName>_UnitTests.exe или
Binaries/Tests-Linux-x64/<ProjectDevName>_UnitTests.
Tests dump-ов atlas и render target используют TexDumpArtifacts из
Source/Tests/Test_DumpArtifacts.h. До production dump test сохраняет snapshot
существующих каталогов TexDump_*, а затем удаляет только новые каталоги своего
run. Поэтому parallel или прерванный test session не удаляет ранее собранные
diagnostic evidence, а cleanup ограничен artifacts с доказанным ownership.
Для Visual Studio/MSBuild RunUnitTests пишет process output в
<build-dir>/<ProjectDevName>_UnitTests.log и использует exit code процесса.
Так ожидаемые строки error из negative cases не превращаются в ошибки MSBuild.
При failure helper также выводит captured output перед остановкой, поэтому CI log
называет failing test/assertion даже после удаления runner workspace и file log.
BuildTools может запускать выбранные широкие сценарии:
Engine/BuildTools/validate.sh unit-tests
Engine/BuildTools/validate.sh android-arm64-client linux-client linux-server
Обычный validator unit-tests разрешает native в toolchain текущего host:
MSVC/Visual Studio на Windows, Xcode на macOS и Clang на Linux. Если Windows
configure command требует -A, validator отклоняет cached generator не из
семейства Visual Studio, но принимает любую cached версию Visual Studio вместо
закрепления display name generator. Sanitizer validators остаются явно
Linux-specific. BuildTools/tests/test_native_unit_validation.py покрывает
platform resolution, передачу configure, проверки generator cache и
неподдерживаемые hosts.
Начинайте с минимального focused test и добавляйте общий target, когда изменение пересекает границы подсистем.
Unit-тесты под sanitizers
Выделенные validators выбирают соответствующий San_* build type и запускают
инструментированный RunUnitTests:
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
Workflow validate.yml выполняет их матрицей unit-tests-sanitizers; все четыре
ветки блокирующие. MemorySanitizer подготавливает Workspace/msan-libcxx из
инструментированных libc++, libc++abi, libunwind и передает
FO_MSAN_LIBCXX_ROOT. Узкий libunwind ignorelist не дает unwinding-у исключений
самому срабатывать на ABI snapshots. Native stack capture и crash handlers
отключаются под MSan и TSan, чтобы reports принадлежали sanitizer runtimes.
Bundled LLVM libunwind и libbacktrace собираются без instrumentation: crash path
читает другие stack frames и debug data. Более медленный
unit-tests-san-memory-with-origins предназначен для
локальной диагностики. San_DataFlow не подключен: DataFlowSanitizer является
taint framework, а не общим defect detector.
Приложение, загружающее BakerLib под sanitizer, должно использовать библиотеку
той же San_*-конфигурации. Скрытие ELF exports не устраняет переходы через
общий C++ runtime и allocator; совпадающие конфигурации сохраняют единый runtime
contract.
На MSVC San_Address и Debug_San_Address получают executable stack 8 MiB.
ASan раздувает stack frames и может переполнить Windows-default 1 MiB; production
configurations сохраняют стандартное значение.
Для vendored third-party кода UBSan исключает только function и alignment:
AngelScript вызывает зарегистрированные C-функции через обобщенные signatures и
укладывает pointer operands в 4-byte-aligned bytecode slots. Остальные undefined
checks активны, а first-party Engine сохраняет и эти две проверки.
LeakSanitizer входит в address leg с detect_leaks=1 и без suppression list.
Linux libbacktrace хранит прочитанные debug data в собственной mapped memory;
его process-lifetime state остается достижимым через StackTraceState, а
AngelScript preprocessor translator, SPARK converters и owning metadata
containers освобождаются при shutdown. Новые утечки исправляются в источнике,
а не скрываются.
Code coverage
При FO_CODE_COVERAGE backend выбирается компилятором:
- MSVC и clang-cl используют MSVC-style output;
- Clang использует LLVM profile/coverage mapping;
- GCC использует GCC/lcov flags.
Applications.cmake подключает через BuildTools/codecoverage.py targets
CleanCodeCoverageData, RunCodeCoverage, GenerateCodeCoverageReport и
AnalyzeCodeCoverage. Результат находится под
CodeCoverage/<Toolchain>/<Platform-Config>/.
Изолированные фикстуры стадии Applications в
BuildTools/tests/test_codecoverage_llvm_objects.py включают настоящие исходники
помощника хеширования пакетов ресурсов и проверяют его сборку без флагов LLVM
coverage на нативных платформах хоста. Они также сохраняют сбор профилей реально
инструментированных процессов, повторное использование core library и проверки
сброса профиля при quick exit.
В denominator входят first-party production sources из Engine/Source/;
Source/Tests/, ThirdParty/, GeneratedSource/ и Applications/ исключены.
Локальные примечания находятся в
Source/Tests/README.ru.md.
Coverage зависит от platform и environment. Sources, не скомпилированные в текущем build, не имеют mapping и отдельно показываются как untouched. Sources, которые компилируются, но не могут выполниться в headless test process, входят в ENVIRONMENT_EXCLUDED_SOURCES с письменной причиной; сейчас это device-backed audio/video, Mongo/updater infrastructure и намеренно завершающий процесс diagnostic self-test. Loopback sockets и debugger endpoint остаются в headline. Report раздельно показывает scoped, all-source и excluded buckets. Exclusion является routing decision: его обязан покрыть owning platform, windowed run или integration lane с реальным endpoint.
Шаблоны focused harness
- ImGui panels: создайте backend-less context, задайте
ImGuiBackendFlags_RendererHasTexturesи используйтеImGui::LogToBuffer(depth)для auto-open tree nodes и доказательства nested text. Collapsing headers требуют ручной записи IDs вStateStorage. Context уничтожается на scope exit. Для widget branchImGuiTestHarness::ActivateItemтребует два frame; controls в child windows адресуются черезActivateChildItem, а между presses очищается stale active ID. - Server diagnostics: sync point сам не покрывает entities. Snapshot ещё не вошедших players берётся под publication lock; lock освобождается до entity locks, после чего один replacement cover охватывает snapshot и registered world. Fixture должен содержать настоящего not-logged-in player.
- Inbound remote calls: entry покрывает calling player и controlled critter. Любая вторая entity требует явного
Game.Sync; ожидаемый cover violation нельзя проверять под scripttry/catch, потому что session завершится до следующего probe. - Crash reporting: non-terminating crash stream проверяется через private log file с последующим возвратом на
NULили/dev/null. Terminating reporters запускаются вне процесса черезDiagnosticSelfTest;main_basic_strong_assert,main_fatal_exitиmain_failure_exitразличают ранний fatal report и raw status-only exit. - Fonts без assets: синтезируйте
.fofnttext или BMFont blocksBMF\3в памяти, предоставьте sprite и bind scale из(0..1].SplitLinesвыдаёт pages размером с rect, поэтому для нескольких outputs нужен короткий rectangle. - Logged-in client/server: login remote calls объявляются в обоих metadata blobs в противоположных направлениях с правильным subsystem/namespace. До login insertion добавьте хотя бы одно project-owned persistent
Playerproperty, затем создайте и переключите critter и перенесите его в location/map. Оба.fomap-bin-*blob начинаются сBAKED_MAP_FILE_MAGICиBAKED_MAP_FILE_VERSION; после header client layout заканчивается после counts hash table и static items. - World reload: используйте file-backed JSON, отметьте ожидаемые entities persistent, остановите один server и запустите второй на том же каталоге. Critter восстанавливается через owning map или global-map membership; off-map runtime critter не reload-ится.
- Headless 3D: запеките недегенеративный triangle, создайте description настоящим
ModelInfoBaker, предоставьте source и baked mesh,Metadata.fometa-clientиModelAnimationInfo.foinfo, затем создайте instance через null renderer. Fixture metadata создавайте черезBakerTests::MakeMetadataBlobилиMakeEmptyMetadataBlob: registration отклоняет blob без обязательной metadata version. - Static maps и disk writes Mapper: сначала запишите baked-map format header, затем настоящий payload
Properties::StoreAllData()для server map records; zero length недопустим. Server payload продолжается hashes, critters и items, а более короткий client payload содержит hashes и static items. Mapper save tests требуют настоящий Maps root черезInputDirsс reference.fomap; предпочитайтеSaveMapToDir, потому что plainSaveMapиначе может записать в working directory процесса. Удаление статического предмета на карте наблюдаемо от начала до конца только тогда, когда один и тот же id статического предмета есть в обоих payload — серверу он нужен вStaticItemsById, чтобы удалить, а клиенту нужен построенный из него view, чтобы убрать, — поэтомуTest_ClientServerIntegrationдержит такой предмет в обоих map blobs.
Текущий набор тестов
Полный отсортированный список и authoritative count генерируются из
Source/Tests/Test_*.cpp в
source-inventory.json. Не копируйте
полный список или total в prose.
python BuildTools/docs_inventory.py --write
python BuildTools/docs_inventory.py --check
Группы ниже помогают выбрать starting area; generated JSON остается исчерпывающим.
Конфигурация и источники данных
Начните с Test_CacheStorage.cpp, Test_ConfigFile.cpp, Test_DataSource.cpp,
Test_FileSystem.cpp, Test_Settings.cpp и Test_SettingsStorage.cpp.
Общая runtime-модель
Сюда относятся headless application (Test_ApplicationHeadless), metadata, entities/prototypes, properties, geometry, map loading,
movement/pathfinding, text packs, timers и two-dimensional grids. Основные suites:
Test_EngineMetadata, Test_EntityLifecycle, Test_EntityProtos,
Test_MapLoader, Test_Movement, Test_PathFinding, Test_Properties,
Test_ProtoManager и соседние common tests.
Networking и server/client integration
Начните с Test_ClientDataValidation, Test_NetBuffer, Test_NoiseProtocol, Test_SecureChannel, Test_NetworkClient,
Test_NetworkServer, Test_NetworkUdp, Test_ClientServerIntegration,
Test_EntitySync, server engine/map/item suites, database, fog of war и
location/entity management.
Scripting и script-visible API
AngelScript compiler/runtime, bytecode, calls, attributes, builtins, entities и native script methods покрывают Test_AngelScript*, Test_ScriptBuiltins, Test_ScriptEntityOps, Test_CommonScriptMethods и Test_ServerScriptMethods.
Для Managed C# используются отдельные слои evidence: Test_ManagedScriptBaker.cpp проверяет native generation baker-а; BuildTools/tests/test_managed_*.py — runtime setup, payloads, platforms, callbacks, GC roots и packaging; Source/Scripting/Managed/Analyzers/Tests — Roslyn analyzer синхронизации; Source/Scripting/Managed/Tests — CoreScripts и bootstrap generated API. После них выполните CompileManagedScripts и реальный resource bake Managed, чтобы доказать настроенные проектом sources, target assemblies и payload ManagedRuntime/. Эти слои дополняют, а не заменяют backend-neutral tests сущностей и script methods.
Bakers и инструменты
Сюда входят Baker setup, config/effect/image/map/metadata/model/particle/proto/ text processors, Mapper, texture atlas, model source loader, Ozz и complete model-animation family.
Model-animation suites разделяют production contract. Test_ModelMeshData
проверяет обязательный LFMODMSH schema-1 wire format, structural validation,
truncation и exact writer compatibility. Test_ClientEngine пересекает реальный
BakerLib/ClientLib payload boundary. Test_ModelSourceLoader проверяет
OBJ/ASCII-FBX, cache single-flight и error fan-out. Test_ModelAnimationData,
converter, procedural pose, runtime, baker и timeline suites покрывают archive,
joint remap, manifests, sampling/blending, canonical resolution, links и event
state.
После source-loader, mesh-wire или converter изменений запускайте
ForceBakeResources на реальном содержимом проекта, затем обычный
BakeResources, который должен остаться incremental-clean на неизмененном tree.
Rendering/frontend smoke tests
Test_ImGui закрепляет backend-less harness активации widgets и состояния windows для coverage diagnostic panels.
Test_EffekseerParticleRuntime проводит cooked legacy/modern effects через
реальные Sprite/Ring callbacks и проверяет topology, geometry, UV, Z-sort,
index chunking и scale reapplication. Test_ParticleBaker проверяет authored
source discovery/output mapping и запрет runtime .spk/.efk как входов.
Общие renderer-контракты принадлежат Test_Rendering.cpp.
Сводка владения
| Область | Типичные starting points |
|---|---|
| Essentials | Logging, containers, serialization, filesystem, exceptions, memory, platform, smart pointers, stack traces, strings, time, workers. |
| Configuration/data | Cache, config, data source, filesystem, settings. |
| Common runtime | Metadata, entities/prototypes, geometry, maps, movement, pathfinding. |
| Networking/integration | Buffers, connections, UDP ordering, server/client runtime, updater, database. |
| Scripting | Backend AngelScript и Managed C#, bakers, generated API, callbacks/async, entities, exports, script methods, synchronization и value semantics. |
| Bakers/tools | Baking, metadata/resource packs, Mapper/editors и asset processors. |
| Frontend/rendering | Application init, visible/headless behavior и renderer-facing contracts. |
Изменения Managed interop требуют одновременно свидетельств generated shape и
live runtime. Test_ManagedScriptBaker.cpp фиксирует dense ABI ids, typed
settings, scalar/value property routes, raw-byte массивы fixed values,
FillInnerEntities, generated callback adapters и wrapper factories, а также
участие *Abi.gen.cs в bake stamp. Native frame test намеренно передаёт
невыравненный packed buffer через ManagedAbiNativeFrame и проверяет alignment
аргументов, выборочный copy-back mutable/result slots, границы и сохранность
значений.
CoreScripts/InteropProbe.cs является переиспользуемым live probe. Он сравнивает
runtime invoke, classic thunk и UnmanagedCallersOnly callback transports там,
где есть dynamic code; проверяет enum/bool/int64/value/hstring, exceptions,
collections, nested entries, native threads, instance и virtual targets; и
сообщает managed bytes вместе с per-thread native counters handles, lookups,
objects и wrappers. Native allocation counts доступны только в Tracy builds.
Latency служит наблюдением, а не CI threshold, но allocations, delivery counts и
transport checks остаются assertions. На browser/device client задайте
ManagedScript.InteropProbeOnStart=True и требуйте ноль failures в завершающем
INTEROP-TRANSPORT summary; interpreter-only Web проверяет runtime invoke и
пропускает transports, которым нужен compiled code.
Маршрутизация проверки по типу изменения
- Essentials: Essentials и соответствующие tests.
- Config/files/cache/resources: Конфигурация и источники данных, parser/filesystem/cache tests и потребители bake/runtime.
- BuildTools/CMake/codegen: конвейер BuildTools, Generated API и хотя бы один generated target.
- Bakers/resources: Baking Pipeline и owning baker tests.
- Runtime entities/maps/persistence/networking: русские Entity Model, Maps and Movement, Persistence, Networking и focused tests.
- Client/frontend/server: Client Runtime, Frontend и рендеринг, Server Runtime и integration/smoke tests.
- Scripting: runtime,
Managed C#,
lifecycle/concurrency,
стиль AngelScript,
method ownership,
nullability и соответствующие suites. Изменения AngelScript направляйте в его attribute/baker suites; Managed generation, indexed ABI/native-frame transport, analyzers, async callbacks, runtime payload и packaging — в соответствующие native, Python и C# suites; общий server cover/lock contract — в
Test_EntitySyncи затронутые entity/script-method tests.
Добавление и удаление тестов
- Добавьте детерминированный
Source/Tests/Test_*.cpp. - Включите его в
FO_TESTS_SOURCEвEngineSources.cmake. - Выполните
python BuildTools/docs_inventory.py --write. - Меняйте эту страницу, только если изменились ownership group или validation route.
- Запустите focused binary и, по возможности,
RunUnitTests. - При изменении coverage проверьте соответствующий target.
Контрольный список
python BuildTools/docs_inventory.py --checkподтверждает точное соответствие generated inventory каталогуSource/Tests.python BuildTools/docs_validate.pyпроверяет artifacts и ссылки.- Target names описаны как производные
FO_DEV_NAME. - Изменения
TestingApp.cpp,FO_TESTS_SOURCE, ownership groups или coverage wiring обновляют этот документ в той же change.
См. также
- Profiling — Tracy build modes и captures.
- Нативная отладка, AngelScript и Managed C# для диагностики конкретного backend.