Última atualização em dezembro de 2019, leitura de 6 minutos

Teste o código do seu jogo com o Unity Test Framework

O que você encontrará nesta página: dicas sobre como usar o Unity Test Framework (UTF) para conduzir QA em seus projetos. O UTF é uma das ferramentas mais importantes para garantia de qualidade. É usado para executar testes automatizados no Editor e em plataformas compatíveis. E está disponível para todos os usuários do Unity!  

Uma nova API do Test Runner oferece maior flexibilidade e capacidade de extensão ao UTF, para a maioria das necessidades de testes. Está disponível no Package Manager do Unity, para que possamos enviar correções de bugs e novas atualizações mais rápido. Isso também significa que você pode acessar o código-fonte do UTF localmente. Você pode observar o código-fonte, analisá-lo durante a depuração e modificá-la.  

Para ver a história completa, assista à sessão do UTF na Unite Copenhagen, com Richard Fine e Christian Warnecke, desenvolvedores de ferramentas e testes na Unity.

Teste o código do seu jogo com o Unity Test Framework

Conceitos básicos do Unity Test Framework

Se você é iniciante no Unity Test Framework (UTF), leia a documentação para obter uma introdução. Resumindo, o UTF permite que usuários do Unity testem código no Modo Edit e no Modo Play, bem como em plataformas-alvo, como Standalone, Android, iOS.

UTF usa uma integração com o Unity da biblioteca NUnit, que é uma biblioteca de testes de unidade de código aberto para linguagens .Net. Para obter mais informações sobre NUnit, acesse o site oficial da NUnit e a documentação da NUnit no GitHub

Estas publicações do blog são informativas para iniciantes:

Avaliação comparativa de desempenho no Unity: como começar a usar

Testes de desenvolvimento conduzido por testes com o Test Runner do Unity

Visão geral da API do Test Runner

Você pode executar os testes de maneira programática de qualquer script por meio da API do Test Runner (veja a API abaixo). Ela permite que você recupere uma lista dos testes que serão executados no Modo Edit, Modo Play ou ambos sem executá-los. Você pode vincular alguns callbacks de registro/cancelamento de registro no início e no término de cada teste em cada nível do ciclo de testes, ou seja, em todo o conjunto de teste, em cada instalação de teste e em cada teste e classe de teste. 

No início de cada teste, você recebe informações sobre a rota de teste que está prestes a ser executada. Ao final do teste, você verá os resultados. 

Além de executar o UTF no Modo Play no Unity Editor, um novo ponto de personalização permite a execução nos dispositivos-alvo. Isso é chamado antes de compilar o jogador. Você pode modificar as opções de build do jogador, por exemplo, para alterar as configurações de execução do teste e para especificar os locais da build.

