¿Qué estás buscando?
Hero background image
Cómo ejecutar pruebas automatizadas para tus juegos con Unity Test Framework

En el desarrollo de juegos, las pruebas manuales pueden volverse rápidamente repetitivas y propensas a errores. ¿Alguna vez te has encontrado en uno de estos ciclos de prueba aparentemente interminables mientras trabajas en una nueva característica o intentas corregir un error?

Al automatizar las pruebas de código, puede dedicar más tiempo al desarrollo creativo de juegos y menos a tareas de control de calidad repetitivas (pero importantes) que garantizan que agregar, eliminar o cambiar código no interrumpa su proyecto.

Unity te ayuda a crear, administrar y ejecutar pruebas automatizadas para tus juegos con Unity Test Framework.

Pruebe de dos maneras en Unity Test Framework

Unity Test Framework (UTF) le permite probar el código de su proyecto en los modos Editar y Reproducir . También puede orientar el código de prueba a varias plataformas, como la independiente, iOS o Android.

El UTF se instala agregándolo a su proyecto con el Administrador de paquetes.

En el fondo, UTF se integra con NUnit, que es una conocida biblioteca de pruebas de código abierto para lenguajes .NET.

Hay dos categorías principales de pruebas que puedes escribir con UTF, modo de edición y modo de reproducción:

Las pruebas del modo de ediciónse ejecutan en Unity Editor y tienen acceso tanto al editor como al código del juego. Esto significa que puede probar sus extensiones personalizadas del Editor o usar pruebas para modificar la configuración en el Editor e ingresar al modo Reproducir, lo cual es útil para ajustar los valores del Inspector y luego ejecutar pruebas automatizadas con muchas configuraciones diferentes.

Las pruebas del modo de juegote permiten ejercitar el código del juego en tiempo de ejecución. Las pruebas generalmente se ejecutan comorutinasutilizando el atributo[UnityTest]. Esto le permite probar código que puede ejecutarse en varios fotogramas. De forma predeterminada, las pruebas del modo Reproducción se ejecutarán en el Editor, pero también puedes ejecutarlas en una versión de reproductor independiente para varias plataformas de destino.

pruebas automatizadas
El paquete Controlador de personajes en tercera persona, disponible en Unity Asset Store
Cómo probar el marco de prueba de Unity

Para seguir este ejemplo, deberá instalar el paquete Starter Assets – Third Person Character Controller de Unity Asset Store e importarlo a un nuevo proyecto.

pruebas automatizadas
El archivo manifest.json
Configuración del marco de prueba de Unity

Instale UTF a través de Ventana> Administrador de paquetes. Busque Test Framework en el Registro de Unity en el Administrador de paquetes. Asegúrese de seleccionar la versión 1.3.3 (la última versión al momento de escribir este artículo).

Una vez instalado UTF, abra el archivo Packages/manifest.json con un editor de texto y agregue una sección testables después de las dependencias, como esta:

,
"testables": [
"com.unity.inputsystem"
]

Guarda el archivo. Esto será útil más adelante, cuando necesite hacer referencia al ensamblado Unity.InputSystem.TestFramework para probar y emular la entrada del reproductor.

Regrese al Editor y permita que se instale la versión más nueva.

pruebas automatizadas
Referencias de definición de ensamblaje en el inspector para el controlador de personajes en tercera persona
Definiciones de ensamblaje de prueba

Haga clic en Ventana > General > Test Runner para ver la ventana del editor de Test Runner .

En esta parte del tutorial, la atención se centrará en la creación de pruebas del modo Juego. En lugar de usar las opciones Crear carpeta de ensamblaje de prueba en la ventana Test Runner, las creará usando la ventana Proyecto.

Con la raíz de la carpeta Recursos del proyecto resaltada, haga clic con el botón derecho y elija Crear > Pruebas > Carpeta de ensamblaje de pruebas.

Se agrega una carpeta de proyecto de Pruebas que contiene un archivo Tests.asmdef (definición de ensamblado). Esto es necesario para que las pruebas hagan referencia a los módulos y dependencias de tu juego.

Se hará referencia al código del controlador de caracteres en las pruebas y también necesitará una definición de ensamblaje. A continuación, configurará algunas definiciones y referencias de ensamblados para facilitar las pruebas entre los módulos.

