Construyendo algoritmos complejos con TDD

8

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?

Munk
fuente
1
Compruebe el principio de "Premisa de transformación": javacodegeeks.com/2013/01/…
Mik378
2
TDD no es una bala de plata, si cree que no es aplicable, no lo aplique.
Den
@Den Siento que es aplicable, pero me preguntaba cómo otros lo abordaron. Como estoy tratando de adoptar la práctica, descartarla por algo que no entiendo parece contraproducente. Prefiero saber por qué no funcionará en ese caso. Esta es la ventaja de adoptar para mis propios proyectos.
munk

Respuestas:

13

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.

Robert Harvey
fuente
2
+1 para "TDD no es un sustituto del diseño". En esta página ( ravimohan.blogspot.de/2007/04/learning-from-sudoku-solvers.html ) puede encontrar una buena ilustración de lo que puede suceder al aplicar TDD sin tener una visión general de lo que está haciendo.
Giorgio
0

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.

Podría escribir una prueba para el algoritmo con una entrada y la salida esperada,

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.

Asim Ghaffar
fuente
0

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.

Marcin
fuente
0

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.

soru
fuente
El problema particular que tengo aquí es que estoy usando el filtro Kalman extendido . No he encontrado una buena implementación de referencia en la que confío como lo haría con Apache Commons.
Munk