[UE4] ビルドコンフィギュレーション Test構成とは

 検証Ver:4.25.0

# ビルドコンフィギュレーションとは
　アプリケーションのパッケージを作成する時や、Visual Studioからアプリケーションの構成を選択する時に見る「ビルドコンフィギュレーション」ですが、これはアプリケーションのビルド構成の1つです。この構成は5種類(`Debug`, `DebugGame`, `Development`, `Test`, `Shipping`)に分類されていますが、それぞれアプリケーションに含めるコードを切り替えたり、項目をスイッチしたい場合に利用されます。詳細についてはドキュメント[「ビルド コンフィギュレーションのリファレンス」](https://docs.unrealengine.com/ja/Programming/Development/BuildConfigurations/index.html)をご覧ください。

　アプリケーションパッケージを作成する場合は、`Packaging Project`から指定することが出来ます。
![2020-06-12_16h44_51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101019/a6199ba4-35f3-fcbe-a904-84ee9422eeec.png)

　Visual Studioからビルドする場合は、`Solution Configuralions`から指定することが出来ます。
![2020-06-12_19h29_55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101019/96241618-ce08-a268-9a02-4a533f9afda4.png)

# Test構成とは
　Test構成はビルド構成の1つです。DebugやRelease(Shipping)といった構成はUE4以外のサンプルなどでも見かけることがありますが、TestはUE4独自のソリューション構成の1つです。ドキュメントには**「このコンフィギュレーションは、Shipping コンフィギュレーションですが、一部のコンソール コマンド、統計情報、プロファイリング ツールが有効になっています。」**と記載されています。

　ビルド構成は5種類(`Debug`, `DebugGame`, `Development`, `Test`, `Shipping`)に分類されていますが、Debugに近いほどデバッグに特化しており、Shppingに近いほど出荷状態に特化した構成となっているので、Testはどちらかといえば出荷状態に近い構成となっています。

# なぜTest構成があるか
　パフォーマンス計測用として用意されています。出荷状態に近い状態として、デバッグ用のコードは殆ど取り除かれているためデバッグの目的としては適していません。例えばTest構成ではログを出力しないかったり、利用可能なコンソールコマンドが限られているので、デバッグを行う上で利用する機能が取り除かれています。その代わり、コードが最適化されて出荷状態に近い状態となっているため、パフォーマンスが出やすい状態になっています。

　このShippingに近い状態のパフォーマンスを計測することで、最終的にパフォーマンスをどこまで最適化するかをコントロールします。例えばDevelopmentでCPUの負荷計測を行った場合、Developmentにはデバッグ用のコードなども含まれるため計測環境としては最適ではありません。デバッグ用コードが最終的にTestやShippingで取り除かれるものであれば、それがノイズとして負荷の1つに追加されるためです。極力出荷状態に近い構成で計測することで、不必要な最適化を控えてクオリティとパフォーマンスの調整することができます。

# Test構成が最適とは限らない
　パフォーマンス計測はTest構成で行う方が良いと述べましたが、これはCPUの負荷計測[^1]や、GCのコストを計測するケース[^2]に限って言えばそうです。以下に挙げるような、Test構成ではなくDevelopmentを用いた方が良いケースもあります。これらはTest構成による恩恵を殆ど受けないため、Developmentでの計測で許容できるものと認識しています。

**・GPUパフォーマンス計測**
　シーン中のDrawEventをキャプチャに含めるためのコンソールコマンド`ToggleDrawEvents`がTest構成では無効となるためDevelopmentを使用します。

**・メモリ使用量の計測**
　[LLM](https://docs.unrealengine.com/ja/Programming/Development/Tools/LowLevelMemoryTracker/index.html)がTest構成では無効となるためDevelopmentを使用します。

# Test構成で"できること"と"できないこと"
　これを1つ1つ列挙するのは（本当に）膨大な作業なのでここでは記載しませんが、基本的にはShipping同様にデバッグ機能は殆どが除外されて利用できないものという認識でよいかと思います。以下、大まかな利用制限事項について記載しています。

**利用可なコンソールコマンド**
・stat unit, stat levels, stat fps などの一部のstatコマンド
・open, travel, log, r.xxx, a.xxx, t.xxx, gc.xxx など

**Test構成で利用可能な機能**
・UnrealInsights

**利用不可のコンソールコマンド**
・stat collision, stat startfile/stopfile などの一部のstatコマンド
・showflag, obj, memreport などの一連のコマンド
・shot/hiresshot, toggledrawevents, profilegpu など

**Test構成で制限される機能**
・デバッグ用として用意されたコンソールコマンド全般は利用不可
・DrawDebugXXX系のデバッグコードは殆どのケースで除外
・check()コードは除外
・ログ出力の抑制
・LLM, CSV計測, memory profile関連等

# コード上で探す場合は
　Test構成で有効な処理やコードは以下のdefine定義で記載されています。

```:
UE_BUILD_TEST
```
　DevelopやDebugで利用可能な機能(Test,Shippingで抑制したい機能)は以下の定義を使用しています。

```:
#if !(UE_BUILD_SHIPPING || UE_BUILD_TEST)
```
　Shipping構成でのみ除外したい場合は以下のdefine定義で記載されています。

```:
#if !UE_BUILD_SHIPPING
```
　例えば以下のように記述されている箇所はTest/Shippingでは制限されるものです。もし利用したい機能が制限されているかどうかを知らべたい場合は、これらの定義を参考に探してみると良いかと思います。 

```cpp:AvoidanceManager.cpp
bool UAvoidanceManager::Exec(UWorld* Inworld, const TCHAR* Cmd, FOutputDevice& Ar)
{
#if !(UE_BUILD_SHIPPING || UE_BUILD_TEST)
	if (FParse::Command(&Cmd, TEXT("AvoidanceDisplayAll")))
	{
		HandleToggleDebugAll( Cmd, Ar );
	}
	else if (FParse::Command(&Cmd, TEXT("AvoidanceSystemToggle")))
	{
		HandleToggleAvoidance( Cmd, Ar );
		return true;
	}
#endif

	return false;
}
```



[^1]: 参照：[UE4で多数のキャラクターを生かすためのテクニック](https://www.slideshare.net/EpicGamesJapan/cedec2018-ue4-111105729/25) 
[^2]: 参照：[UE4におけるLoadingとGCのProfilingと最適化手法](https://www.slideshare.net/EpicGamesJapan/ue4loadinggcprofiling/38)