Haga clic con el botón derecho en la carpeta del proyecto Assets/StarterAssets/InputSystem y elija Crear > Definición de ensamblaje. Nómbralo con algo descriptivo, por ejemplo StarterAssetsInputSystem.

Seleccione el nuevo archivo StarterAssetsInputSystem.asmdef y, usando el Inspector, agregue una Referencia de definición de ensamblaje a Unity.InputSystem. Haga clic en Aplicar.

Haga clic con el botón derecho en la carpeta del proyecto Assets/StarterAssets/ThirdPersonController/Scripts y elija Crear > Definición de ensamblaje. Nómbralo con algo descriptivo, por ejemplo ThirdPersonControllerMain.

Como hizo con la definición de ensamblaje anterior, abra ThirdPersonControllerMain en el Inspector y seleccione referencias para:

- Unity.InputSystem

- StarterAssetsInputSystem

Haga clic en Aplicar.

pruebas automatizadas
Agregar referencias a definiciones de ensamblaje
Agregar referencias a definiciones de ensamblaje

Para emular partes del sistema de entrada, deberá hacer referencia a él en sus pruebas. Además, deberá hacer referencia al espacio de nombres StarterAssets en un ensamblado que creará para el código del controlador en tercera persona.

Abra Tests.asmdef en el Inspector y agregue una referencia a las siguientes definiciones de ensamblaje:

- UnityEngine.TestRunner

- UnityEditor.TestRunner

- Unity.InputSystem

- Unity.InputSystem.TestFramework

- ThirdPersonControllerMain

Haga clic en Aplicar.

Ventana «Build Settings» (Ajustes de compilación)
Ventana «Build Settings» (Ajustes de compilación)
Tu primera prueba

Su primera prueba cubrirá algunos conceptos básicos sobre cómo cargar y mover el personaje principal desde el paquete del controlador en tercera persona.

Comience configurando el nuevo proyecto con una escena de entorno de prueba simple y un recurso prefabricado de personajes con el cual trabajar.

Abra la escena denominada Assets/StarterAssets/ThirdPersonController/Scenes/Playground.unity y guarde una copia usando el menú Archivo > Guardar como en esta nueva ruta: Assets/Scenes/SimpleTesting.unity

Si observa materiales de color rosa en la vista del juego, utilice el Convertidor de canalización de renderizado para actualizar los materiales del Canalización de renderizado incorporado al Canalización de renderizado universal (URP). Consulte este artículo para obtener una descripción general rápida.

Cree una nueva carpeta en su carpeta Recursos del proyecto llamada Recursos. Nota: El nombre de la carpeta "Recursos" es importante aquí para permitir que se utilice el método Unity Resources.Load() .

Arrastre y suelte PlayerArmature GameObject en la vista Escena en la nueva carpeta Recursos y elija crear un Prefab original cuando se le solicite. Cambie el nombre del activo prefabricado Carácter.

Este será el carácter base que Prefab utilizará en sus pruebas en el futuro.

Elimine PlayerArmature GameObject de la nueva escena SimpleTesting y guarde los cambios en la escena.

Para el último paso en la configuración de prueba inicial, vaya a Archivo > Configuración de compilacióny elija Agregar escenas abiertas para agregar la escena Escenas/SimpleTesting a la configuración de compilación.

Crear un script de prueba de C#

Seleccione la carpeta Pruebas en la carpeta Activos del proyecto. Haga clic con el botón derecho y elija Crear>Pruebas>Script de prueba de C#.

Nombra el nuevo script CharacterTests. Abra el script en su IDE para verlo más de cerca.

Se proporcionan dos resguardos de métodos con el archivo de clase inicial, que demuestran algunos conceptos básicos de prueba.

A continuación, se asegurará de que las pruebas carguen una escena de juego "centrada en las pruebas". Esta debería ser una escena que contenga lo mínimo necesario para probar el sistema o componente en el que te estás centrando.

Actualice la clase CharacterTests para agregar dos nuevas declaraciones de uso e implemente la clase InputTestFixture :

using UnityEngine.InputSystem;
using UnityEngine.SceneManagement;

Pruebas de caracteres de clase pública: InputTestFixture

Agregue dos campos privados en la parte superior de la clase CharacterTests:

GameObject character = Resources.Load<GameObject>("Character");
Teclado teclado;

El campo de personaje almacenará una referencia al personaje prefabricado, cargado desde la carpeta Recursos. El teclado contendrá una referencia al dispositivo de entrada del teclado proporcionado por InputSystem.

