unit testing - unitarias - Prueba automatizada de un juego
unit test c# visual studio 2013 (10)
Los valores son tan aleatorios dentro de los aspectos de desarrollo del juego que sería una idea exagerada probar valores absolutos
Pero podemos probar valores deterministas. Por ejemplo, una prueba unitaria podría hacer que Guybrush Threepwood se mueva hacia una puerta (pathfinding), abra la puerta (use el comando), falle porque no tiene una clave en su inventario (feedback), elija la tecla de la puerta (pathfinding + inventario) administración) y luego finalmente abrir la puerta.
Todos estos caminos son deterministas. Con esta prueba de unidad, puedo refactorizar el administrador de memoria y si de alguna manera se rompió la rutina de administración de inventario, la prueba de unidad fallaría.
Esta es solo una idea para probar unidades en juegos. Me encantaría saber otras ideas, por lo tanto, la motivación para esta publicación.
Pregunta
¿Cómo agregarías pruebas automatizadas a un juego?
Creo que puedes probar un montón de la funcionalidad del motor del juego (creación de redes, creación de objetos, administración de memoria, etc.), pero ¿es posible automatizar la prueba del juego en sí?
No estoy hablando de elementos de juego (como Protoss vencería a Zerg en el mapa X), pero estoy hablando de la interacción entre el juego y el motor.
Introducción
En el desarrollo del juego, el motor es solo una plataforma para el juego. Podrías pensar en el motor del juego como un sistema operativo y el juego como un software que el SO ejecutaría. El juego podría ser una colección de scripts o una subrutina real dentro del motor del juego.
Respuestas posibles
Mi idea es esta:
Necesitarías un motor que sea determinista. Esto significa que dado un conjunto de entrada, la salida sería exactamente la misma. Esto incluiría el generador aleatorio sembrado con la misma entrada.
Luego, cree un nivel básico que contenga un par de objetos con los que el avatar / usuario pueda interactuar. Comience poco a poco y luego agregue objetos al nivel a medida que se desarrollan más interacciones.
Cree un script que siga una ruta (prueba pathfinding) e interactúe con los diferentes objetos (almacene el resultado o el comportamiento esperado). Este script sería tu prueba automatizada. Después de una cierta cantidad de tiempo (por ejemplo, una semana), ejecute el script junto con las pruebas de unidad de su motor.
Esto realmente no responde a su pregunta, pero estaba escuchando un podcast en Pex de Microsoft que hace algo similar a la solución que está proponiendo y cuando lo escuché recuerdo haber pensado que sería realmente interesante ver si sería capaz de probar juegos. No sé si podría ayudarte específicamente, pero tal vez podrías echar un vistazo a algunas de las ideas que usan y aplicarlas a las pruebas de tu unidad.
Hice algo similar a tu idea una vez y fue muy exitoso, aunque sospecho que en realidad es más una prueba del sistema que una prueba unitaria. Al sugerir que su generador de números aleatorios debe ser sembrado con el mismo valor, y debe producir una secuencia idéntica cada vez. El juego corría en ciclos de 50 Hz, por lo que el tiempo no era un problema. Tenía un sistema que registraba los clics y ubicaciones del mouse y lo usaba para generar manualmente un ''script'' que se podía reproducir para producir los mismos resultados. Al eliminar los retrasos de tiempo y desactivar la generación de gráficos, una hora de juego podría replicarse en unos pocos segundos. El mayor problema era que los cambios en el diseño del juego invalidaban el guión.
Si su sala de barebones contenía lógica que era independiente del juego en general, podría funcionar muy bien. El motor podría arrancar sin ningún ui e iniciar el script tan pronto como se complete la inicialización. Las pruebas de colisión en el camino serían simples, pero las pruebas más complejas, como dejar a los personajes en las posiciones correctas, serían más complejas. Si la grabación de las secuencias de comandos es lo suficientemente simple, que estaban en mi sistema, entonces pueden actualizarse muy fácilmente, y las secuencias de comandos especiales para probar el comportamiento especializado se pueden configurar muy rápidamente. Mi sistema tenía la ventaja adicional de que podía usarse durante las pruebas del juego y la secuencia exacta de los eventos grabados para facilitar la corrección de errores.
Si está probando el motor de renderizado, creo que podría renderizar escenas de prueba específicas, hacer una captura de pantalla y compararlas con las representaciones de prueba de referencia. De esta forma puede detectar si los cambios en el motor rompen cualquier cosa, visualmente. Puede escribir una prueba similar para el motor de sonido, o incluso animación (comparando una serie de cuadros).
Si desea probar la lógica del juego o el progreso de la escena, puede hacerlo probando varias condiciones en las variables de scripting (suponiendo que esté usando scripts para implementar la mayoría de los aspectos de la escena y la historia).
Si está utilizando XNA (la idea podría extrapolarse a otros marcos, por supuesto), podría usar un marco de pruebas de unidades en el juego que le permita acceder al estado del juego en la prueba unitaria. Uno de estos frameworks es Scurvy.Test :-)
Esta publicación en Games From Within podría ser relevante / interesante.
http://flea.sourceforge.net/gameTestServer.pdf
Esta es una discusión interesante sobre la implementación de un probador funcional completo en un juego.
El término "prueba unitaria" implica que se está probando una "unidad". Esta es una cosa. Si realiza pruebas de nivel superior (por ejemplo, varios sistemas a la vez), generalmente esto se denomina prueba funcional. Es posible probar muchas unidades de un juego, sin embargo, no se puede probar para la diversión.
El determinismo no es necesario, siempre y cuando sus pruebas puedan ser borrosas. Por ejemplo, "el personaje se lastimó" en lugar de "el personaje perdió 14.7 puntos de vida".
Escribí un artículo sobre ese tema - http://download.springer.com/static/pdf/722/art%253A10.7603%252Fs40601-013-0010-4.pdf?auth66=1407852969_87bc2e71ad5228b36738f0237084ebe5&ext=.pdf
Riot Games tiene un artículo sobre el uso de pruebas automatizadas para League of Legends (LoL), un juego de estrategia en tiempo real en línea multijugador.
Según los desarrolladores, hay muchos cambios en el código del juego y en el equilibrio del juego todos los días. Crearon un marco de prueba de Python que básicamente es un cliente de juego más simple que envía comandos al servidor de Integración Continua que está ejecutando una instancia del servidor de juego de LoL. El servidor luego envía el marco de prueba al efecto del comando, permitiendo que la respuesta sea probada.
El marco proporciona una cola de eventos que registra los eventos, datos y efectos desde un punto particular en el tiempo. El artículo lo llama una "instantánea".
El artículo describía un ejemplo de prueba unitaria para un hechizo:
Preparar
1. Dale a un personaje la habilidad.
2. Engendre un personaje enemigo en la línea central (una ubicación en el mapa).
3. engendrar un creep en el medio de la calle. (En el contexto de LoL, los creeps son débiles personajes no controlables que forman parte del ejército de cada equipo. Son básicamente forraje de canónigo y una fuente de experiencia y oro para el equipo enemigo. Pero si no se controlan, pueden abrumar a los oponentes. equipo) 4. Teletransporta el personaje a la línea media.
Ejecutar
1. Tome una instantánea de todas las variables (por ejemplo, la vida actual del jugador, enemigo y personajes normales).
2. Lanza el hechizo.
3. Activa los efectos del hechizo (por ejemplo, hay algunos hechizos que se procesarán al golpear) en un personaje enemigo.
4. Restablece el tiempo de reutilización del hechizo para que pueda ser lanzado de nuevo inmediatamente.
5. Lanza el hechizo.
6. Activa los efectos del hechizo en un creep (en el contexto de LoL, la mayoría de los hechizos tienen diferentes cálculos cuando se usan en creeps). 7. Toma otra instantánea.
Verificar
A partir de la primera instantánea, repita los eventos y afirme que los resultados esperados (desde el punto de vista del diseñador de juegos) son correctos. Ejemplos de eventos que se pueden verificar son: el daño está dentro del rango del daño del hechizo (LoL usa números aleatorios para dar variación a los ataques), el daño se resiste adecuadamente cuando se compara con un personaje de jugador y un deslizamiento, y los hechizos se lanzan dentro su rango efectivo
El artículo muestra que se puede extraer un video de la prueba cuando el servidor de prueba se ve desde un cliente de juego normal.
Ya se mencionó un artículo de Power of Two Games Games From Within en otra respuesta, pero sugiero leer todo (o casi todo) allí, ya que están muy bien escritos y se aplican directamente al desarrollo de juegos. El artículo sobre Assert es particularmente bueno. También puede visitar su sitio web anterior en Games From Within , que tiene mucho escrito sobre Test Driven Development , que es una prueba unitaria llevada al extremo.
Los Power of Two son los que implementaron UnitCpp, un marco de pruebas de unidades bastante respetado. Personalmente, prefiero WinUnit .