Gravação e execução de testes — MRTK2

Para garantir que o MRTK seja confiável, o MRTK tem um conjunto de testes para garantir que as alterações no código não regredam o comportamento existente. Ter uma boa cobertura de teste em uma grande base de código como o MRTK é crucial para a estabilidade e ter confiança ao fazer alterações.

O MRTK usa o Executor de Teste do Unity que usa uma integração do Unity do NUnit. Este guia fornecerá um ponto de partida sobre como adicionar testes ao MRTK. Ele não explicará o Unity Test Runner e o NUnit que podem ser pesquisados nos links fornecidos.

Antes de enviar uma solicitação de pull, certifique-se de:

  1. Execute os testes localmente para que as alterações não regredam o comportamento existente (a conclusão de PRs não será permitida se algum teste falhar).

  2. Se estiver corrigindo um bug, escreva um teste para testar a correção e garantir que as futuras modificações de código não serão interrompidas novamente.

  3. Se estiver escrevendo um recurso, escreva novos testes para evitar que as próximas alterações de código quebrando esse recurso.

Atualmente, os testes do playmode devem ser executados no Unity 2018.4 e podem falhar em outras versões do Unity

Executando testes

Editor do Unity

O Executor de Teste do Unity pode ser encontrado em GerenciadordeTesteGeral> da Janela > e mostrará todos os testes disponíveis do modo de reprodução e edição do MRTK.

Linha de comando

Os testes também podem ser executados por um script do PowerShell localizado em Scripts\test\run_playmode_tests.ps1. Isso executará os testes do playmode exatamente como eles são executados no github/CI (veja abaixo) e imprimirá os resultados. Aqui estão alguns exemplos de como executar o script

Execute os testes no projeto localizado em H:\mrtk.dev, com o Unity 2018.4 (por exemplo, Unity 2018.4.26f1)

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

Execute os testes no projeto localizado em H:\mrtk.dev, com o Unity 2018.4, gerando resultados para 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\"

Também é possível executar os testes do playmode várias vezes por meio do run_repeat_tests.ps1 script. Todos os parâmetros usados em run_playmode_tests.ps1 podem ser usados.

.\run_repeat_tests.ps1 -Times 5

Validação de solicitação de pull

A CI do MRTK criará o MRTK em todas as configurações e executará todos os testes de modo de edição e reprodução. A CI pode ser disparada postando um comentário no github PR /azp run mrtk_pr se o usuário tiver direitos suficientes. As execuções de CI podem ser vistas na guia "verificações" da PR.

Somente depois que todos os testes forem aprovados com êxito, a PR poderá ser mesclada em main.

Testes de estresse/testes em massa

Às vezes, os testes só falham ocasionalmente, o que pode ser frustrante para depurar.

Para ter várias execuções de teste localmente, modifique os scripts de teste de acordo. O script python a seguir deve tornar esse cenário mais conveniente.

O pré-requisito para executar o script python é ter o Python 3.X instalado.

Para um único teste que precisa ser executado várias vezes:

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

Execute o seguinte em uma linha de comando (o PowerShell é recomendado)

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

Copie e cole a saída no arquivo de teste. O script a seguir é para executar vários testes em sequência:

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

O novo arquivo de teste agora deve conter

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

Abra o executor de teste e observe os novos testes que agora podem ser chamados repetidamente.

Escrever testes

Há dois tipos de testes que podem ser adicionados para o novo código

  • Testes no modo de reprodução
  • Editar testes de modo

Testes no modo de reprodução

Os testes do modo de reprodução do MRTK têm a capacidade de testar como o novo recurso responde a diferentes fontes de entrada, como mãos ou olhos.

Novos testes de modo de reprodução podem herdar BasePlayModeTests ou o esqueleto abaixo pode ser usado.

Para criar um novo teste de modo de reprodução:

  • Navegue até Ativos > Testes > do MRTK > PlayModeTests
  • Clique com o botão direito do mouse em Criar > Script > de Teste em C#
  • Substitua o modelo padrão pelo esqueleto abaixo
#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

Editar testes de modo

Os testes de modo de edição são executados no modo de edição do Unity e podem seradicionadosna pastaEditModeTests> de Testes do MRTK> no repositório Realidade Misturada Toolkit. Para criar um novo teste, o modelo a seguir pode ser usado:

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

        }
    }
}

Testar convenções de nomenclatura

Os testes geralmente devem ser nomeados com base na classe que estão testando ou no cenário que estão testando. Por exemplo, dada uma classe a ser testada:

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

Considere nomear o teste

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

Considere colocar o teste em uma hierarquia de pastas semelhante ao arquivo de não teste correspondente. Por exemplo:

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

Isso é para garantir que haja uma maneira clara de encontrar a classe de teste correspondente de cada classe, se essa classe de teste existir.

O posicionamento de testes baseados em cenário é menos definido – se o teste exercer o sistema de entrada geral, por exemplo, considere colocá-lo em uma pasta "InputSystem" no modo de edição correspondente ou na pasta de teste do modo de reprodução.

Ícones de script de teste

Ao adicionar um novo teste, modifique o script para ter o ícone correto do MRTK. Há uma ferramenta fácil do MRTK para fazer isso:

  1. Vá para o item de menu kit de ferramentas Realidade Misturada.
  2. Clique em Utilitários e, em seguida, em Atualizar e ícones.
  3. Clique em Testes e o atualizador será executado automaticamente, atualizando todos os scripts de teste que não tiverem seus ícones.

Métodos do Utilitário MRTK

Esta seção mostra alguns dos snippets de código/métodos comumente usados ao escrever testes para MRTK.

Há duas classes do Utilitário que ajudam a configurar o MRTK e testar interações com componentes no MRTK

TestUtilities fornecem os seguintes métodos para configurar sua cena do MRTK e 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();

Consulte os documentos da API de TestUtilities e PlayModeTestUtilities para obter mais métodos dessas classes util, pois elas são estendidas regularmente enquanto novos testes são adicionados ao MRTK.