Anule el método Setup() de la clase base InputTestFixture proporcionando el suyo propio en la clase CharacterTests:

anulación pública de configuración anulada()
{
SceneManager.LoadScene("Scenes/SimpleTesting");
base.Setup();
keyboard = InputSystem.AddDevice<Keyboard>();

var mouse = InputSystem.AddDevice<Mouse>();
Press(mouse.rightButton);
Release(mouse.rightButton);;
}

El método Setup() ejecuta el método Setup() de la clase base y luego configura su propia clase CharacterTests cargando la escena de prueba e inicializando el dispositivo de entrada del teclado.

La entrada del mouse se agrega únicamente para que el controlador en tercera persona comience a recibir entradas desde el dispositivo de teclado virtual/simulado. Esto es casi como una acción de "establecer enfoque".

Para su primera prueba, creará una instancia del personaje del Prefab y afirmará que no es nulo. Agregue el siguiente método a su clase de prueba:

[Test]
public void TestPlayerInstantiation()
{
GameObject CharacterInstance = GameObject.Instantiate (carácter, Vector3.zero, Quaternion.identity);
Assert.That(characterInstance, !Is.Null);
}

Mientras esté allí, es posible que desee limpiar los métodos de prueba de la plantilla de muestra. Elimine los métodos CharacterTestsSimplePasses y CharacterTestsWithEnumeratorPasses .

prueba aprobada
La marca de verificación verde significa que la prueba ha pasado con éxito
Pasando tu primera prueba

Guarde el script y regrese a la ventana Test Runner en el Editor. Resalte la prueba TestPlayerInstantiation y haga clic en Ejecutar seleccionados.

La marca de verificación verde significa que se aprobó la prueba. Ha afirmado que el personaje se puede cargar desde recursos, crear una instancia en la escena de prueba y no es nulo en ese momento.

Es posible que haya notado que se usó la anotación [Prueba] para esta prueba en lugar de la anotación [UnityTest] . El atributo UnityTest permite que las corrutinas ejecuten pruebas en varios fotogramas. En este caso, sólo necesita crear una instancia del personaje y afirmar que se cargó.

Generalmente, debe usar el atributo NUnit Test en lugar del atributo UnityTest en el modo Edición, a menos que necesite dar instrucciones especiales, omitir un fotograma o esperar una cierta cantidad de tiempo en el modo Reproducir.

Probando el movimiento del personaje en el modo Jugar
Probando el movimiento del personaje en el modo Jugar
Pruebas de movimiento de personajes.

A continuación, utilizará UnityTest para afirmar que mantener presionada la tecla del controlador de avance mueve el personaje hacia adelante.

Agregue el nuevo método de prueba que se proporciona a continuación a su clase CharacterTests.

Han aparecido dos nuevos métodos auxiliares de prueba; Presione y suelte(). Ambos son proporcionados por la clase base InputTestFixture y le ayudan a emular el control de InputSystem presionando y soltando.

El método TestPlayerMoves() hace lo siguiente:

Crea una instancia del personaje a partir del personaje Prefab en la ubicación(X: 0, Y: 0, Z: 0)

Presiona la tecla de flecha hacia arriba en el teclado virtual durante 1 segundo y luego la suelta

Espera 1 segundo más (a que el personaje disminuya la velocidad y deje de moverse)

Afirma que el personaje se ha movido a una posición en el eje Z mayor a 1,5 unidades.

Guarde el archivo, regrese al Test Runner y ejecute la nueva prueba.

El guión de salud del jugador
El guión de salud del jugador
Prueba de daños por caída

A continuación, probará un script Monobehaviour personalizado agregando un componente simple de Salud del jugador.

Cree un nuevo script en Assets/StarterAssets/ThirdPersonController/Scripts. Nómbrelo PlayerHealth.

Abra el script en su IDE y reemplace el contenido con el código que se proporciona a continuación.

Hay mucho código nuevo agregado aquí. Para resumirlo, este script determinará si el personaje del jugador está en estado de caída. Si el suelo se golpea una vez en estado de caída, la salud del personaje se reduce en un 10%.

Localice el personaje prefabricado en Activos/Recursos. Abra el Prefab y agregue el nuevo componente de script PlayerHealth.

A continuación, usarás la escena de prueba para afirmar que la salud del jugador disminuye después de caerse de una cornisa.