TestRunnerAPI.cs (C#)
void Execute(ExecutionSettings executionSettings);
void RegisterCallbacks<T>(T testCallbacks, int priority = 0) where T : ICallbacks;
void UnregisterCallbacks<T>(T testCallbacks) where T : ICallbacks;
void RetrieveTestList(TestMode testMode, Action<ITestAdaptor> callback);

Separar compilação e execução

Separar os processos de compilação e execução é útil quando você deseja executar testes em um dispositivo-alvo que não está conectado ao computador local, por exemplo, se estiver na nuvem (ou se forem vários dispositivos na nuvem). 

Para isso, primeiro é necessário personalizar o próprio processo de compilação do jogador de teste. Veja como fazer isso: 

  • Desative o AutoRun de modo que, ao compilar o jogador, os testes não sejam inicializados e executados. 
  • Salve em um local conhecido em vez da pasta temporária do sistema (onde seria salvo por padrão. 

Depois, adicione relatórios de resultados personalizados no lado do jogador (usando a interface de callback) para capturar todos os resultados e salvá-los em um arquivo XML, ou qualquer outro formato adequado para o seu projeto. 

Vejas os exemplos de código a seguir para separação de compilação e execução. Na sessão da Unite (em 6:28), Richard Fine apresenta o código passo a passo para ambas as partes dessa aplicação — compilação e relatórios de resultados.

Separar compilação e execução: compilação

Compilação:

 

SplitBuildAndRun:build.cs (C#)
[assembly:TestPlayerBuildModifier(typeof(SetupPlaymodeTestPlayer))]
public class SetupPlaymodeTestPlayer : ITestPlayerBuildModifier {
   public BuildPlayerOptions ModifyOptions(BuildPlayerOptions playerOptions) {
   	playerOptions.options &= ~(BuildOptions.AutoRunPlayer | BuildOptions.ConnectToHost);
   	var buildLocation = Path.GetFullPath("TestPlayers");
   	var fileName = Path.GetFileName(playerOptions.locationPathName);
   	if (!string.IsNullOrEmpty(fileName))
       	buildLocation = Path.Combine(buildLocation, fileName);
   	playerOptions.locationPathName = buildLocation;
   	return playerOptions;
   }
}

Separar compilação e execução: salvar resultados na execução

Execução: 

SplitBuildAndRun:SaveResults.cs (C#)
[assembly:TestRunCallback(typeof(ResultSerializer))]
public class ResultSerializer : ITestRunCallback {
   public void RunStarted(ITest testsToRun) { }
   public void TestStarted(ITest test) { }
   public void TestFinished(ITestResult result) { }
   public void RunFinished(ITestResult testResults) {     
   	var path = Path.Combine(Application.persistentDataPath, "testresults.xml");
   	using (var xw = XmlWriter.Create(path, new XmlWriterSettings{Indent = true}))
       	testResults.ToXml(true).WriteTo(xw);
   	System.Console.WriteLine($"***\n\nTEST RESULTS WRITTEN TO\n\n\t{path}\n\n***");
   	Application.Quit(testResults.FailCount > 0 ? 1 : 0);
   }
}

Inicialização de testes específicos de um item de menu

Frequentemente, quando os desenvolvedores gravam validações, os resultados são exibidos na janela Console, onde podem ser facilmente perdidos no fluxo de mensagens. E se você pudesse obter resultados de validação em um pacote de testes com indicadores claros em um local dedicado no Editor? Isso pode ser feito inicializando testes específicos para um item de menu.  

Comece com um método vinculado a um MenuItem, da mesma maneira que faria com qualquer outro item de menu de extensão do Editor. Esse método criará um objeto de callback de ScriptableObject. Use um ScriptableObject em vez de uma classe regular para que os testes possam realizar ações, como fazer com que um domínio seja recarregado enquanto mantém os callbacks intactos. Ao habilitar o ScriptableObject, ele é registrado para callbacks, e ao desabilitar, o registro é cancelado. 

Depois, configure filtros. Frequentemente, ao inicializar um teste para um MenuItem, deseja-se executar testes para uma categoria ou um grupo específico. Com filtros é possível executar o teste de maneira assíncrona. Será executado ao longo de vários quadros, permitindo que UnityTest, UnitySetUp e UnityTearDown marquem o ciclo da engine durante o teste. Quando o teste for concluído e registrar RunFinished, você poderá defini-lo para exibir uma mensagem ou abrir uma janela de resultados — o que fizer sentido para o seu fluxo de trabalho.

Veja o exemplo de código abaixo. Richard aborda a configuração do código para essa aplicação na sessão da Unite (em 11:50).  

LaunchTestsFromMenuItem.cs (C#)
public class RunTestsFromMenu : ScriptableObject, ICallbacks {
   [MenuItem(“Tools/Run useful tests”)] public static void DoRunTests() {
   	CreateInstance<RunTestsFromMenu>().StartTestRun();
   }
   private void StartTestRun() {
   	hideFlags = HideFlags.HideAndDontSave;
   	CreateInstance<TestRunnerApi>().Execute(new ExecutionSettings {
       	filters = new [] { new Filter{ categoryNames = new[] { “UsefulTests” }}}
   	});
   }
   public void OnEnable() { CreateInstance<TestRunnerApi>().RegisterCallbacks(this); }
   public void OnDisable() { CreateInstance<TestRunnerApi>().UnregisterCallbacks(this); }
   /* ...RunStarted, TestStarted, TestFinished... */
   public void RunFinished(ITestResultAdaptor result) {       
   	…
   	DestroyImmediate(this);
   }

Execução de testes antes da compilação

Executar testes antes da compilação pode ser complicado pois o processo de compilação requer que os testes sejam executados de um callback, portanto, não há oportunidade para impulsionar o ciclo de atualização da engine. Mas o benefício é que você pode verificar se a funcionalidade básica está funcionando, antes de gastar tempo na compilação em si (que pode levar vários minutos em alguns projetos). 

Você pode implementar essa aplicação usando a interface IPreprocessBuildWithReport, da mesma maneira que implementaria qualquer outro tipo de pré-processamento de compilação. Para obter os resultados, registre um callback como de costume.

Como não é possível acessar o Modo Play durante uma compilação, você pode usar a API do Test Runner para executar testes específicos no Modo Edit. Você pode selecionar esses testes filtrando por categoria, como uma categoria de teste de validação pré-compilação. Esses testes podem ser executados de maneira síncrona. 

Ao concluir o teste, verifique os resultados. Se algo falhou, lance uma exceção BuildFailed, que fará com que o processo de compilação seja abortado. 

Essa aplicação pode ser dividida em duas partes — o ResultCollector e o pré-processador — que são detalhados por Richard na palestra (em 15:20). 

Assista a Christian e Richard demonstrarem a API do Test Runner ao vivo. Confira toda a sessão para obter ainda mais dicas de QA! 

RunTestsBeforeBuild.cs (C#)
   public ITestResultAdaptor Result { get; private set; }     
   public void RunStarted(ITestAdaptor testsToRun) { }
   public void TestStarted(ITestAdaptor test) { }
   public void TestFinished(ITestResultAdaptor result) { }
   public void RunFinished(ITestResultAdaptor result)
   {
   	Result = result;
   }
}

Você gostou deste conteúdo?

Usamos cookies para garantir a melhor experiência no nosso site. Visite nossa página da política de cookies para obter mais informações.

Eu entendi