ue-testing-debugging

Use when writing automation tests, functional tests, or any test in Unreal Engine. Also use when the user asks about "UE_LOG", logging, log categories, assertion, check, ensure, verify, DrawDebug, debug draw, console command, profiling, Unreal Insights, stat commands, or debugging techniques. See ue

By quodsoler · 860 installs

npx skills add quodsoler/unreal-engine-skills --skill ue-testing-debugging

Source repository · Upstream listing

UE Testing, Logging & Profiling Target engine: UE 5.8 . APIs below are verified against the 5.8 headers; older forms are listed under "Deprecated — do not use". This skill owns logging, assertions, automation/functional testing, console commands and performance profiling for the repo. Logging, assertions, stats, trace and CVars live in Core ( Logging/ , Misc/AssertionMacros.h , Stats/Stats.h , ProfilingDebugging/ , HAL/IConsoleManager.h ). Debug drawing, the Visual Logger and AHUD::ShowDebug live in Engine . Test frameworks are the developer modules AutomationController , CQTest , FunctionalTesting and AutomationDriver ; the Gameplay Debugger is the runtime module GameplayDebugger . Context Read .agents/ue project context.md if it exists (module names, conventions, enabled plugins, GAS/networking setup). Do not stop if it is missing. Identify the area from the request and the codebase; ask only when two plausible readings would produce different code. Request is about… Go to UE LOG , categories, verbosity, structured logging [Logging]( logging) check , ensure , verify , crash on bad state [Assertions]( assertions) Unit tests, IMPLEMENT SIMPLE AUTOMATION TEST , specs, latent commands [Automation Tests]( automation tests) TEST CLASS , ASSERT THAT , fixture style tests [CQTest]( cqtest) Tests placed in a map, AFunctionalTest [Functional Tests]( functional tests) Insights, stat , cycle counters, CSV, memory, hitches [Profiling]( profiling) DrawDebug , UE VLOG , Gameplay Debugger, ShowDebug [Debug Visualization]( debug visualization) Exec functions, FAutoConsoleCommand , CVars [Console Commands and CVars]( console commands and cvars) Logging Declaring categories Macro Where Scope DECLARE LOG CATEGORY EXTERN(Name, Default, CompileTime) header the module and everything that includes it DEFINE LOG CATEGORY(Name) one .cpp pairs with the EXTERN form DEFINE LOG CATEGORY STATIC(Name, Default, CompileTime) one .cpp that translation unit only DECLARE LOG CATEGORY CLASS(Name, Default, CompileTime) class body class static; pair with DEFINE LOG CATEGORY CLASS(Class, Name) DefaultVerbosity must be <= CompileTimeVerbosity or the static assert inside the category macro fires. Anything above CompileTimeVerbosity is deleted by the compiler, so DECLARE LOG CATEGORY EXTERN(LogMyGame, Log, Log) removes every Verbose / VeryVerbose call site. Monolithic builds can cap all categories at once by defining COMPILED IN MINIMUM VERBOSITY . Verbosity levels Level Console File Notes Fatal yes yes crashes the process, even when logging is disabled Error yes yes collected by commandlets and the editor; fails a commandlet Warning yes yes can be promoted to an error Display yes yes use this when the user must see the line Log no yes file only — the default for development messages Verbose no yes only once the category is raised to Verbose VeryVerbose no yes only once the category is raised to VeryVerbose ELogVerbosity::All is an alias for VeryVerbose and is the usual CompileTimeVerbosity argument. Emitting Wrap an expensive report in if (UE LOG ACTIVE(LogMyGame, Verbose)) { … } so the work itself is skipped, not just the formatting. Structured logging UE LOGFMT emits named fields that survive into Insights and log analysis; use {Name} placeholders, not %s . Field names must match [A Za z0 9 ]+ and be unique per event; values serialize through SerializeForLog or operator<<(FCbWriter&, T) . UE LOGFMT takes at most 16 fields — use UE LOGFMT EX with UE LOGFMT FIELD / UE LOGFMT VALUE beyond that. Shipping and Test builds NO LOGGING is !USE LOGGING IN SHIPPING in both Test and Shipping , and 0 in Debug and Development . Under NO LOGGING , UE LOG / UE CLOG / UE LOGFMT collapse to a Fatal only path: every non fatal call disappears, arguments included. Set bUseLoggingInShipping = true; in MyGame.Target.cs to define USE LOGGING IN SHIPPING=1 and get logging back. Controlling verbosity at runtime From code use UE SET LOG VERBOSITY(LogMyGame, Verbose) ; from config use [Core.Log] in DefaultEngine.ini . Assertions All in Misc/AssertionMacros.h . Choose by who is wrong: check for programmer error, ensure for a recoverable surprise worth reporting, a plain if for user or data input. ensure / ensureMsgf report once per call site per session ; ensureAlways / ensureAlwaysMsgf report every time. All four return the condition, so they compose with if . Build DO CHECK DO ENSURE DO GUARD SLOW NO LOGGING Debug 1 1 1 0 Development 1 1 0 0 Test and Shipping USE CHECKS IN SHIPPING USE ENSURES IN SHIPPING 0 !USE LOGGING IN SHIPPING USE CHECKS IN SHIPPING defaults to 0 and is set by bUseChecksInShipping in the target rules, so Test builds also strip check and ensure by default . When DO CHECK is 0, check(expr) degrades to CA ASSUME(expr) and the expression is never evaluated; verify(expr) still evaluates it and only drops the halt. Automation Tests Test sources live in a Private/Tests folder of the module under test, or in a dedicated test module. Wrap each test file in if WITH DEV AUTOMATION TESTS (or WITH AUTOMATION TESTS = WITH DEV AUTOMATION TESTS WITH PERF AUTOMATION TESTS ) — the IMPLEMENT macros alone still compile the class, they only skip registration when WITH AUTOMATION WORKER is 0 ( Misc/AutomationTest.h:4366 ); UBT turns both on for every configuration except Test and Shipping, overridable with bForceCompileDevelopmentAutomationTests , bForceCompilePerformanceAutomationTests and bForceDisableAutomationTests ( UEBuildTarget.cs:6309 6325 ). Module and target wiring, the full pattern library and the command lines for running tests are in [references/automation test patterns.md](references/automation test patterns.md). IMPLEMENT COMPLEX AUTOMATION TEST adds virtual void GetTests(TArray<FString & OutBeautifiedNames, TArray<FString & OutTestCommands) const and runs RunTest once per entry. IMPLEMENT CUSTOM SIMPLE AUTOMATION TEST(TClass, TBaseClass, PrettyName, TFlags) declares a simple test whose base is a shared fixture you derive from FAutomationTestBase . Flags EAutomationTestFlags is an enum class with ENUM CLASS FLAGS , so combine with . Two static assert s enforce at least one context flag and exactly one filter flag . Group Values Context (≥1 required) EditorContext , ClientContext , ServerContext , CommandletContext , ProgramContext Filter (exactly 1) SmokeFilter , EngineFilter , ProductFilter , PerfFilter , StressFilter , NegativeFilter Priority CriticalPriority , HighPriority , MediumPriority , LowPriority Other NonNullRHI , RequiresUser , Disabled , SupportsAutoRTFM EAutomationTestFlags ApplicationContextMask covers every context flag in one token. Assertions inside a test The pattern is a regex unless you use the …Plain variants ( AddExpectedMessagePlain , AddExpectedErrorPlain ). AddExpectedError(Pattern, MatchType, Occurrences, bIsRegex) is the shorthand that matches warnings and errors (it forwards ELogVerbosity::Warning , which is inclusive); the AddExpectedMessage overload without a verbosity matches every severity. Latent commands RunTest returns before latent commands run. Enqueue them, then let Update() return true when the step is finished. Enqueuing after return true; is unreachable code. DEFINE LATENT AUTOMATION COMMAND through ... FIVE PARAMETER exist. To assert after the wait, derive from IAutomationLatentCommand and capture the FAutomationTestBase . Specs BEGIN DEFINE SPEC(TClass, PrettyName, TFlags) / member declarations / END DEFINE SPEC(TClass) declares a BDD style test whose body is void TClass::Define() . Inside Define() use Describe , It , LatentIt , BeforeEach , LatentBeforeEach , AfterEach (and xIt / xDescribe to disable a block). DEFINE SPEC(TClass, PrettyName, TFlags) replaces the pair when the spec needs no members. Worked example in [references/automation test patterns.md](references/automation test patterns.md). CQTest CQTest (module CQTest ) is the fixture based front end over the same framework. Assert is a FNoDiscardAsserter , so every assertion goes through ASSERT THAT , which returns from the method on failure. TEST CLASS(ClassName, TestDir) uses FNoDiscardAsserter and DefaultFlags ( EAutomationTestFlags ApplicationContextMask EAutomationTestFlags::ProductFilter ). Variants: TEST CLASS WITH FLAGS(ClassName, TestDir, Flags) , TEST CLASS WITH TAGS , TEST CLASS WITH BASE , TEST CLASS WITH ASSERTS . Lifecycle macros are BEFORE ALL() / AFTER ALL() (static, once per fixture) and BEFORE EACH() / AFTER EACH() (override Setup() / TearDown() ). Asserter helpers: IsTrue , IsFalse , IsNull , IsNotNull , AreEqual , AreNotEqual , AreEqualIgnoreCase , AreNotEqualIgnoreCase , IsNear(Expected, Actual, Epsilon) — each also takes a trailing failure message. World, actor and async helpers ( TestCommandBuilder , FSpawnHelper , FActorTestSpawner , FMapTestSpawner , TObjectBuilder , UTestGameInstance ) are covered in [references/automation test patterns.md](references/automation test patterns.md). Functional Tests AFunctionalTest (module FunctionalTesting ) is an actor placed in a test map. PrepareTest , StartTest , IsReady Implementation and OnTimeout are protected virtuals; FinishTest and the Assert helpers are public. Each override calls Super:: first. FinishTest(EFunctionalTestResult TestResult, const FString& Message) ends the run; EFunctionalTestResult is Default , Invalid , Error , Running , Failed , Succeeded , and Default lets the recorded assertions decide. Assertions are AssertTrue / AssertFalse ( bool Condition, const FString& Message, const UObject ContextObject = nullptr ), AssertIsValid(UObject , const FString&, const UObject = nullptr) , AssertEqual Int/Float/Bool/Name/Object/Vector/Rotator/Transform/Quat and AssertValue Int/Float/Double/DateTime (with an EComparisonMethod ). Also TimeLimit , PreparationTimeLimit , SetTimeLimit(float, EFunctionalTestResult) , LogMessage(const FString&) and StartStep / FinishStep . Full .cpp in [references/automation test patterns.md](references/automation test patterns.md). Run every functional test in the current world with the Blueprint node UFunctionalTestingManager::RunAllFunctionalTests(WorldContextObject, bNewLog, bRunLooped, FailedTestsReproString) (the class is MinimalAPI and the function is not FUNCTIONALTESTING API , so calling it from another module's C++ does not link), or from the command line: Automation also accepts List , RunTest , RunFilter <Filter , RunAll , SetFilter , SetPriority , SetMinimumPriority , Quit and SoftQuit ; chain them with ; . Profiling Full command tables, the CSV and LLM workflows and the bottleneck triage procedure are in [references/profiling commands.md](references/profiling commands.md). Unreal Insights Channel names drop the Channel suffix and lowercase: cpu , gpu , frame , bookmark , counters , log , loadtime , task , memalloc , callstack , module , metadata , net , rhicommands , rendercommands , slate , assetmetadata , iostore , animation , region , screenshot . Instrumenting code QUICK SCOPE CYCLE COUNTER(STAT MyAdHocScope) declares a stat inline for a one off measurement; TRACE INT VALUE(TEXT("MyGame/Spawned"), Count) and TRACE FLOAT VALUE emit a counter with no declaration; SCOPED NAMED EVENT TEXT("Name", FColor::Y