Con el atributo [UnityTest], puede escribir una prueba del modo de juego que pruebe los daños por caída. Al caer durante más de 0,2 segundos, el jugador debería sufrir 0,1f de daño (el equivalente al 10% de la salud máxima).

En la escena SimpleTesting , verás una escalera que conduce a una repisa. Esta es una plataforma de prueba para generar el personaje y probar el script PlayerHealth .

Abra CharacterTests.cs nuevamente y agregue un nuevo método de prueba llamado TestPlayerFallDamage:

[UnityTest]
public IEnumerator TestPlayerFallDamage()
{
// genera el personaje en un área lo suficientemente alta en la escena de prueba
GameObject CharacterInstance = GameObject.Instantiate (carácter, nuevo Vector3 (0f, 4f, 17.2f), Quaternion.identity);

// Obtener una referencia al componente PlayerHealth y afirmar que actualmente se encuentra en pleno estado de salud (1f)
var characterHealth = characterInstance.GetComponent<PlayerHealth>();
Assert.That(characterHealth.Health, Is.EqualTo(1f));

// Baja de la cornisa y espera la caída.
Press(keyboard.upArrowKey);
rendimiento devuelve nuevo WaitForSeconds(0.5f);
Release(keyboard.upArrowKey);
rendimiento devolver nuevo WaitForSeconds(2f);

// Afirma que se perdió 1 punto de vida debido al daño de la caída
Assert.That(characterHealth.Health, Is.EqualTo(0.9f));
}

También necesitarás agregar una referencia de uso al espacio de nombres StarterAssets en la parte superior del archivo de clase:

utilizando StarterAssets;

La prueba anterior sigue un patrón típico de organizar, actuar y afirmar (AAA), que se encuentra comúnmente en las pruebas:

La secciónOrganizarde un método de prueba unitaria inicializa objetos y establece el valor de los datos que se pasan al método bajo prueba.

La secciónActinvoca el método bajo prueba con los parámetros organizados. En este caso, la invocación del método bajo prueba se maneja mediante una interacción física cuando el jugador golpea el suelo después de caer.

La sección Assert verifica que la acción del método bajo prueba se comporta como se esperaba.

Ejecutor de pruebas: ejecutar pruebas
Una prueba para garantizar que un personaje caiga en el juego según lo previsto, incluida la cantidad correcta de daño.
Ejecutando la nueva prueba

De vuelta en el Editor, ejecute la nueva prueba. Al correr en el modo Jugar, verás al personaje caminar por el borde, caer (superando el umbral de 0,2 segundos para categorizar una caída) y recibir daño después de golpear el suelo.

Las pruebas no solo sirven para comprobar que los cambios de código no afectan la funcionalidad, sino que también pueden servir como documentación o sugerencias para ayudar a los desarrolladores a pensar en otros aspectos del juego al modificar la configuración.

Cómo hacer que la prueba se ejecute en una compilación de reproductor independiente
Cómo hacer que la prueba se ejecute en una compilación de reproductor independiente
Ejecución de pruebas en el reproductor independiente
Automatización y CI

Una vez que haya comenzado a crear un conjunto de pruebas, el siguiente paso es ejecutarlas automáticamente una vez completadas las compilaciones. Las pruebas unitarias y de integración automatizadas que se ejecutan después de la compilación son útiles para detectar regresiones o errores lo antes posible. También pueden ejecutarse como parte de un sistema de construcción automatizado remoto en la nube.

Separa la compilación de la ejecución

A menudo, querrás capturar los resultados de las pruebas en un formato personalizado para que los resultados puedan compartirse con una audiencia más amplia. Para capturar los resultados de las pruebas fuera del Editor de Unity, deberá dividir los procesos de compilación y ejecución.

Cree un nuevo script en la carpeta de su proyecto de Pruebas llamado SetupPlaymodeTestPlayer.

La clase SetupPlaymodeTestPlayer implementará la interfaz ITestPlayerBuildModifier. Utilizará esto para anular y "enganchar" el método ModifyOptions, que recibe las opciones del reproductor de la compilación y le permite modificarlas.

using System.IO;
using UnityEditor;
using UnityEditor.TestTools;

[asamblea: TestPlayerBuildModifier(typeof(SetupPlaymodeTestPlayer))]
clase pública SetupPlaymodeTestPlayer: ITestPlayerBuildModifier
{
pública 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;

devolver opciones de jugador;
}
}

