Schreiben und Ausführen von Tests – MRTK2

Um sicherzustellen, dass MRTK zuverlässig ist, verfügt MRTK über eine Reihe von Tests, um sicherzustellen, dass Änderungen am Code nicht das vorhandene Verhalten zurücknehmen. Eine gute Testabdeckung in einer großen Codebasis wie MRTK ist entscheidend für Stabilität und Vertrauen bei Änderungen.

MRTK verwendet den Unity Test Runner , der eine Unity-Integration von NUnit verwendet. Dieser Leitfaden bietet einen Ausgangspunkt zum Hinzufügen von Tests zu MRTK. Der Unity Test Runner und die NUnit , die in den bereitgestellten Links gesucht werden können, werden nicht erläutert.

Stellen Sie vor dem Übermitteln eines Pull Requests Folgendes sicher:

  1. Führen Sie die Tests lokal aus, damit Ihre Änderungen das vorhandene Verhalten nicht zurücknehmen (das Abschließen von PRs ist nicht zulässig, wenn Tests fehlschlagen).

  2. Wenn Sie einen Fehler beheben, schreiben Sie einen Test, um den Fix zu testen und sicherzustellen, dass zukünftige Codeänderungen ihn nicht erneut unterbrechen.

  3. Wenn Sie ein Feature schreiben, schreiben Sie neue Tests, um zu verhindern, dass anstehende Codeänderungen dieses Feature unterbrechen.

Derzeit sind Playmode-Tests für die Ausführung in Unity 2018.4 vorgesehen und können in anderen Versionen von Unity fehlschlagen.

Ausführen von Tests

Unity-Editor

Der Unity-Test Runner befindet sich unter Windows>General>Test Runner und zeigt alle verfügbaren MRTK-Play- und Edit-Modus-Tests an.

Befehlszeile

Tests können auch von einem PowerShell-Skript ausgeführt werden, das sich unter Scripts\test\run_playmode_tests.ps1befindet. Dadurch werden die Playmode-Tests genau so ausgeführt, wie sie auf GitHub/CI ausgeführt werden (siehe unten), und die Ergebnisse werden ausgegeben. Hier sind einige Beispiele für die Ausführung des Skripts

Führen Sie die Tests für das Projekt unter H:\mrtk.dev mit Unity 2018.4 (z. B. Unity 2018.4.26f1) aus.

.\run_playmode_tests.ps1 H:\mrtk.dev -unityExePath "C:\Program Files\Unity\Hub\Editor\2018.4.26f1\Editor\Unity.exe"

Führen Sie die Tests für das Projekt unter H:\mrtk.dev aus, wobei Unity 2018.4 die Ergebnisse an 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\"

Es ist auch möglich, die Playmode-Tests mehrmals über das run_repeat_tests.ps1 Skript auszuführen. Alle Parameter, die in run_playmode_tests.ps1 verwendet werden, können verwendet werden.

.\run_repeat_tests.ps1 -Times 5

Pull Request-Überprüfung

Die MRTK-CI erstellt MRTK in allen Konfigurationen und führt alle Tests im Bearbeitungs- und Wiedergabemodus aus. CI kann ausgelöst werden, indem ein Kommentar auf dem GitHub-PR /azp run mrtk_pr gepostet wird, wenn der Benutzer über ausreichende Rechte verfügt. CI-Ausführungen können auf der Registerkarte "Checks" des PR angezeigt werden.

Erst wenn alle Tests erfolgreich bestanden wurden, kann der PR in Standard zusammengeführt werden.

Belastungstests/Massentests

Manchmal schlagen Tests nur gelegentlich fehl, was beim Debuggen frustrierend sein kann.

Um mehrere Testläufe lokal auszuführen, ändern Sie die jeweiligen Testskripts. Das folgende Python-Skript sollte dieses Szenario komfortabler machen.

Voraussetzung für die Ausführung des Python-Skripts ist die Installation von Python 3.X.

Für einen einzelnen Test, der mehrmals ausgeführt werden muss:

[UnityTest]
public IEnumerator MyTest() {...}

Führen Sie folgendes über eine Befehlszeile aus (PowerShell wird empfohlen)

cd scripts\tests
# Repeat the test 5 times. Default is 100
python .\generate_repeat_tests.py -n 5 -t MyTest

