Cyber week

Подарок при покупке. Время ограничено. Действует до 4 декабря
Подарок при покупке. Время ограничено. Действует до 4 декабря

Last Updated August 2020, 6 min. read

Тестируйте игровой код с помощью Unity Test Framework

Что вы узнаете на этой странице: советы по использованию Unity Test Framework (UTF) для контроля качества ваших проектов. UTF — это один из важнейших инструментов для контроля качества; это система автоматизированного тестирования как в Editor, так и на поддерживаемых платформах. И эта система доступна всем пользователям Unity!  

Новый API Test Runner расширяет гибкость и возможности UTF, обеспечивая максимальный охват тестирования. Эта система доступна в Unity Package Manager, благодаря чему мы можем быстрее устранять ошибки и обновлять ее. Кроме того, это означает для вас локальную доступность исходного кода UTF. Изучайте исходный код, улучшайте его при отладке и меняйте на свое усмотрение.  

Подробнее об этой системе можно узнать из доклада об UTF на Unite Copenhagen, который представили разработчики инструментария и тестов Ричард Файн и Кристиан Варнеки.

Тестируйте игровой код с помощью Unity Test Framework

Начало работы с Unity Test Framework

If you are new to the Unity Test Framework (UTF), read the documentation for an introduction. In brief, the UTF enables Unity users to test their code in both Edit Mode and Play Mode, and also on target platforms such as Standalone, Android, iOS, and others.

UTF uses a Unity integration of the NUnit library, which is an open-source unit testing library for .Net languages. For more information about NUnit, see the official NUnit website and the NUnit documentation on GitHub

You might also find these blog posts informative:

Performance benchmarking in Unity: How to get started

Testing test-driven development with the Unity Test Runner

Another related solution to learn about is Backtrace, an error management platform that enables you to capture crashes and exceptions and fix them quickly. Watch this Unite Now session for an in-depth introduction. 

Обзор Test Runner API

Тесты можно запускать автоматически, любым скриптом, с помощью Test Runner API (см. API ниже). Интерфейс позволяет получать список тестов, которые запускаются в режиме редактирования, в режиме игры или в обоих режимах без необходимости их запуска. Вы можете подключить обратные вызовы регистрации и дерегистрации в начало и конец каждого теста на каждом уровне в рамках цикла тестирования, то есть для каждой тестовой сборки, для каждого тестового устройства, для каждого тестового класса и отдельного теста. 

В начале вы получите информацию о ходе запускаемого теста. После завершения теста вы увидите его результаты. 

Помимо запуска UTF в режиме игры в редакторе Unity, новая точка настройки позволяет запускать тест на целевых устройствах. Она вызывается до сборки Player и позволяет изменить настройки сборки Player. Например, изменить настройки запуска тестов и указать расположения сборок.

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);

Разделение сборки и запуска

Разделение процессов сборки и запуска удобно при необходимости провести тестирование на целевом устройстве, не подключенном к локальной машине, например, если оно находится в облаке (или при наличии нескольких устройств в облаке). 

Для этого сначала нужно изменить сам процесс сборки тестового приложения Player. Сделать это можно так: 

  • отключите параметр AutoRun, чтобы после завершения не происходило запуска Player и запланированных тестов; 
  • сохраните сборку в известное расположение, а не во временную папку системы (куда она сохраняется по умолчанию); 

добавьте свои настройки отчета по результатам на стороне Player (с помощью интерфейса обратных вызовов) для записи всех результатов в XML или в файл любого удобного вам формата. 

Ниже приведены примеры кода для разделения процессов сборки и запуска. В докладе на конференции Unite (отметка 6:28) Ричард Файн подробно раскрывает оба аспекта этого приложения — и процесс сборки, и составление отчета по результатам.

Разделение сборки и запуска: сборка

Сборка:

 

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;
   }
}

Разделение сборки и запуска: сохранение результатов и запуск

Запуск: 

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);
   }
}

Запуск конкретных тестов из меню

Зачастую при разработке проверок результаты выводятся в окно Console, где их очень легко потерять в потоке сообщений. А что если результаты проверки выводить в тестовую среду с понятными индикаторами, в специальном окне редактора? Это возможно путем запуска конкретных тестов из меню.  

Начните с метода, привязанного к MenuItem, точно так же, как и в случае с пунктом меню любого другого расширения для редактора. Этот метод создает объект обратного вызова ScriptableObject. Используйте ScriptableObject вместо обычного класса, чтобы тесты могли выполнять, например, перезагрузку домена, не влияя на обратные вызовы. Когда ScriptableObject включен, он зарегистрирован для обратных вызовов — и не зарегистрирован, когда выключен. 

Затем настройте фильтры. Зачастую при запуске теста из MenuItem нужно выполнить тесты для конкретной категории или группы. Фильтры позволяют выполнить тестовый запуск асинхронно. Тест будет выполняться в течение нескольких кадров, позволяя вам продвинуть вперед цикл движка с помощью атрибутов UnityTest, UnitySetUp и UnityTearDown. Вы можете настроить тест так, чтобы после его завершения и регистрации RunFinished выводилось сообщение или открывалось окно с результатами, в зависимости от того, что вам удобнее.

Пример кода можно увидеть ниже. Ричард объясняет код для этого приложения в докладе на Unite (отметка 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);
   }

Выполнение тестов до сборки

Выполнение тестов до сборки может быть сопряжено с некоторыми сложностями, поскольку процессу сборки нужно, чтобы тесты запускались обратным вызовом, чтобы не было возможности выполнить цикл update для движка. Но такой подход полезен возможностью проверить базовую функциональность, не тратя время на процесс сборки (который может занимать несколько минут для некоторых проектов). 

Вы можете реализовать это с помощью интерфейса IPreprocessBuildWithReport, аналогично реализации любых других операций, выполняемых до сборки. Как и в других случаях, для получения результатов нужно зарегистрировать обратный вызов.

В режим игры невозможно переключиться в процессе сборки, но можно использовать Test Runner API для выполнения тестов в режиме редактирования. Эти тесты можно выбрать с помощью фильтра по категориям, например, категория «валидационный тест перед сборкой». Эти тесты можно выполнять синхронно. 

После завершения тестов проверьте результаты. Если что-то пошло не так, то можно отправить исключение BuildFailed, которое отменит процесс сборки. 

Это приложение можно разбить на две части: ResultCollector и препроцессор, о котором Ричард рассказывает в своем докладе (отметка 15:20). 

Смотрите демонстрацию работы Test Runner API от Кристиана и Ричарда. Смотрите весь доклад, если хотите узнать ответы на заданные им вопросы! 

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;
   }
}

Понравился ли вам этот контент?

Мы используем cookie-файлы, чтобы вам было удобнее работать с нашим веб-сайтом. Подробнее об этом можно узнать на странице, посвященной политике использования cookie-файлов.

Согласен