Partilhar via


Escrever e executar testes – MRTK2

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

O MRTK utiliza o Unity Test Runner que utiliza uma integração do Unity do NUnit. Este guia irá fornecer um ponto de partida sobre como adicionar testes ao MRTK. Não explicará o Unity Test Runner e o NUnit que podem ser pesquisados nas ligações fornecidas.

Antes de submeter um pedido Pull, certifique-se de que:

  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 corrigir um erro, escreva um teste para testar a correção e certifique-se de que as futuras modificações de código não voltarão a quebrá-lo.

  3. Se escrever uma funcionalidade, escreva novos testes para evitar que as próximas alterações de código que interrompem esta funcionalidade.

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

Executar testes

Editor do Unity

O Unity Test Runner pode ser encontrado em Window>General>Test Runner e mostrará todos os testes de modo de reprodução e edição do MRTK disponíveis.

Linha de comandos

Os testes também podem ser executados por um script do Powershell localizado em Scripts\test\run_playmode_tests.ps1. Esta ação irá executar os testes playmode exatamente como são executados no github/CI (ver abaixo) e imprimir resultados. Eis 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, resultados de saída 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 playmode várias vezes através do run_repeat_tests.ps1 script. Todos os parâmetros utilizados no run_playmode_tests.ps1 podem ser utilizados.

.\run_repeat_tests.ps1 -Times 5

Validação do pedido Pull

O CI do MRTK irá 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 acionada ao publicar um comentário no PR /azp run mrtk_pr do github se o utilizador tiver direitos suficientes. As execuções de CI podem ser vistas no separador "verificações" do PR.

Só depois de todos os testes terem sido aprovados com êxito é que o PR pode ser intercalado no principal.

Testes de esforço/testes em massa

Por vezes, os testes só falham ocasionalmente, o que pode ser frustrante de depurar.

Para executar vários testes localmente, modifique os scripts de teste de acordo. O seguinte script python deve tornar este cenário mais conveniente.

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

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

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

Execute o seguinte a partir de uma linha de comandos (recomenda-se o PowerShell )

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

Copie e cole o resultado no ficheiro de teste. O script seguinte destina-se à execução de 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 ficheiro de teste deve agora 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 test runner e observe os novos testes que agora podem ser chamados repetidamente.

Escrever testes

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

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

Testes do modo de reprodução

Os testes do modo de reprodução do MRTK têm a capacidade de testar a forma como a nova funcionalidade responde a diferentes origens de entrada, como mãos ou olhos.

Os novos testes do modo de reprodução podem herdar BasePlayModeTests ou a estrutura abaixo pode ser utilizada.

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

  • Navegue até Assets > MRTK > Tests > PlayModeTests
  • Clique com o botão direito do rato em Criar > Script de Teste C# de Teste >
  • Substitua o modelo predefinido 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 do modo de edição são executados no modo de edição do Unity e podem seradicionadosna pastaEditModeTests> dos Testes MRTK> no repositório Mixed Reality Toolkit. Para criar um novo teste, pode utilizar o seguinte modelo:

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

Geralmente, os testes devem ser nomeados com base na classe que estão a testar ou no cenário que estão a testar. Por exemplo, dada uma classe a testar:

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

Considere atribuir um nome ao teste

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

Considere colocar o teste numa hierarquia de pastas semelhante ao ficheiro não teste correspondente. Por exemplo:

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

Isto é para garantir que existe uma forma clara e óbvia de encontrar a classe de teste correspondente de cada classe, se existir uma classe de teste desse tipo.

A colocação de testes baseados em cenários é menos definida – se o teste exercer o sistema de entrada geral, por exemplo, considere colocá-lo numa 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 de MRTK correto. Existe uma ferramenta MRTK fácil para o fazer:

  1. Aceda ao item de menu Mixed Reality Toolkit.
  2. Clique em Utilitários e, em seguida, em Atualizar e, em seguida, em Ícones.
  3. Clique em Testes e o atualizador será executado automaticamente, atualizando os scripts de teste em falta nos respetivos ícones.

Métodos do Utilitário MRTK

Esta secção mostra alguns dos fragmentos/métodos de código utilizados frequentemente ao escrever testes para MRTK.

Existem duas classes utilitárias que ajudam a configurar o MRTK e a testar interações com componentes no MRTK

As TestUtilities fornecem os seguintes métodos para configurar a cena mrTK e os 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();

Veja os documentos da API de TestUtilities e PlayModeTestUtilities para obter mais métodos destas classes de utilitários, uma vez que são expandidos regularmente enquanto são adicionados novos testes ao MRTK.