Kopieren Sie die Ausgabe, und fügen Sie sie in Die Testdatei ein. Das folgende Skript dient zum Ausführen mehrerer Tests nacheinander:

cd scripts\tests
# Repeat the test 5 times. Default is 100
python .\generate_repeat_tests.py -n 5 -t MyTest MySecondTest

Die neue Testdatei sollte jetzt enthalten.

[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() {...}

Öffnen Sie den Testrunner, und beobachten Sie die neuen Tests, die jetzt wiederholt aufgerufen werden können.

Schreiben von Tests

Es gibt zwei Arten von Tests, die für neuen Code hinzugefügt werden können.

  • Tests im Wiedergabemodus
  • Bearbeiten von Tests im Bearbeitungsmodus

Tests im Wiedergabemodus

MRTK-Wiedergabemodus-Tests können testen, wie Ihr neues Feature auf verschiedene Eingabequellen wie Hände oder Augen reagiert.

Neue Tests im Wiedergabemodus können BasePlayModeTests erben , oder das Gerüst unten kann verwendet werden.

So erstellen Sie einen neuen Wiedergabemodustest:

  • Navigieren Sie zu Assets > MRTK-Tests >> PlayModeTests
  • Rechtsklick, C>#-Testskript erstellen >
  • Ersetzen Sie die Standardvorlage durch das Skelett unten.
#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

Bearbeiten von Tests im Bearbeitungsmodus

Tests im Bearbeitungsmodus werden im Bearbeitungsmodus von Unity ausgeführt und können im Repository Mixed Reality Toolkit unter dem OrdnerEditModeTests für MRTK-Tests>> hinzugefügt werden. Um einen neuen Test zu erstellen, kann die folgende Vorlage verwendet werden:

// 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()
        {

        }
    }
}

Testen von Namenskonventionen

Tests sollten in der Regel basierend auf der Klasse benannt werden, die sie testen, oder dem Szenario, das sie testen. Beispiel: Bei einer zu testden Klasse:

namespace Microsoft.MixedReality.Toolkit.Input
{
    class InterestingInputClass
    {
    }
}

Erwägen Sie die Benennung des Tests.

namespace Microsoft.MixedReality.Toolkit.Tests.Input
{
    class InterestingInputClassTest
    {
    }
}

Erwägen Sie, den Test in einer Ordnerhierarchie zu platzieren, die der entsprechenden Nicht-Testdatei ähnelt. Beispiel:

Non-Test: Assets/MRTK/Core/Utilities/InterestingUtilityClass.cs
Test: Assets/MRTK/Tests/EditModeTests/Core/Utilities/InterestingUtilityClassTest.cs

Dadurch soll sichergestellt werden, dass es eine offensichtliche Möglichkeit gibt, die entsprechende Testklasse jeder Klasse zu finden, wenn eine solche Testklasse vorhanden ist.

Die Platzierung von szenariobasierten Tests ist weniger definiert. Wenn der Test das gesamte Eingabesystem ausübt, sollten Sie es beispielsweise in einem Ordner "InputSystem" im entsprechenden Bearbeitungsmodus oder im Testordner für den Wiedergabemodus ablegen.

Testskriptsymbole

Wenn Sie einen neuen Test hinzufügen, ändern Sie das Skript, um das richtige MRTK-Symbol zu erhalten. Hierfür gibt es ein einfaches MRTK-Tool:

  1. Wechseln Sie zum Menüelement Mixed Reality Toolkit.
  2. Klicken Sie auf Hilfsprogramme, dann auf Aktualisieren und dann auf Symbole.
  3. Klicken Sie auf Tests, und der Updater wird automatisch ausgeführt, wobei alle Testskripts aktualisiert werden, die keine Symbole aufweisen.

MRTK-Hilfsprogrammmethoden

In diesem Abschnitt werden einige der häufig verwendeten Codeausschnitte/Methoden beim Schreiben von Tests für MRTK gezeigt.

Es gibt zwei Hilfsprogrammklassen, die beim Einrichten von MRTK und beim Testen von Interaktionen mit Komponenten in MRTK helfen.

TestUtilities bietet die folgenden Methoden zum Einrichten Ihrer MRTK-Szene und 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();

Weitere Methoden dieser util-Klassen finden Sie in den API-Dokumentationen von TestUtilities und PlayModeTestUtilities , da sie regelmäßig erweitert werden, während neue Tests zu MRTK hinzugefügt werden.