UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
LowLevelTestAdapter.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
5#if !WITH_LOW_LEVEL_TESTS
6
9#include <sstream>
10#include <vector>
11
19template<typename... ArgTypes>
21{
22 std::ostringstream Result;
23 auto Args = { InExpressionsValues... };
24 auto Iter = Args.begin();
25
27 FString Expression;
28 while (RemainingExpressions.Split(TEXT(","), &Expression, &RemainingExpressions))
29 {
30 if (Iter == Args.end())
31 {
32 break;
33 }
34 else if (Iter != Args.begin())
35 {
36 Result << ", ";
37 }
38 Result << std::string(TCHAR_TO_UTF8(*Expression.TrimStartAndEnd())) << " = " << *Iter++;
39 }
40
41 if (Iter != Args.end() && !RemainingExpressions.TrimStartAndEnd().IsEmpty())
42 {
43 Result << ", " << std::string(TCHAR_TO_UTF8(*RemainingExpressions)) << " = " << *Iter;
44 }
45
46 Result << std::endl;
47 return FString(Result.str().c_str());
48}
49
50
51#define IMPLEMENT_SIMPLE_AUTOMATION_TEST_PRIVATE_LLT( TClass, PrettyName, TFlagsOrTags, FileName, LineNumber ) \
52 class TClass : public FAutomationTestBase \
53 { \
54 public:\
55 TClass( const FString& InName) \
56 : FAutomationTestBase( InName, false ) \
57 { \
58 TestFlags = ExtractAutomationTestFlags(TFlagsOrTags); \
59 PrettyNameDotNotation = FString(PrettyName).Replace(TEXT("::"), TEXT(".")); \
60 if (!(TestFlags & EAutomationTestFlags_ApplicationContextMask)) \
61 { \
62 TestFlags |= EAutomationTestFlags_ApplicationContextMask; \
63 } \
64 if (!(TestFlags & EAutomationTestFlags_FilterMask)) \
65 { \
66 TestFlags |= EAutomationTestFlags::EngineFilter; \
67 } \
68 FAutomationTestFramework::Get().RegisterAutomationTestTags(GetBeautifiedTestName(), TFlagsOrTags); \
69 } \
70 virtual EAutomationTestFlags GetTestFlags() const override { return TestFlags; } \
71 virtual bool IsStressTest() const { return false; } \
72 virtual uint32 GetRequiredDeviceNum() const override { return 1; } \
73 virtual FString GetTestSourceFileName() const override { return FileName; } \
74 virtual int32 GetTestSourceFileLine() const override { return LineNumber; } \
75 protected: \
76 virtual void GetTests(TArray<FString>& OutBeautifiedNames, TArray <FString>& OutTestCommands) const override \
77 { \
78 OutBeautifiedNames.Add(PrettyNameDotNotation); \
79 OutTestCommands.Add(FString());\
80 } \
81 void TestBody(const FString& Parameters); \
82 virtual bool RunTest(const FString& Parameters) { \
83 TestBody(Parameters); \
84 return !HasAnyErrors(); \
85 } \
86 virtual FString GetBeautifiedTestName() const override { return PrettyNameDotNotation; } \
87 private:\
88 EAutomationTestFlags TestFlags; \
89 FString PrettyNameDotNotation; \
90 };
91
92#define LLT_JOIN(Prefix, Counter) LLT_JOIN_INNER(Prefix, Counter)
93#define LLT_JOIN_INNER(Prefix, Counter) Prefix##Counter
94
95#define TEST_CASE_NAMED_STR(TClass, StrName, PrettyName, TFlagsOrTags) \
96 IMPLEMENT_SIMPLE_AUTOMATION_TEST_PRIVATE_LLT(TClass, PrettyName, TFlagsOrTags, __FILE__, __LINE__) \
97 namespace \
98 { \
99 TClass LLT_JOIN(TClass, Instance)(TEXT(StrName)); \
100 } \
101 void TClass::TestBody(const FString& Parameters)
102
103
104#define TEST_CASE_GENERATED_NAME_UNIQUE LLT_JOIN(FLLTAdaptedTest, __COUNTER__)
105#define LLT_STR(Macro) #Macro
106#define LLT_STR_EXPAND(Macro) LLT_STR(Macro)
107#define TEST_CASE_GENERATED_NAME_UNIQUE_STR LLT_STR_EXPAND(TEST_CASE_GENERATED_NAME_UNIQUE)
108// Note: TEST_CASE uses unique names which only work when used inside unique namespace in the same compilation unit?// Use TEST_CASE_NAMED instead and provide an unique global instance name
109#define TEST_CASE(PrettyName, TFlagsOrTags) TEST_CASE_NAMED_STR(TEST_CASE_GENERATED_NAME_UNIQUE, TEST_CASE_GENERATED_NAME_UNIQUE_STR, PrettyName, TFlagsOrTags)
110#define TEST_CASE_NAMED(ClassName, PrettyName, TFlagsOrTags) TEST_CASE_NAMED_STR(ClassName, #ClassName, PrettyName, TFlagsOrTags)
111
112// Both python and oodle don't trust __LINE__ for unique names, and use __COUNTER__ where possible
113#ifdef __COUNTER__
114#define MAKE_UNIQUE_IDENT(str) LLT_JOIN(str, __COUNTER__)
115#else
116#define MAKE_UNIQUE_IDENT(str) LLT_JOIN(str, __LINE__)
117#endif
118
119// DISABLED_ makes a unique name for either a function or a lambda such that the linker should strip them.
120#define DISABLED_TEST_CASE(...) static void MAKE_UNIQUE_IDENT(disabled_test_()
121#define DISABLED_TEST_CASE_NAMED(ClassName, ...) static void MAKE_UNIQUE_IDENT(disabled_test_)()
122#define DISABLED_SCENARIO(...) static void MAKE_UNIQUE_IDENT(disabled_scenario_)()
123#define DISABLED_SECTION(...) auto MAKE_UNIQUE_IDENT(disabled_section_) = []()
124
125//-V:CHECK:571,501,547
126#define CHECK(...) if (!(__VA_ARGS__)) { FAutomationTestFramework::Get().GetCurrentTest()->AddError(TEXT("Condition failed")); }
127//-V:CHECK_FALSE:571,501,547
128#define CHECK_FALSE(...) if (!!(__VA_ARGS__)) { FAutomationTestFramework::Get().GetCurrentTest()->AddError(TEXT("Condition expected to return false but returned true")); }
129#define CHECKED_IF(...) if (!!(__VA_ARGS__))
130#define CHECKED_ELSE(...) if (!(__VA_ARGS__))
131//-V:CHECK_MESSAGE:571,501,547
132#define CHECK_MESSAGE(Message, ...) if (!(__VA_ARGS__)) { FAutomationTestFramework::Get().GetCurrentTest()->AddError(Message); }
133//-V:CHECK_FALSE_MESSAGE:571,501,547
134#define CHECK_FALSE_MESSAGE(Message, ...) if (!!(__VA_ARGS__)) { FAutomationTestFramework::Get().GetCurrentTest()->AddError(Message); }
135//-V:REQUIRE:571,501,547
136#define REQUIRE(...) if (!(__VA_ARGS__)) { FAutomationTestFramework::Get().GetCurrentTest()->AddError(TEXT("Required condition failed, interrupting test")); return; }
137//-V:REQUIRE_MESSAGE:571,501,547
138#define REQUIRE_MESSAGE(Message, ...) if (!(__VA_ARGS__)) { FAutomationTestFramework::Get().GetCurrentTest()->AddError(Message); return; }
139#define STATIC_REQUIRE(...) static_assert(__VA_ARGS__, #__VA_ARGS__);
140#define STATIC_CHECK(...) static_assert(__VA_ARGS__, #__VA_ARGS__);
141#define STATIC_CHECK_FALSE(...) static_assert(!(__VA_ARGS__), "!(" #__VA_ARGS__ ")");
142
143#define CHECK_EQUALS(What, X, Y) FAutomationTestFramework::Get().GetCurrentTest()->TestEqual(What, X, Y);
144#define CHECK_EQUALS_SENSITIVE(What, X, Y) FAutomationTestFramework::Get().GetCurrentTest()->TestEqualSensitive(What, X, Y);
145#define CHECK_NOT_EQUALS(What, X, Y) FAutomationTestFramework::Get().GetCurrentTest()->TestNotEqual(What, X, Y);
146#define CHECK_NOT_EQUALS_SENSITIVE(What, X, Y) FAutomationTestFramework::Get().GetCurrentTest()->TestNotEqualSensitive(What, X, Y);
147
148#define SECTION(Text) FAutomationTestFramework::Get().GetCurrentTest()->AddInfo(TEXT(Text));
149#define FAIL_CHECK(Message) FAutomationTestFramework::Get().GetCurrentTest()->AddError(Message);
150
151#define CAPTURE(...) FAutomationTestFramework::Get().GetCurrentTest()->AddInfo(CaptureExpressionsAndValues(#__VA_ARGS__, __VA_ARGS__));
152#define INFO(Message) FAutomationTestFramework::Get().GetCurrentTest()->AddInfo(Message);
153#define WARN(Message) FAutomationTestFramework::Get().GetCurrentTest()->AddWarning(Message);
154#define ADD_WARNING(Message) FAutomationTestFramework::Get().GetCurrentTest()->AddWarning(Message);
155#define ADD_ERROR(Message) FAutomationTestFramework::Get().GetCurrentTest()->AddError(Message);
156#define FAIL_ON_MESSAGE(Message) FAutomationTestFramework::Get().GetCurrentTest()->AddExpectedError(Message);
157
158
159#define SKIP(Message)
160
161#endif // !WITH_LOW_LEVEL_TESTS
#define TEXT(x)
Definition Platform.h:1272
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
FString CaptureExpressionsAndValues(const FString &InExpressions, ArgTypes &&... InExpressionsValues)
Captures expressions and their evaluated values. Internal use only for the low level tests adapter.
Definition LowLevelTestAdapter.h:20
#define TCHAR_TO_UTF8(str)
Definition StringConv.h:1021
UE_FORCEINLINE_HINT DataType::RangedForIteratorType begin()
Definition UnrealString.h.inl:301