¿Es práctico usar un marco de prueba como JUnit en una situación de desarrollo de juegos? ¿Qué tipo de consideraciones de diseño puedes seguir para que tu juego sea más comprobable? ¿Qué partes de un juego pueden / deben probarse y qué partes deben / deben dejarse a prueba en humanos?
Por ejemplo, si el ciclo del juego está encapsulado en una función, parece que sería terriblemente difícil de probar. Me gusta refactorizar una función de "actualización" que toma un tiempo delta y avanza la lógica del juego; Esto permite algunos trucos interesantes, como la capacidad de ralentizar el juego al alimentarlo con deltas falsos y más lentos.
architecture
unit-testing
Ricket
fuente
fuente
Respuestas:
Uno de los principios de TDD es que permite que TDD en algunos casos influya en su diseño. Escribes una prueba para el sistema, luego escribes el código para pasar esa prueba, mantienes las dependencias lo más superficial posible.
Para mí, solo hay dos cosas que no pruebo como parte de las pruebas unitarias:
Primero, no pruebo los elementos visuales y cómo se ven las cosas. Lo pruebo y el objeto estará en el lugar correcto después de actualizarse, que una cámara eliminará un objeto fuera de sus límites, que las transformaciones (al menos las que se realizan fuera de los sombreadores) se realizan correctamente antes de ser entregadas al motor gráfico , pero una vez que llega al sistema de gráficos, trazo la línea. No me gusta tratar de burlarme de cosas como DirectX.
En segundo lugar, realmente no pruebo la función principal del bucle del juego. Compruebo que cada sistema funcionará cuando pase un delta razonable, y que los sistemas funcionen juntos correctamente cuando lo necesiten. Luego solo actualizo cada sistema con el delta correcto en el bucle del juego. En realidad, podría tener una prueba para mostrar que cada sistema recibió una llamada con el delta correcto, pero en muchos casos encuentro esa exageración (a menos que esté haciendo una lógica compleja para obtener su delta, entonces no es una exageración).
fuente
Noel Llopis ha cubierto las pruebas unitarias en la medida que creo que está buscando:
Con respecto a probar todo el ciclo del juego, existe otra técnica para evitar regresiones funcionales en su código. La idea es hacer que su juego se juegue a través de un sistema de repetición (es decir, primero registrar las entradas del jugador y luego reproducirlas en una ejecución diferente). Durante la reproducción, genera una instantánea del estado de cada objeto para cada cuadro. Esta colección de estados puede llamarse la "imagen dorada". Al refactorizar su código, ejecuta la reproducción nuevamente y compara el estado de cada cuadro con el estado de la imagen dorada. Si difiere, la prueba ha fallado.
Si bien los beneficios de esta técnica son obvios, hay algunas cosas con las que debe tener cuidado:
fuente
Estoy de acuerdo con los comentarios de Jeff y jpaver. También quería agregar que la adopción de un modelo de componentes para su arquitectura aumenta enormemente su capacidad de prueba. Con un modelo de componente, cada componente debe realizar una sola unidad de trabajo y debe poder probarse de forma aislada (o con objetos simulados limitados).
Del mismo modo, las otras partes del juego que dependen de entidades solo deberían depender de un subconjunto de componentes para funcionar. En la práctica, esto significa que generalmente puede burlarse de algunos componentes falsos para facilitar la prueba de estas áreas o simplemente puede componer entidades parciales para fines de prueba. por ejemplo, omite los componentes de renderizado y entrada porque no son necesarios para probar la física.
Finalmente, ignoraría los consejos sobre el rendimiento que recibe de algunas personas en la comunidad del juego con respecto a las interfaces. Escriba bien el código con las interfaces y si se encuentra con problemas de rendimiento en el futuro, puede fácilmente perfilar, identificar y refactorizar para resolver el problema. No me convencieron las preocupaciones de Noel sobre el impacto en el rendimiento de las interfaces o la complejidad de la sobrecarga que agregaron.
Dicho esto, no te excedas tratando de probar cada pequeña cosa de forma independiente. Como la mayoría de las cosas, las pruebas y el diseño tienen que ver con lograr el equilibrio adecuado.
fuente
Pensé que agregaría una segunda respuesta en respuesta al comentario del OP de que el usuario podría reemplazar las pruebas unitarias. Creo que eso es completamente incorrecto ya que el propósito de las pruebas unitarias no es garantizar la calidad. Si desea realizar pruebas para garantizar la calidad de su programa, probablemente debería investigar las pruebas de escenarios o invertir en un excelente monitoreo.
(Con una excelente supervisión y un producto que se ejecuta como servicio, de hecho es posible aplicar algunas "pruebas" al cliente, pero debe tener un sistema sofisticado que detecte los errores rápidamente y revierta los cambios responsables. Lo más probable es que esto sea demasiado para un pequeño equipo de desarrollo)
El principal beneficio de las pruebas unitarias es que obligan al desarrollador a escribir código mejor diseñado. El acto de probar desafía al desarrollador a separar las preocupaciones y encapsular los datos. También alienta al desarrollador a usar interfaces y otras abstracciones para que pruebe solo una cosa.
fuente