Probar sin darle mil veces al Play#
Cada vez que cambias algo, ¿vuelves a jugar entero para comprobar que no rompiste nada? Eso no escala. Las pruebas automáticas ejecutan por ti comprobaciones de que tu código sigue funcionando, en segundos. Unity trae el Unity Test Framework (basado en NUnit) para esto.
Un videojuego tiene mucho que es subjetivo y visual (¿es divertido?, ¿se ve bien?), y eso no se testea automáticamente. Pero la lógica sí: cálculo de daño, reglas de inventario, condiciones de victoria, guardado/carga. Testea la lógica, prueba a mano lo demás.
Dos modos de test#
Abre Window → General → Test Runner. Hay dos tipos:
- Edit Mode: pruebas que corren sin ejecutar el juego, rápidas. Ideales para lógica pura (una fórmula, una regla, una utilidad) que no depende del ciclo de vida de Unity.
- Play Mode: pruebas que corren con el juego en marcha, con GameObjects reales, física y frames. Para comportamientos que sí dependen de Unity (que un objeto se destruye, que una colisión resta vida).
Escribir un test#
Primero, crea un assembly de test desde el Test Runner (te genera la carpeta y el .asmdef necesarios). Un test es un método con [Test] que afirma (Assert) lo que debería ocurrir:
using NUnit.Framework;
public class CalculadoraDañoTests
{
[Test]
public void ElDañoNoReduceLaVidaPorDebajoDeCero()
{
var salud = new Salud(vidaMax: 100);
salud.RecibirDaño(150); // más daño que vida
Assert.AreEqual(0, salud.VidaActual); // no baja de 0
}
[Test]
public void CurarNoSuperaLaVidaMaxima()
{
var salud = new Salud(vidaMax: 100);
salud.RecibirDaño(30); // 70
salud.Curar(9999);
Assert.AreEqual(100, salud.VidaActual); // tope en el máximo
}
}El patrón es AAA: Arrange (preparas), Act (ejecutas la acción), Assert (compruebas el resultado). Si un Assert falla, el test se pone en rojo y sabes exactamente qué se rompió.
Fíjate en que Salud del ejemplo es una clase plana, sin depender de MonoBehaviour. El código fácil de testear suele ser código bien diseñado: lógica separada de Unity, sin dependencias ocultas. Si algo es imposible de testear, muchas veces es señal de que está demasiado acoplado. Testear mejora tu arquitectura casi sin querer.
Play Mode: probar comportamiento en escena#
Para lo que necesita el motor, un test de Play Mode puede esperar frames con corrutinas:
using System.Collections;
using UnityEngine;
using UnityEngine.TestTools;
using NUnit.Framework;
public class ProyectilTests
{
[UnityTest]
public IEnumerator ElProyectilSeDestruyeTrasSuVida()
{
var go = new GameObject();
var proyectil = go.AddComponent<Proyectil>(); // vida de 1 segundo
yield return new WaitForSeconds(1.1f);
Assert.IsTrue(proyectil == null); // se autodestruyó
}
}Qué testear (y qué no)#
- ¿Lógica con reglas claras (daño, economía, inventario, guardado, condiciones de victoria)? → Sí, testéalo: barato y muy rentable
- ¿Sistemas críticos donde un fallo arruina partidas (guardado/carga)? → Sí, prioritario
- ¿"Se siente bien" el salto, se ve bonito el efecto, es divertido? → No automatizable: prueba a mano (playtesting)
- ¿Prototipo desechable que cambiará mañana? → No malgastes tests aún
Testing y trabajo en equipo#
Las pruebas brillan en equipo (ver flujo de trabajo en equipo): se ejecutan automáticamente en cada cambio subido (integración continua), y avisan si alguien rompió algo sin darse cuenta. Es una red de seguridad que evita el clásico "funcionaba antes de tu commit".
Errores frecuentes#
- Intentar testear lo subjetivo (diversión, aspecto) con pruebas automáticas.
- No separar la lógica de
MonoBehavioury hacerla imposible de testear. - Olvidar crear el assembly de test (
.asmdef) y que no compilen. - Tests frágiles que dependen de tiempos exactos o de una escena concreta.
- Escribir tests para un prototipo que vas a tirar.
Ponte a prueba#
Resumen#
El Unity Test Framework (NUnit) automatiza las pruebas: Edit Mode para lógica pura (rápido) y Play Mode para comportamiento con el motor en marcha. Escribe tests con el patrón AAA (Arrange-Act-Assert) sobre lo que tiene reglas claras (daño, inventario, guardado, victoria); lo subjetivo (diversión, aspecto) se prueba a mano. Testear empuja a un código mejor diseñado (lógica separada de MonoBehaviour) y es una red de seguridad clave en equipo con integración continua.