Estoy codificando un juego en mi tiempo libre, pero aún soy un principiante en lo que respecta a la programación. Lo siento si esta pregunta está fuera de tema o si termina no siendo útil para nadie más, pero espero que lo sea.
He pasado mucho tiempo leyendo libros sobre el diseño de código, así como diferentes metodologías y enfoques de codificación. En el curso de esta investigación sigo topando con el concepto de Test Driven Development. Las personas que defienden esta idea generalmente parecen muy apasionadas. Creo que puede ayudar a la velocidad y eficiencia del software de escritura. El tiempo es un recurso muy valioso, por lo que preferiría aprender a hacer las cosas de la mejor manera en lugar de confundirme sin tratar de ampliar mi conocimiento de la programación.
De todos modos, posiblemente porque soy un principiante, no puedo imaginar cómo aplicar el desarrollo basado en pruebas a los juegos. Encontré un par de artículos sobre el tema pero no fueron de mucha ayuda. La mayoría de los ejemplos de pruebas unitarias que he visto son ejemplos muy simples, o ejemplos de software que no se parece en nada a un juego.
En mi propia codificación, trato de abordarlo con una mentalidad similar para probar el desarrollo impulsado, aunque estoy seguro de que en realidad no califica como TDD. Escribo la cantidad mínima de código para intentar implementar cualquier característica que agregue al juego, y luego pruebo inmediatamente el juego para ver si funciona. Si las cosas no suceden como pretendía, inmediatamente hago cambios para acercarme a lo que quiero. Si no funciona o no funciona, y si no puedo encontrar los errores leyendo el código, paso por los métodos en el depurador hasta que encuentre el comportamiento inesperado, y luego lo elimino. Lo que intento decir es que constantemente estoy probando el juego, más o menos después de cada cambio incremental. Las pruebas impulsan mi desarrollo. La "prueba unitaria" está en mi cabeza,
A mi pregunta real. ¿Cómo se pueden escribir pruebas unitarias para un juego complejo? Por complejo, quiero decir con muchos aspectos emergentes del juego, de modo que la esencia del juego surge de la interacción entre los diferentes elementos dentro del juego combinados con las elecciones del jugador. Por ejemplo, un RPG roguelike con un mundo procesal. ¿Qué tipo de pruebas unitarias escribiría para un juego como ese? ¿Cómo se podría aplicar el desarrollo impulsado por pruebas a un juego así?
Respuestas:
Las pruebas unitarias no prueban el juego . No hay criterios programáticos para ver si un juego es divertido o si un nivel es la dificultad correcta. Las pruebas unitarias comprobarán que tu mapgen roguelike realmente produce un nivel con una escalera arriba y una escalera abajo. Pondrá a prueba que sus reglas de gravamen están configuradas para que su personaje realmente se mueva más lento cuando está ponderado. Se asegurará de que tu personaje no pueda usar 50 sombreros . Se asegurará de que todas las mecánicas se implementen correctamente en un relativo aislamiento.
fuente
Es difícil escribir pruebas unitarias para código que no sea determinista. Si tiene un código que involucra números aleatorios, no podrá escribir una prueba unitaria que afirme un resultado esperado.
Entonces, las pruebas unitarias son más apropiadas para el código que es determinista. Cuando le doy a un método estas entradas, espero estas salidas. Como ejemplo: cuando un luchador con 15 puntos de fuerza usa su espada ancha de dos manos para golpear con éxito a un demonio no muerto con 10 armaduras, espero 8 daños. La parte no determinista (si el golpe fue exitoso o no) no necesariamente puede ser probada por unidad, pero lo que sucede después puede serlo. Incluso si se espera que la cantidad de daño esté dentro de cierto rango, puede probarlo.
Si tiene dificultades para encontrar código para escribir pruebas unitarias, debe refactorizar para que la lógica determinista esté aislada en métodos o clases. Tira los dados primero para determinar el éxito, luego pasa las entradas relevantes (clase, fuerza, armadura, etc.) a un método comprobable.
Para su comentario acerca de tener la prueba de la unidad en su cabeza, el punto de la prueba de la unidad no es solo el código recién escrito. También se trata de tener confianza en que el código aún funciona después de hacer cambios inevitables .
fuente
IRandomNumberGenerator
) y cualquier cosa que necesite usar números aleatorios acepta una referencia a esa interfaz de servicio en su constructor. Luego, cuando su prueba crea ese objeto para ejecutar una prueba unitaria, inyecta unMockRandomNumberGenerator
que alimenta un flujo fijo de números conocidos. Entonces tienes una prueba repetible. La misma idea es útil para cualquier cosa que necesite obtener la fecha / hora actual o descargar información de un servicio web, simplemente inyecte un servicio simulado.RandomNumberGenerator
.