Perspectiva:
Entonces, demos un paso atrás y preguntemos con qué TDD está tratando de ayudarnos. TDD está tratando de ayudarnos a determinar si nuestro código es correcto o no. Y por correcto, quiero decir "¿cumple el código con los requisitos comerciales?" El punto de venta es que sabemos que se requerirán cambios en el futuro, y queremos asegurarnos de que nuestro código siga siendo correcto después de hacer esos cambios.
Traigo esa perspectiva porque creo que es fácil perderse en los detalles y perder de vista lo que estamos tratando de lograr.
Principios - SAP:
Si bien no soy un experto en TDD, creo que te estás perdiendo parte de lo que el Principio de Afirmación Única (SAP) está tratando de enseñar. SAP puede ser reexpresado como "prueba de una cosa a la vez". Pero TOTAT no se sale de la lengua tan fácilmente como lo hace SAP.
Probar una cosa a la vez significa que te enfocas en un caso; un camino una condición límite; un caso de error; uno lo que sea por prueba. Y la idea principal detrás de eso es que necesita saber qué se rompió cuando falla el caso de prueba, para que pueda resolver el problema más rápidamente. Si prueba varias condiciones (es decir, más de una cosa) dentro de una prueba y la prueba falla, entonces tiene mucho más trabajo en sus manos. Primero debe identificar cuál de los múltiples casos falló y luego averiguar por qué ese caso falló.
Si prueba una cosa a la vez, su alcance de búsqueda es mucho más pequeño y el defecto se identifica más rápidamente. Tenga en cuenta que "probar una cosa a la vez" no necesariamente lo excluye de mirar más de una salida de proceso a la vez. Por ejemplo, al probar un "buen camino conocido", puedo esperar ver un valor específico resultante, fooasí como otro valor bary puedo verificarlo foo != barcomo parte de mi prueba. La clave es agrupar lógicamente las comprobaciones de salida según el caso que se está probando.
Principios - PMP:
Del mismo modo, creo que te estás perdiendo un poco sobre lo que el Principio del Método Privado (PMP) tiene que enseñarnos. PMP nos anima a tratar el sistema como una caja negra. Para una entrada dada, debe obtener una salida dada. No le importa cómo el cuadro negro genera la salida. Solo le importa que sus salidas se alineen con sus entradas.
PMP es realmente una buena perspectiva para mirar los aspectos API de su código. También puede ayudarlo a determinar lo que tiene que probar. Identifique sus puntos de interfaz y verifique que cumplan con los términos de sus contratos. No necesita preocuparse por cómo los métodos detrás de la interfaz (también conocidos como privados) hacen su trabajo. Solo necesita verificar que hicieron lo que se suponía que debían hacer.
TDD aplicado ( para ti )
Por lo tanto, su situación presenta una pequeña arruga más allá de una aplicación ordinaria. Los métodos de su aplicación tienen estado, por lo que su salida depende no solo de la entrada, sino también de lo que se ha hecho anteriormente. Estoy seguro de que debería <insert some lecture>decir que el estado es horrible y bla, bla, bla, pero eso realmente no ayuda a resolver su problema.
Asumiré que tiene algún tipo de tabla de diagrama de estado que muestra los diversos estados potenciales y lo que debe hacerse para desencadenar una transición. Si no lo hace, lo necesitará, ya que ayudará a expresar los requisitos comerciales para este sistema.
Las pruebas: Primero, terminarás con un conjunto de pruebas que promulgan un cambio de estado. Idealmente, tendrá pruebas que ejerciten la gama completa de cambios de estado que pueden ocurrir, pero puedo ver algunos escenarios en los que es posible que no necesite llegar a ese punto.
A continuación, debe crear pruebas para validar el procesamiento de datos. Algunas de esas pruebas estatales se reutilizarán cuando cree las pruebas de procesamiento de datos. Por ejemplo, suponga que tiene un método Foo()que tiene diferentes resultados basados en un estado Inity State1. Querrá usar su ChangeFooToState1prueba como un paso de configuración para probar la salida cuando " Foo()está en State1".
Hay algunas implicaciones detrás de ese enfoque que quiero mencionar. Spoiler, aquí es donde enfureceré a los puristas
En primer lugar, debe aceptar que está usando algo como prueba en una situación y una configuración en otra situación. Por un lado, esto parece ser una violación directa de SAP. Pero si usted se enmarca lógicamente ChangeFooToState1como teniendo dos propósitos, todavía está cumpliendo con el espíritu de lo que SAP nos está enseñando. Cuando necesite asegurarse de que los Foo()cambios cambien de estado, lo usará ChangeFooToState1como prueba. Y cuando necesite validar " Foo()la salida de cuando está en State1", entonces está utilizando ChangeFooToState1como configuración.
El segundo elemento es que, desde un punto de vista práctico, no querrá pruebas de unidad totalmente aleatorias para su sistema. Debería ejecutar todas las pruebas de cambio de estado antes de ejecutar las pruebas de validación de salida. SAP es una especie de principio rector detrás de ese pedido. Para decir lo que debería ser obvio: no puede usar algo como configuración si falla como prueba.
Poniendo todo junto:
Usando su diagrama de estado, generará pruebas para cubrir las transiciones. Nuevamente, utilizando su diagrama, genera pruebas para cubrir todos los casos de procesamiento de datos de entrada / salida controlados por estado.
Si sigue ese enfoque, las bloated, complicated, long, and difficult to writepruebas deberían ser un poco más fáciles de administrar. En general, deberían terminar siendo más pequeños y deberían ser más concisos (es decir, menos complicados). Debe notar que las pruebas también están más desacopladas o modulares.
Ahora, no estoy diciendo que el proceso será completamente indoloro porque escribir buenas pruebas requiere cierto esfuerzo. Y algunos de ellos seguirán siendo difíciles porque está mapeando un segundo parámetro (estado) en algunos de sus casos. Y además, debería ser un poco más evidente por qué un sistema sin estado es más fácil de crear pruebas. Pero si adapta este enfoque para su aplicación, debería descubrir que puede probar que su aplicación funciona correctamente.