You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
157 lines
11 KiB
Plaintext
157 lines
11 KiB
Plaintext
INTSourceChangelist:3656883
|
|
Availability:Public
|
|
Title:自動化に関するテクニカルガイド
|
|
Crumbs: %ROOT%
|
|
Description:エンジン レベルの自動化テストを作成するためのプログラマー向けガイド
|
|
type:overview
|
|
skilllevel:Advanced
|
|
Version:4.17
|
|
parent:Programming/Automation
|
|
order:1
|
|
tags:Automation
|
|
tags:Testing
|
|
|
|
[TOC (start:2 end:3)]
|
|
|
|
## 自動化テスト
|
|
|
|
**Automation Testing (自動化テスト)** は、自動化テストの最低レベルのテストで、エンジンのコア機能の低レベル テストに最適です。このシステムは、`UObject` エコシステムの外部にあり、**ブループリント** やエンジンの **リフレクション システム** からは見えません。こうしたテストはビルトインのコードで、**コンソールのコマンドライン** から、エディタ内で、またはオペレーティング システムのコマンドライン パラメータで実行することができます。自動化テストは、簡易テストと複合テストの二通りがあります。両方とも、`FAutomationTestBase` をベースにした派生クラスとして実装されます。
|
|
|
|
### 新規自動化テストの作成
|
|
|
|
自動化テストはマクロによって宣言され、`FAutomationTestBase` クラスから仮想関数をオーバーライドすることで実装されます。簡易テストは `IMPLEMENT_SIMPLE_AUTOMATION_TEST` マクロを使用して宣言します。一方、複合テストでは、`IMPLEMENT_COMPLEX_AUTOMATION_TEST` マクロが必要になります。これらのマクロは両方とも以下の順序の同じ 3 つのマクロを特徴とします。
|
|
|
|
| パラメータ | 説明 |
|
|
| --------- | ----------- |
|
|
| `TClass` | テストのクラス名です。マクロは、この名前のクラス、例えば、テストを実装できる `FPlaceholderTest` といったクラスを作成します。 |
|
|
| `PrettyName` | UI に表示される階層的なテストの名前を指定した文字列です。例えば、最小限の例の "TestGroup.TestSubgroup.Placeholder Test" です (以下)。 |
|
|
| `TFlags` | `EAutomationTestFlags` 値の組み合わせであり、自動化テストの要件と挙動を指定するために使われます。詳細については、[`EAutomationTestFlags` API Page](API:EAutomationTestFlags) をご覧ください。 |
|
|
|
|
新規 Automation Test クラスが以下の 2 つのマクロのひとつによって宣言されたら、その機能を実装することができます。以下の関数を記述しなければなりません。
|
|
|
|
| 関数 | パラメータ | 説明 |
|
|
| --- | --- | --- |
|
|
| `RunTest` | | 実際のテストを行い、テストに合格すると `true` を戻し、失敗すると `false` を戻します。 |
|
|
| | `Parameters` | 特定の機能テストのためにパースされるか、必要に応じて他の関数に渡されます。 |
|
|
| --- | --- | --- |
|
|
| `GetTests` | | 複合テストに限りオーバーライドされなくてはなりません。簡易テストの場合は、この関数の自動生成バージョンが宣言用マクロに組み込まれています。 |
|
|
| | `OutBeautifiedNames` | この文字列には、UI に表示される各テストの `PrettyName` が入ります。 |
|
|
| | `OutTestCommands` | この文字列は、`OutBeautifiedNames` と並列し、`RunTest` に渡される `Parameters` が入ります。 |
|
|
|
|
#### ソース ファイルの場所
|
|
|
|
現在の決まりでは、全ての自動化テストは、関連モジュール内の `Private\Tests` ディレクトリに入ります。自動化テストが特定クラスと一対一で一致した時、テストファイル名を `[ClassFilename]Test.cpp` としてください。例えば、`FText` だけに適用されるテストは、`TextTest.cpp` になります。
|
|
|
|
#### 最小限の例
|
|
|
|
可能な限り、最小限かつ単純なテストは、簡易テストであり、自動的に合格 (または不合格) になります。このようなテストのビルドは、さらに重要なテストをビルドする前に、セットアップを確実に正しいものにする最初のステップとして役立ちます。
|
|
|
|
IMPLEMENT_SIMPLE_AUTOMATION_TEST(FPlaceholderTest, "TestGroup.TestSubgroup.Placeholder Test", EAutomationTestFlags::EditorContext | EAutomationTestFlags::EngineFilter)
|
|
|
|
bool FPlaceholderTest::RunTest(const FString& Parameters)
|
|
{
|
|
// Make the test pass by returning true, or fail by returning false.
|
|
return true;
|
|
}
|
|
|
|
### 簡易テスト
|
|
|
|
簡易テストは、単一のアトミックなテストを表し、ユニット テストまたは機能テストとして便利です。例えば、簡易テストは現在のマップが Play In Editor (PIE) にロードされるか、テキストのラッピングがスレートで正しく機能しているかをテストするために使用することができます。以下の例では、`SetRes` コマンドの機能をテストしています。
|
|
|
|
IMPLEMENT_SIMPLE_AUTOMATION_TEST( FSetResTest, "Windows.SetResolution", ATF_Game )
|
|
|
|
bool FSetResTest::RunTest(const FString& Parameters)
|
|
{
|
|
FString MapName = TEXT("AutomationTest");
|
|
FEngineAutomationTestUtilities::LoadMap(MapName);
|
|
|
|
int32 ResX = GSystemSettings.ResX;
|
|
int32 ResY = GSystemSettings.ResY;
|
|
FString RestoreResolutionString = FString::Printf(TEXT("setres \%dx\%d"), ResX, ResY);
|
|
|
|
ADD_LATENT_AUTOMATION_COMMAND(FEngineWaitLatentCommand(2.0f));
|
|
ADD_LATENT_AUTOMATION_COMMAND(FExecStringLatentCommand(TEXT("setres 640x480")));
|
|
ADD_LATENT_AUTOMATION_COMMAND(FEngineWaitLatentCommand(2.0f));
|
|
ADD_LATENT_AUTOMATION_COMMAND(FExecStringLatentCommand(RestoreResolutionString));
|
|
|
|
return true;
|
|
}
|
|
|
|
### 複合テスト
|
|
|
|
複合テストは、同じコードを複数の入力に対して実行します。これは通常はコンテンツ負荷テストです。例えば、すべてのマップのロードやすべてのブループリントのコンパイルは、複合自動化テストに適しています。`RunTest` 関数と `GetTests` 関数は両方ともオーバーライドされなければなりません。以下のサンプルは、すべてのプロジェクト マップのロードをテストします。
|
|
|
|
IMPLEMENT_COMPLEX_AUTOMATION_TEST(FLoadAllMapsInGameTest, "Maps.LoadAllInGame", ATF_Game)
|
|
|
|
void FLoadAllMapsInGameTest::GetTests(TArray<FString>& OutBeautifiedNames, TArray <FString>& OutTestCommands) const
|
|
{
|
|
FEngineAutomationTestUtilities Utils;
|
|
TArray<FString> FileList;
|
|
FileList = GPackageFileCache->GetPackageFileList();
|
|
|
|
// Iterate over all files, adding the ones with the map extension..
|
|
for( int32 FileIndex=0; FileIndex< FileList.Num(); FileIndex++ )
|
|
{
|
|
const FString& Filename = FileList[FileIndex];
|
|
|
|
// Disregard filenames that don't have the map extension if we're in MAPSONLY mode.
|
|
if ( FPaths::GetExtension(Filename, true) == FPackageName::GetMapPackageExtension() )
|
|
{
|
|
if (!Utils.ShouldExcludeDueToPath(Filename))
|
|
{
|
|
OutBeautifiedNames.Add(FPaths::GetBaseFilename(Filename));
|
|
OutTestCommands.Add(Filename);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
bool FLoadAllMapsInGameTest::RunTest(const FString& Parameters)
|
|
{
|
|
FString MapName = Parameters;
|
|
|
|
FEngineAutomationTestUtilities::LoadMap(MapName);
|
|
ADD_LATENT_AUTOMATION_COMMAND(FEnqueuePerformanceCaptureCommands());
|
|
|
|
return true;
|
|
}
|
|
|
|
[REGION:tip]特定のテスト状況に応じたやり方で、`Parameters` 引数をビルドしてパースすることができます。複合テストの場合、いくつかのデータ ポイントを同じコードを使ってテストするために使う方法です。[/REGION]
|
|
|
|
### Latent コマンド
|
|
|
|
**Latent (潜在) コマンド** を `RunTest` 中に待ち行列に入れて、コードのセクションを複数のフレームで実行することができます。Latent Action を作成するには、`DEFINE_LATENT_AUTOMATION_COMMAND` マクロで定義しなければなりません。このマクロは、`CommandName` というパラメータをとります。これは、この種の Latent コマンドで作成されるクラス名を定義します。Latent コマンドの作成を完了するには、その新規クラスで `Update` 関数の関数ボディを必要とします。以下はシンプルな Latent コマンドの例です。**Unit Test Manager** がテスト実行を終了するまで実行します。
|
|
|
|
DEFINE_LATENT_AUTOMATION_COMMAND(FNUTWaitForUnitTests);
|
|
|
|
bool FNUTWaitForUnitTests::Update()
|
|
{
|
|
return GUnitTestManager == NULL || !GUnitTestManager->IsRunningUnitTests();
|
|
}
|
|
|
|
作成する Latent コマンドがパラメータ文字列などの引数を必要とする場合、`DEFINE_LATENT_AUTOMATION_COMMAND` マクロを使用することができます。このマクロはさらに 2 つのパラメータをとります。`ParamType` と `ParamName` で、それぞれ渡すパラメータのタイプと名前を定義します。この例では、Latent コマンドを使ってソース コントロール プロバイダーへの接続を開始し、接続の試みが終了するまで待機します。
|
|
|
|
DEFINE_LATENT_AUTOMATION_COMMAND_ONE_PARAMETER(FConnectLatentCommand, SourceControlAutomationCommon::FAsyncCommandHelper, AsyncHelper);
|
|
|
|
bool FConnectLatentCommand::Update()
|
|
{
|
|
// Attempt a login and wait for the result.
|
|
if(!AsyncHelper.IsDispatched())
|
|
{
|
|
if(ISourceControlModule::Get().GetProvider().Login( FString(), EConcurrency::Asynchronous, FSourceControlOperationComplete::CreateRaw( &AsyncHelper, &SourceControlAutomationCommon::FAsyncCommandHelper::SourceControlOperationComplete ) ) != ECommandResult::Succeeded)
|
|
{
|
|
return false;
|
|
}
|
|
AsyncHelper.SetDispatched();
|
|
}
|
|
|
|
return AsyncHelper.IsDone();
|
|
}
|
|
|
|
`Update` 関数が `true` を戻すと、Latent コマンドが完了したと考えられます。戻り値が `false` の場合、自動化テストはただちに実行を停止し、次のフレームで再度実行を試みます。テスト コードで Latent コマンドを使用するには、実行する Latent コマンドのコンストラクタで `ADD_LATENT_AUTOMATION_COMMAND` を呼び出します。Latent コマンドでパラメータを設定したら、その値を、パラメータがコンストラクタの引数として取る値として渡します。`RunTest` 関数で、以下のコードはすべてのユニット テストが終わるまで待機し、以前名前を付けたソース コントロール プロバイダに接続しようとします。
|
|
|
|
ADD_LATENT_AUTOMATION_COMMAND(FNUTWaitForUnitTests());
|
|
ADD_LATENT_AUTOMATION_COMMAND(FConnectLatentCommand(SourceControlAutomationCommon::FAsyncCommandHelper()));
|
|
|
|
[REGION:note]データのロードやストリーミングに関する動作や、単一フレームで実行できる保証がないものは、Latent コマンドを使用する対象になります。例えば、エディタではマップのロードはただちに起こりますが、ゲームではマップのロードは次のフレームで起こります。従って、自動化テストでマップのロードが必要な場合、Latent コマンドを使って確実に一貫性のある挙動になるようにします。[/REGION]
|