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 an dem Code nicht vorhandenes Verhalten regressieren. Eine gute Testabdeckung in einer großen Codebasis wie MRTK ist entscheidend für Stabilität und Vertrauen beim Vornehmen von Änderungen.

MRTK verwendet den Unity Test Runner , der eine Unity-Integration von NUnit verwendet. Dieser Leitfaden stellt einen Ausgangspunkt für das Hinzufügen von Tests zu MRTK dar. Er erklärt nicht den Unity Test Runner und NUnit , der in den links bereitgestellten Links nachschlagen kann.

Stellen Sie vor dem Übermitteln einer Pullanforderung folgendes sicher:

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

  2. Wenn ein Fehler behoben wird, schreiben Sie einen Test, um den Fix zu testen, und stellen Sie sicher, dass zukünftige Codeänderungen sie nicht erneut unterbrechen.

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

Derzeit sollen Playmode-Tests in Unity 2018.4 ausgeführt werden und können in anderen Versionen von Unity fehlschlagen.

Ausführen von Tests

Unity-Editor

Der Unity Test Runner finden Sie unter Window>General>Test Runner und zeigt alle verfügbaren MRTK-Wiedergabe- und Bearbeitungsmodustests an.

Befehlszeile

Tests können auch von einem PowerShell-Skript ausgeführt werden, das sich unter Scripts\test\run_playmode_tests.ps1befindet. Dies führt die Playmode-Tests genau aus, wie sie auf github / CI (siehe unten) ausgeführt werden, und drucken Sie Ergebnisse. Hier sind einige Beispiele zum Ausführen des Skripts

Führen Sie die Tests im Projekt aus, die sich auf H:\mrtk.dev befinden, mit Unity 2018.4 (z. B. Unity 2018.4.26f1)

.\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 im Projekt aus, die sich auf H:\mrtk.dev befinden, mit Unity 2018.4, ausgabeergebnisse 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

MRTK's CI erstellt MRTK in allen Konfigurationen und führt alle Bearbeitungs- und Wiedergabemodustests aus. CI kann ausgelöst werden, indem sie einen Kommentar auf der github PR /azp run mrtk_pr veröffentlichen, wenn der Benutzer über ausreichende Rechte verfügt. CI-Ausführungen können auf der Registerkarte "Überprüfungen" der PR angezeigt werden.

Nur nachdem alle Tests erfolgreich bestanden haben, kann die PR in haupt zusammengeführt werden.

Stresstests / Massentests

Manchmal tritt nur gelegentlich ein Fehler auf, der frustrierend zum Debuggen sein kann.

Wenn mehrere Testvorgänge lokal ausgeführt werden sollen, ändern Sie die angegebenen Testskripts. Das folgende Python-Skript sollte dieses Szenario bequemer machen.

Voraussetzung für das Ausführen des Python-Skripts besteht darin, dass Python 3.X installiert ist.

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

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

Führen Sie folgendes aus einer 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 und Einfügen der Ausgabe in Ihre Testdatei. Das folgende Skript dient zum Ausführen mehrerer Tests in Sequenz:

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 sein.

[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 Testläufer, 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

  • Wiedergabemodustests
  • Bearbeiten von Modustests

Wiedergabemodustests

MRTK-Wiedergabemodustests haben die Möglichkeit, zu testen, wie Ihr neues Feature auf verschiedene Eingabequellen reagiert, z. B. Hände oder Augen.

Neue Wiedergabemodustests können BasePlayModeTests erben oder das Skelett unten verwendet werden.

So erstellen Sie einen neuen Wiedergabemodustest:

  • Navigieren zu Assets > MRTK >> Tests PlayModeTests
  • Klicken Sie mit der rechten Maustaste, Erstellen des > Testskripts > C#
  • Ersetzen Sie die Standardvorlage durch das untere Skelett
#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 Modustests

Bearbeitungsmodustests werden im Bearbeitungsmodus von Unity ausgeführt und können im Ordner "EditModeTests>>" im Ordner "EditModeTests" im Mixed Reality Toolkit-Repo 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 Benennungskonventionen

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

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

Berücksichtigen Sie die Benennung des Tests

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

Überlegen Sie, den Test in einer Ordnerhierarchie zu platzieren, die der entsprechenden Nichttestdatei ähnlich ist. Beispiel:

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

Dies besteht darin, sicherzustellen, 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 z. B. in einen Ordner "InputSystem" im entsprechenden Bearbeitungsmodus oder im Testmodus einfügen soll.

Skriptsymbole testen

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

  1. Wechseln Sie zum Menüelement Mixed Reality Toolkit.
  2. Klicken Sie auf Dienstprogramme, und aktualisieren Sie dann Symbole.
  3. Klicken Sie auf Tests, und der Updater wird automatisch ausgeführt, indem Sie alle Testskripts aktualisieren, die ihre Symbole fehlen.

MRTK-Hilfsmethoden

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

Es gibt zwei Hilfsklassen, die beim Einrichten von MRTK- und Testinteraktionen mit Komponenten in MRTK helfen

TestUtilities stellen die folgenden Methoden bereit, um Ihre MRTK-Szene und GameObjects einzurichten:

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

Bitte verweisen Sie auf die API-Dokumente und TestUtilitiesPlayModeTestUtilities für weitere Methoden dieser util-Klassen, da sie regelmäßig erweitert werden, während neue Tests dem MRTK hinzugefügt werden.