¿Es una mala práctica separar las pruebas unitarias para una clase? [cerrado]

8

Mis clases normalmente tienen un máximo de 5-20 métodos, lo que implica que la clase que tiene las pruebas unitarias tiene aproximadamente el doble de métodos (contando proveedores de datos, configuración, ...)

He pensado separar las pruebas en 2-3 clases, porque incluso si trato de seguir el principio de responsabilidad única, prefiero 2 clases de prueba con 10 métodos cada una, que una con 20.

¿Es una mala práctica? ¿Es bueno tener todas las pruebas para una clase en una sola, aunque la clase de prueba crece en vertical?

luisandani
fuente
44
tener demasiadas pruebas unitarias parece un síntoma de una clase que viola el principio de responsabilidad única . En lugar de evitar los síntomas, aborde la causa raíz en un diseño de clase
mosquito
Una ventaja de tener todas sus pruebas en un archivo es que ayuda a algunos IDEs a saber automáticamente qué pruebas están asociadas a qué clases según sus nombres. Pero en algún momento, esto no es una gran consideración en comparación con mantener sus pruebas bien organizadas.
Kevin
Gracias mosquito por tu respuesta, he actualizado la pregunta para centrarla solo en separar las pruebas.
luisandani

Respuestas:

18

Para responder a la pregunta específica, es absolutamente posible que agrupar pruebas en varias clases sea una buena decisión, evento cuando la clase bajo prueba está bien diseñada.

El código de prueba de la unidad es como cualquier otro código: debe seguir buenos principios de diseño ( DRY , GRASP , KISS , SOLID , YAGNI , etc.). Debido a que la lógica que compone el código de prueba es a menudo más simple que la lógica de dominio, muchos de los puntos específicos no aparecerán tanto, pero tenga en cuenta al escribir sus pruebas de todos modos.

Hay un par de principios que vienen a la mente que pueden aplicarse fácilmente al pensar en su pregunta:

Legibilidad

Idealmente, una vez que se escribe una prueba, nunca tiene que volver a mirarla; pero lo mismo puede decirse de cualquier código. La realidad es que los requisitos cambian, por lo que nos encontramos leyendo el código mucho más que escribiéndolo. Incluso cuando haces tu mejor esfuerzo, puedes encontrar que la prueba que escribiste no verificaba lo que pensabas, en ese momento tendrás que volver y descubrir qué estaba mal. Encontrar ese método de prueba en una clase de 40-50 métodos de prueba será difícil, sin mencionar la complicación de nombrar esos métodos para que puedan diferenciarse fácilmente.

Alta cohesión

Cada clase de prueba (como cualquier otra clase) debe tener un enfoque claro. Si tiene muchos casos de prueba diferentes para un método determinado de la clase bajo prueba, como cuando una prueba determinada verifica una sola cosa, coloque esos métodos de prueba en una clase separada y asígnele un nombre para reflejar su enfoque.

Mike Partridge
fuente
3
En realidad, es posible que desee ver una prueba incluso si no cambian los requisitos, solo para comprender cómo se debe usar la clase probada, por ejemplo.
Paŭlo Ebermann
7

Casi no tiene importancia cómo se organizan las pruebas unitarias en comparación con tenerlas en primer lugar.

Un módulo o clase de código comercial es algo que debe comprender como una unidad y desarrollar más. Esa es la razón principal por la que nos esforzamos por hacerlo coherente, fácil de entender en su conjunto, etc. Un conjunto de pruebas es solo una colección de casos que todos deben pasar; No tienen ninguna relación particular entre ellos . Idealmente, nunca más tendrás que lidiar con eso; si lo hace, generalmente es agregar más pruebas que nuevamente no tienen una relación particular con ninguna otra prueba, y nunca se llaman por código de cliente, excepto el marco de prueba de la unidad.

Por lo tanto, la cuestión de cómo organizar las clases que contienen pruebas unitarias es mucho menos crítica que cómo organizar las clases que componen su propia aplicación. No se supone que trates con ellos como una macroestructura bien diseñada de todos modos.

Kilian Foth
fuente
Si bien creo que en general tienes razón, hay pocas cosas peores que las pruebas con errores, frágiles, poco claras y difíciles de seguir. El código de prueba de espagueti no es bueno.
Paul Draper el
3

Ponga las pruebas en un archivo. Por lo general, para cada archivo de clase, tendría un archivo de prueba. Por lo general, agregue "Pruebas" al nombre del archivo.

Por ejemplo, si hay una clase llamada "Foo", habría un archivo "FooTests" correspondiente. De esta manera, para cada archivo de código hay una relación 1 a 1 entre el archivo de código y el archivo de prueba.

Esto proporciona coherencia y facilita a los desarrolladores localizar las pruebas y mantenerlas actualizadas. Las pruebas generalmente se excluyen del análisis / métricas de código, por lo que si el archivo es grande, no daña la métrica de salud general del código, por lo que no considero que sea un mal formato tener un archivo de prueba con mucho código de prueba unitaria.

Jon Raynor
fuente
3

Si decimos que la definición de mala práctica en el desarrollo de software es algo que no te ayuda a lidiar con el cambio y encapsularlo, entonces diría que no mantener tus clases y exámenes en una relación uno a uno es una mala práctica . Es un olor a código que puede surgir debido a las cosas que se mencionan a continuación.

Obviamente, hay excepciones al igual que con cualquier cosa, pero tenlo en cuenta mientras escribes tus exámenes.

Mis clases normalmente tienen un máximo de 5-20 métodos.

Si alguna de sus clases tiene 20 (o un poco menos) métodos, eso me muestra que la clase está haciendo demasiado en primer lugar. Aquí es donde las pruebas unitarias deberían indicarle que es posible que deba desglosar su clase un poco más y distribuir la responsabilidad antes de realizar las pruebas.

En cuanto a mantenerlos en la misma clase o no, sugeriría tratar de mantenerlos en una clase si es posible porque es mejor comprensible: la conexión uno a uno es fácil de entender después de que haya pasado mucho tiempo. Solo por experiencia.

Si ve que las pruebas unitarias son enormes incluso cuando tiene 5 métodos o menos, eso me dice que su código de configuración está haciendo demasiado o que sus objetos son anormalmente grandes .

Si aún no lo ha intentado, consulte el patrón de construcción para construir sus objetos; esto podría reducir drásticamente el código sobre cómo está construyendo sus objetos antes de probarlos. Por lo tanto, hacer la clase de prueba unitaria más corta y menos necesidad de reducirla a más clases.

AvetisG
fuente
Este es un excelente consejo, pero no es una respuesta a la pregunta. (Todavía votado)
Jon Raynor
@ JonRaynor gracias! Acabo de actualizar mi respuesta con una conclusión, respondiendo específicamente a la pregunta.
AvetisG
¿Podría por favor dar más detalles sobre el voto negativo?
AvetisG
1
@AvetisG: La gente no tiene que dar más detalles sobre sus votos negativos y es injusto pedirles que lo hagan. Pero intentaré ayudarte ... Solo el primer párrafo aquí incluso intenta responder la pregunta. El resto es una opinión que algunas personas no compartirían. Personalmente, estoy de acuerdo con tu opinión, pero no estoy de acuerdo con el párrafo que es relevante para la pregunta, y no veo la conexión que estás haciendo. La respuesta de Mike es correcta: "Cada clase de prueba (como cualquier otra clase) debe tener un enfoque claro". Ese puede o no ser el mismo enfoque que para sus clases bajo prueba.
pdr
@pdr eso tiene sentido. Gracias por ampliar eso.
AvetisG