Estoy tratando de adoptar TDD en mi práctica de programación diaria. Lo uso en el trabajo de manera muy efectiva, pero tengo problemas con mis proyectos personales en los que uso algunos algoritmos complejos.
El algoritmo particular que me hace hacer esta pregunta es el filtro extendido de Kalman. Es lo suficientemente complejo como para no tener confianza en el código que he escrito, pero es lo suficientemente simple como para que sea difícil de romper.
Podría escribir una prueba para el algoritmo con una entrada y la salida esperada, pero haré un montón de codificación de escopeta en el medio porque no tengo confianza en esos pasos intermedios.
Si ha trabajado con algoritmos complejos razonables y utiliza TDD, ¿cuál es su enfoque?
algorithms
tdd
Munk
fuente
fuente
Respuestas:
TDD no es un sustituto del diseño.
Este es un error común sobre TDD, que de alguna manera puede "hacer crecer" un diseño coherente de red-green-refactor. No puedes Sus pruebas aún deben guiarse por sus habilidades de diseño.
Si está tratando de averiguar qué hacer entre la entrada y la salida de su método bajo prueba, probablemente significa que está tratando de hacer demasiado en un solo método. Piensa en lo que deberían hacer esos pasos intermedios. Escriba pruebas para esos pasos intermedios y escriba métodos que pasen esas pruebas.
fuente
Se puede usar TDD para algoritmos complejos. Escriba muchas pruebas claras pero significativas y úselas para diseñar su programa. Si se utiliza una aleatorización en el algoritmo, utilice algún tipo de inyección de dependencia y pruebe la aleatorización por separado. TDD es uno de los muchos métodos que usará para escribir algoritmos de alta calidad: otros son revisiones de código, registro, etc.
No escriba la prueba "a". TDD no escribe una prueba a la vez. Primero escriba múltiples pruebas que verifiquen varios límites y entradas estándar del algoritmo.
fuente
Soy nuevo en TDD (léase: probablemente no lo estoy haciendo bien), pero parece ser más adecuado para algoritmos fácilmente descripbles, cuando puede razonar fácilmente sobre qué entradas coinciden con qué salidas.
Cuando estoy haciendo más "Todavía no sé cuál será el resultado" TDD no me ha sido muy útil. En cambio, lo que hago es usar afirmaciones de forma muy liberal en pequeñas porciones que sé cómo deberían funcionar hasta ahora. De esta manera, no me quedo atascado tratando de codificar a un objetivo que no estoy seguro debería ser el objetivo válido, pero obtengo algo de protección, localizando las áreas de dolor en porciones más pequeñas del código.
Una vez que el algoritmo está ordenado por su corrección (como estoy seguro de que hay al menos algunas entradas-> salidas para la verificación puntual), entonces regreso y escribo una prueba. Entonces es mucho más seguro regresar y refactorizar, u optimizar la velocidad o el uso de recursos.
fuente
Yo diría que este tipo de cosas es más adecuado para RDD: Desarrollo impulsado por la lectura.
Aquí es donde lees en un libro el algoritmo de algo complicado como un filtro de Kalman, y luego lo traduces en una implementación en tu entorno objetivo.
La desventaja es que hacer las cosas de esa manera significa que no obtendrá casos de prueba de forma gratuita como parte del proceso de diseño. Por otro lado, algo conocido como ese casi seguramente tiene una implementación existente (por ejemplo, Commons Math ). Y luego es sencillo usar eso como un oráculo de prueba para su nueva implementación; de lo único que debe preocuparse es de que su conjunto de casos de prueba cubra todas las rutas en su código.
fuente