Написание и выполнение тестов — MRTK2

Чтобы обеспечить надежность MRTK, MRTK имеет набор тестов, чтобы убедиться, что изменения в коде не регрессии существующего поведения. Наличие хорошего покрытия тестов в большой базе кода, такой как MRTK, имеет решающее значение для стабильности и уверенности при внесении изменений.

MRTK использует средство выполнения тестов Unity , которое использует интеграцию Unity с NUnit. В этом руководстве приведена отправная точка по добавлению тестов в MRTK. Он не будет объяснять средство выполнения тестов Unity и NUnit , которые можно найти по приведенным ссылкам.

Перед отправкой запроса на вытягивание убедитесь в том, что:

  1. Запустите тесты локально, чтобы изменения не регрессивно выполняли существующее поведение (выполнение ЗАПРОСОВ не будет разрешено, если какие-либо тесты завершаются неудачно).

  2. Если вы исправите ошибку, напишите тест, чтобы проверить исправление и убедиться, что будущие изменения кода не сломают ее снова.

  3. При написании функции напишите новые тесты, чтобы предотвратить предстоящие изменения в коде, которые нарушают эту функцию.

В настоящее время тесты playmode предназначены для выполнения в Unity 2018.4 и могут завершиться ошибкой в других версиях Unity.

Выполнение тестов

Редактор Unity

Средство выполнения тестов Unity можно найти в разделе WindowGeneralTest Runner (Общее> средство выполнения тестов) > и будет отображать все доступные тесты режима воспроизведения и редактирования MRTK.

Командная строка

Тесты также можно выполнять с помощью скрипта PowerShell , расположенного по адресу Scripts\test\run_playmode_tests.ps1. При этом тесты playmode будут выполняться точно так, как они выполняются в github/CI (см. ниже) и выводить результаты. Ниже приведены некоторые примеры выполнения скрипта.

Выполните тесты в проекте, расположенном по адресу H:\mrtk.dev, с помощью Unity 2018.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

Проверка запроса на вытягивание

CI MRTK будет создавать MRTK во всех конфигурациях и выполнять все тесты режима редактирования и воспроизведения. Ci может быть активирована путем публикации комментария к запросу на github, /azp run mrtk_pr если у пользователя есть достаточные права. Запуски CI можно увидеть на вкладке "проверки" запроса на вытягивание.

Только после успешного прохождения всех тестов запрос на вытягивание можно объединить в 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 > Tests > 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 и могут быть добавлены в папку MRTK>Tests>EditModeTests в репозитории Смешанная реальность Toolkit. Чтобы создать тест, можно использовать следующий шаблон:

// 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:

  1. Перейдите к элементу меню набор средств Смешанная реальность.
  2. Щелкните Служебные программы, Обновление и Значки.
  3. Щелкните Тесты, и средство обновления запустится автоматически, обновив все тестовые скрипты, в которых отсутствуют значки.

Методы служебной программы 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();

Дополнительные методы этих классов util см. в документации TestUtilities по API и PlayModeTestUtilities по мере их регулярного расширения в то время как новые тесты добавляются в MRTK.