撰寫和執行測試 — MRTK2
為了確保 MRTK 可靠,MRTK 有一組測試,以確保程式碼的變更不會回歸現有的行為。 在 MRTK 之類的大型程式碼基底中擁有良好的測試涵蓋範圍,對於穩定性和在進行變更時擁有信心非常重要。
MRTK 使用 Unity 測試執行器 ,其使用 NUnit的 Unity 整合。 本指南將提供如何將測試新增至 MRTK 的起點。 它不會說明可在提供的連結中查閱 的 Unity 測試執行器和NUnit 。
提交提取要求之前,請務必:
在本機執行測試,讓您的變更不會在完成 PR (傳回現有的行為,如果有任何測試失敗,則不允許) 。
如果修正錯誤,請撰寫測試來測試修正,並確保未來的程式碼修改不會再次中斷。
如果撰寫功能,請撰寫新的測試,以防止即將發生的程式碼變更中斷此功能。
目前 playmode 測試是要在 Unity 2018.4 中執行,而且在其他版本的 Unity 中可能會失敗
執行測試
Unity 編輯器
Unity 測試執行器可以在[視窗>一般>測試執行器] 底下找到,並顯示所有可用的 MRTK 播放和編輯模式測試。
命令列
測試也可以由位於 Scripts\test\run_playmode_tests.ps1
的Powershell腳本執行。 這會執行 playmode 測試,就像是在 github / CI 上執行一樣, (請參閱下列) 和列印結果。 以下是如何執行腳本的一些範例
在位於 H:\mrtk.dev 的專案上執行測試,例如 Unity 2018.4.4 (,例如 Unity 2018.4.26f1)
.\run_playmode_tests.ps1 H:\mrtk.dev -unityExePath "C:\Program Files\Unity\Hub\Editor\2018.4.26f1\Editor\Unity.exe"
在位於 H:\mrtk.dev 的專案上執行測試,使用 Unity 2018.4 將結果輸出至 C:\playmode_test_out
.\run_playmode_tests.ps1 H:\mrtk.dev -unityExePath "C:\Program Files\Unity\Hub\Editor\2018.4.26f1\Editor\Unity.exe" -outFolder "C:\playmode_test_out\"
您也可以透過 run_repeat_tests.ps1
腳本多次執行 Playmode 測試。 中所使用的 run_playmode_tests.ps1
所有參數都可以使用。
.\run_repeat_tests.ps1 -Times 5
提取要求驗證
MRTK 的 CI 將會在所有設定中建置 MRTK,並執行所有編輯和播放模式測試。 如果使用者有足夠的許可權,可以在 github PR /azp run mrtk_pr
上張貼批註來觸發 CI。 您可以在 PR 的 [檢查] 索引標籤中看到 CI 執行。
只有在成功通過所有測試之後,PR 才會合並成 main。
壓力測試/大量測試
有時候,測試偶爾只會失敗,而這可能會令人感到不小心偵錯。
若要在本機執行多個測試,請修改據以測試腳本。 下列 Python 腳本應該讓此案例更方便。
執行 Python 腳本的必要條件是 安裝 Python 3.X。
針對需要多次執行的單一測試:
[UnityTest]
public IEnumerator MyTest() {...}
建議從命令列 (PowerShell 執行下列命令)
cd scripts\tests
# Repeat the test 5 times. Default is 100
python .\generate_repeat_tests.py -n 5 -t MyTest
將輸出複製並貼到測試檔案中。 下列腳本適用于依序執行多個測試:
cd scripts\tests
# Repeat the test 5 times. Default is 100
python .\generate_repeat_tests.py -n 5 -t MyTest MySecondTest
新的測試檔案現在應該包含
[UnityTest]
public IEnumerator A1MyTest0(){ yield return MyTest();}
[UnityTest]
public IEnumerator A2MyTest0(){ yield return MyTest();}
[UnityTest]
public IEnumerator A3MyTest0(){ yield return MyTest();}
[UnityTest]
public IEnumerator A4MyTest0(){ yield return MyTest();}
[UnityTest]
public IEnumerator MyTest() {...}
開啟測試執行器,並觀察現在可以重複呼叫的新測試。
編寫測試
有兩種類型的測試可以針對新程式碼新增
- 播放模式測試
- 編輯模式測試
播放模式測試
MRTK 播放模式測試能夠測試新功能如何回應不同的輸入來源,例如手部或眼睛。
新的播放模式測試可以繼承 BasePlayModeTests ,或使用下列基本架構。
若要建立新的播放模式測試:
- 流覽至 > 資產 MRTK > 測試 > PlayModeTests
- 以滑鼠右鍵按一下 [建立 > 測試 > C# 測試腳本]
- 以下列基本架構取代預設範本
#if !WINDOWS_UWP
// When the .NET scripting backend is enabled and C# projects are built
// The assembly that this file is part of is still built for the player,
// even though the assembly itself is marked as a test assembly (this is not
// expected because test assemblies should not be included in player builds).
// Because the .NET backend is deprecated in 2018 and removed in 2019 and this
// issue will likely persist for 2018, this issue is worked around by wrapping all
// play mode tests in this check.
using Microsoft.MixedReality.Toolkit.Input;
using Microsoft.MixedReality.Toolkit.Utilities;
using NUnit.Framework;
using System;
using System.Collections;
using System.Linq;
using UnityEngine;
using UnityEngine.TestTools;
namespace Microsoft.MixedReality.Toolkit.Tests
{
class ExamplePlayModeTests
{
// This method is called once before we enter play mode and execute any of the tests
// do any kind of setup here that can't be done in playmode
public void Setup()
{
// eg installing unity packages is only possible in edit mode
// so if a test requires TextMeshPro we will need to check for the package before entering play mode
PlayModeTestUtilities.InstallTextMeshProEssentials();
}
// Do common setup for each of your tests here - this will be called for each individual test after entering playmode
// Note that this uses UnitySetUp instead of [SetUp] because the init function needs to await a frame passing
// to ensure that the MRTK system has had the chance to fully set up before the test runs.
[UnitySetUp]
public IEnumerator Init()
{
// in most play mode test cases you would want to at least create an MRTK GameObject using the default profile
TestUtilities.InitializeMixedRealityToolkit(true);
yield return null;
}
// Destroy the scene - this method is called after each test listed below has completed
// Note that this uses UnityTearDown instead of [TearDown] because the init function needs to await a frame passing
// to ensure that the MRTK system has fully torn down before the next test setup->run cycle starts.
[UnityTearDown]
public IEnumerator TearDown()
{
PlayModeTestUtilities.TearDown();
yield return null;
}
#region Tests
/// <summary>
/// Skeleton for a new MRTK play mode test.
/// </summary>
[UnityTest]
public IEnumerator TestMyFeature()
{
// ----------------------------------------------------------
// EXAMPLE PLAY MODE TEST METHODS
// ----------------------------------------------------------
// Getting the input system
// var inputSystem = PlayModeTestUtilities.GetInputSystem();
// Creating a new test hand for input
// var rightHand = new TestHand(Handedness.Right);
// yield return rightHand.Show(new Vector3(0, 0, 0.5f));
// Moving the new test hand
// We are doing a yield return here because moving the hand to a new position
// requires multiple frames to complete the action.
// yield return rightHand.MoveTo(new Vector3(0, 0, 2.0f));
// Getting a specific pointer from the hand
// var linePointer = PointerUtils.GetPointer<LinePointer>(Handedness.Right);
// Assert.IsNotNull(linePointer);
// ---------------------------------------------------------
// Your new test here
yield return null;
}
#endregion
}
}
#endif
編輯模式測試
編輯模式測試是在 Unity 的編輯模式中執行,而且可以在 Mixed Reality Toolkit 存放庫中的MRTK>測試>EditModeTests資料夾下新增。 若要建立新的測試,可以使用下列範本:
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
using NUnit.Framework;
namespace Microsoft.MixedReality.Toolkit.Tests
{
class EditModeExampleTest
{
[Test]
/// the name of this method will be used as test name in the unity test runner
public void TestEditModeExampleFeature()
{
}
}
}
測試命名慣例
測試通常應該根據其正在測試的類別或正在測試的案例來命名。 例如,假設有待測試類別:
namespace Microsoft.MixedReality.Toolkit.Input
{
class InterestingInputClass
{
}
}
請考慮命名測試
namespace Microsoft.MixedReality.Toolkit.Tests.Input
{
class InterestingInputClassTest
{
}
}
請考慮將測試放在類似于其對應非測試檔案的資料夾階層中。 例如:
Non-Test: Assets/MRTK/Core/Utilities/InterestingUtilityClass.cs
Test: Assets/MRTK/Tests/EditModeTests/Core/Utilities/InterestingUtilityClassTest.cs
這是為了確保在這類測試類別存在時,找出每個類別的對應測試類別有清楚的方法。
案例型測試的位置較不定義 - 如果測試練習整體輸入系統,例如,請考慮將它放入對應的編輯模式或播放模式測試檔案夾中的 「InputSystem」 資料夾。
測試腳本圖示
新增測試時,請修改腳本以擁有正確的 MRTK 圖示。 有一個簡單的 MRTK 工具可以這麼做:
- 移至 [Mixed Reality工具組] 功能表項目。
- 按一下 [公用程式],然後按一下 [更新],然後按一下 [圖示]。
- 按一下 [測試],更新程式會自動執行,並更新遺漏其圖示的任何測試腳本。
MRTK 公用程式方法
本節說明撰寫 MRTK 測試時的一些常用程式碼片段/方法。
有兩個公用程式類別可協助設定 MRTK,並測試與 MRTK 中的元件互動
TestUtilities 提供下列方法來設定 MRTK 場景和 GameObjects:
/// creates the mrtk GameObject and sets the default profile if passed param is true
TestUtilities.InitializeMixedRealityToolkit()
/// creates an empty scene prior to adding the mrtk GameObject to it
TestUtilities.InitializeMixedRealityToolkitAndCreateScenes();
/// sets the initial playspace transform and camera position
TestUtilities.InitializePlayspace();
/// destroys previously created mrtk GameObject and playspace
TestUtilities.ShutdownMixedRealityToolkit();
請參閱 和 PlayModeTestUtilities
的 TestUtilities
API 檔,以取得這些公用程式類別的進一步方法,因為它們會定期擴充,同時將新的測試新增至 MRTK。