Écriture et exécution de tests — MRTK2

Pour garantir que MRTK est fiable, MRTK a un ensemble de tests pour s’assurer que les modifications apportées au code ne régressent pas le comportement existant. Une bonne couverture de test dans une base de code volumineuse comme MRTK est essentielle pour la stabilité et avoir confiance lors des modifications.

MRTK utilise Unity Test Runner qui utilise une intégration Unity de NUnit. Ce guide fournit un point de départ sur l’ajout de tests à MRTK. Il n’expliquera pas unity Test Runner et NUnit qui peuvent être recherchés dans les liens fournis.

Avant d’envoyer une demande de tirage, veillez à :

  1. Exécutez les tests localement afin que vos modifications ne régressent pas le comportement existant (l’achèvement des PRs ne sera pas autorisé si des tests échouent).

  2. Si vous corrigez un bogue, écrivez un test pour tester le correctif et assurez-vous que les modifications de code futures ne le réécriront pas.

  3. Si vous écrivez une fonctionnalité, écrivez de nouveaux tests pour empêcher les modifications de code à venir cassant cette fonctionnalité.

Actuellement, les tests playmode sont destinés à être exécutés dans Unity 2018.4 et peuvent échouer dans d’autres versions d’Unity

Exécution des tests

Éditeur Unity

Unity Test Runner se trouve sous Window> GeneralTest Runner et affiche tous les tests de lecture et de modificationMRTK> disponibles.

Ligne de commande

Les tests peuvent également être exécutés par un script PowerShell situé à l’adresse Scripts\test\run_playmode_tests.ps1. Cela exécute les tests playmode exactement comme ils sont exécutés sur github /CI (voir ci-dessous) et impriment les résultats. Voici quelques exemples d’exécution du script

Exécutez les tests sur le projet situé à H:\mrtk.dev, avec Unity 2018.4 (par exemple Unity 2018.4.26f1)

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

Exécutez les tests sur le projet situé à H:\mrtk.dev, avec Unity 2018.4, les résultats de sortie vers 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\"

Il est également possible d’exécuter les tests playmode plusieurs fois via le run_repeat_tests.ps1 script. Tous les paramètres utilisés peuvent run_playmode_tests.ps1 être utilisés.

.\run_repeat_tests.ps1 -Times 5

Validation des demandes de tirage

LE CI de MRTK génère MRTK dans toutes les configurations et exécute tous les tests en mode édition et lecture. CI peut être déclenché en publiant un commentaire sur la demande de tirage /azp run mrtk_pr github si l’utilisateur dispose de droits suffisants. Les exécutions CI peuvent être affichées dans l’onglet « vérifications » de la demande de tirage.

Seulement une fois que tous les tests ont réussi, la demande de tirage peut être fusionnée en main.

Tests de stress / tests en bloc

Parfois, les tests échouent uniquement occasionnellement, ce qui peut être frustrant pour déboguer.

Pour avoir plusieurs exécutions de test localement, modifiez les scripts de test en fonction. Le script Python suivant doit rendre ce scénario plus pratique.

La configuration requise pour l’exécution du script Python est l’installation de Python 3.X.

Pour un test unique qui doit être exécuté plusieurs fois :

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

Exécutez ce qui suit à partir d’une ligne de commande (PowerShell est recommandé)

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

Copiez et collez la sortie dans votre fichier de test. Le script suivant est destiné à exécuter plusieurs tests dans la séquence :

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

Le nouveau fichier de test doit maintenant contenir

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

Ouvrez l’exécuteur de test et observez les nouveaux tests qui peuvent maintenant être appelés à plusieurs reprises.

Écriture des tests

Il existe deux types de tests qui peuvent être ajoutés pour le nouveau code

  • Tests en mode lecture
  • Modifier les tests en mode

Tests en mode lecture

Les tests en mode lecture MRTK ont la possibilité de tester la façon dont votre nouvelle fonctionnalité répond à différentes sources d’entrée telles que les mains ou les yeux.

Les nouveaux tests en mode lecture peuvent hériter de BasePlayModeTests ou le squelette ci-dessous peut être utilisé.

Pour créer un test en mode lecture :

  • Accédez aux ressources > MRTK > Tests > PlayModeTests
  • Cliquez avec le bouton droit sur Créer un >> script de test C#
  • Remplacez le modèle par défaut par le squelette ci-dessous
#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

Modifier les tests en mode

Les tests de mode d’édition sont exécutés en mode édition de Unity et peuvent être ajoutés sous le dossier MrTK>Tests>EditModeTests dans le dépôt Mixed Reality Toolkit. Pour créer un nouveau test, vous pouvez utiliser le modèle suivant :

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

        }
    }
}

Tester les conventions d’affectation de noms

Les tests doivent généralement être nommés en fonction de la classe qu’ils testent ou du scénario qu’ils testent. Par exemple, en fonction d’une classe à tester :

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

Envisagez de nommer le test

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

Envisagez de placer le test dans une hiérarchie de dossiers similaire à son fichier de non-test correspondant. Par exemple :

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

Il s’agit de s’assurer qu’il existe un moyen évident de trouver la classe de test correspondante de chaque classe, s’il existe une telle classe de test.

Le placement des tests basés sur des scénarios est moins défini : si le test exerce le système d’entrée global, par exemple, envisagez de le placer dans un dossier « InputSystem » dans le dossier de test en mode d’édition ou en mode lecture correspondant.

Icônes de script de test

Lors de l’ajout d’un nouveau test, modifiez le script pour avoir l’icône MRTK correcte. Il existe un outil MRTK facile à faire :

  1. Accédez à l’élément de menu Mixed Reality Toolkit.
  2. Cliquez sur Utilitaires, puis Mettez à jour, puis icônes.
  3. Cliquez sur Tests, et le updater s’exécute automatiquement, mettant à jour tous les scripts de test manquants dans leurs icônes.

Méthodes d’utilitaire MRTK

Cette section présente certains des extraits de code / méthodes couramment utilisés lors de l’écriture de tests pour MRTK.

Il existe deux classes Utilitaires qui aident à configurer MRTK et à tester des interactions avec des composants dans MRTK

TestUtilities fournit les méthodes suivantes pour configurer votre scène MRTK et 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();

Reportez-vous à la documentation de l’API et TestUtilitiesPlayModeTestUtilities pour obtenir d’autres méthodes de ces classes d’utilisation, car elles sont étendues régulièrement pendant que de nouveaux tests sont ajoutés à MRTK.