Este script modificador personalizado de Player Build hace lo siguiente cuando las pruebas se ejecutan en modo Reproducir (Ubicación de ejecución: En el jugador):

Desactiva la ejecución automática para reproductores integrados y omite la opción del reproductor que intenta conectarse al host en el que se está ejecutando.

Cambia la ubicación de la ruta de compilación a una ruta dedicada dentro del proyecto (TestPlayers)

Una vez completado esto, ahora puede esperar que las compilaciones se ubiquen en la carpeta TestPlayers cada vez que terminen de compilarse. Esto ahora completa las modificaciones de la compilación y corta el vínculo entre la compilación y la ejecución.

A continuación, implementará el informe de resultados. Esto le permitirá escribir los resultados de las pruebas en una ubicación personalizada, lista para la generación y publicación automatizada de informes.

Cree un nuevo script en la carpeta de su proyecto de Pruebas llamado ResultSerializer (que se proporciona a continuación). Esta clase utilizará una referencia de ensamblado a TestRunCallback e implementará la interfaz ITestRunCallback.

Esta implementación de ITestRunCallback incluye un método RunFinished personalizado, que es lo que configura una compilación de reproductor con pruebas para escribir los resultados de las pruebas en un archivo XML denominado testresults.xml.

Código
Los resultados pueden verse en el archivo testresults.xml que se encuentra en la ubicación Application.persistentDataPath de tu plataforma
Ejecutar una prueba después de dividir la compilación y la ejecución

Con SetupPlaymodeTestPlayer.cs y ResultSerializer.cs combinados, los procesos de compilación y ejecución ahora están divididos. La ejecución de pruebas generará los resultados en testresults.xml ubicado en la ubicaciónApplication.persistentDataPath de la plataforma del reproductor.

Para usar algunos de los tipos en estas clases de enlace, deberá agregar una referencia adicional a Tests.asmdef. Actualícelo para agregar la referencia de definición del ensamblado UnityEditor.UI.EditorTests.

La ejecución de las pruebas en el reproductor ahora generará un resultado de compilación del reproductor en su proyecto en la carpeta TestPlayers y un archivo testresults.xml en la ubicación Application.persistentDataPath.

Arte de portada de libro electrónico
Más recursos sobre pruebas en Unity

Curso Marco de pruebas de Unity

El paquete Test Framework incluye un curso de pruebas con ejercicios de muestra para ayudarle a aprender más sobre las pruebas con Unity. Asegúrese de obtener los archivos del proyecto del curso utilizando el Administrador de paquetes.

Usando el Administrador de paquetes>Paquetes: Registro de unidad>Test Framework, ubique la lista desplegable Ejemplos e importe los ejercicios del curso.

Los ejercicios se importarán a su proyecto y se ubicarán en Activos/Muestras/Marco de prueba. Cada muestra incluye una carpeta de ejercicios en la que puede trabajar, así como una solución para comparar su propio trabajo a medida que avanza.

Control de calidad de su código con UTF

Esta charla de Unite Copenhagen sobre UTF entra en más detalles y ofrece algunos otros casos de uso interesantes para la personalización de pruebas. Asegúrese de comprobarlo para ver qué más es posible.

Depuración en Unity

Acelere su flujo de trabajo de depuración en Unity con artículos sobre:

-Microsoft Visual Studio 2022

- Código de Microsoft Visual Studio

Libros electrónicos técnicos avanzados

Unity proporciona una serie de guías avanzadas para ayudar a los desarrolladores profesionales a optimizar el código del juego. Cree una guía de estilo de C#: Escriba código más limpio y escalable recopila consejos de expertos de la industria sobre cómo crear una guía de estilo de código para ayudar a su equipo a desarrollar una base de código limpia, legible y escalable.

Otra guía popular entre nuestros usuarios son más de 70 consejos para aumentar la productividad con Unity. Está repleto de consejos para ahorrar tiempo y mejorar su flujo de trabajo agregado diario con Unity 2020 LTS, incluidos consejos que incluso los desarrolladores experimentados podrían haberse perdido.

Documentación

Explore más a fondo la API TestRunner más reciente, conozca otros atributos personalizados de UTF y descubra más ciclos de vida a los que conectarse con la documentaciónde UTF.

Encuentre todos los libros electrónicos y artículos avanzados de Unity en el centro de mejores prácticas de Unity.

¿Te gustó este contenido?