Pruebas de integración, pero ¿cuánto?

8

Un debate reciente dentro de mi equipo me hizo preguntarme. El tema básico es cuánto y qué cubriremos con las pruebas funcionales / de integración (claro, no son lo mismo, pero el ejemplo es falso donde no importa).

Digamos que tiene una clase de "controlador" algo como:

public class SomeController {
    @Autowired Validator val;
    @Autowired DataAccess da;
    @Autowired SomeTransformer tr;
    @Autowired Calculator calc;

    public boolean doCheck(Input input) {
        if (val.validate(input)) {
             return false;
        }

        List<Stuff> stuffs = da.loadStuffs(input);
        if (stuffs.isEmpty()) {
             return false;
        }

        BusinessStuff businessStuff = tr.transform(stuffs);
        if (null == businessStuff) {
            return false;
        }

       return calc.check(businessStuff);
    }
}

Necesitamos muchas pruebas unitarias para estar seguros (por ejemplo, si la validación falla o no hay datos en la base de datos, ...), eso está fuera de discusión.

Nuestro problema principal y en lo que no podemos estar de acuerdo es en la cantidad de pruebas de integración que lo cubrirán :-)

Estoy del lado de que apuntaremos a menos pruebas de integración (pirámide de prueba). Lo que cubriría de esto es solo un camino feliz e infeliz donde la ejecución regresa de la última línea, solo para ver si reúno estas cosas, no explotará.

El problema es que no es tan fácil decir por qué la prueba resultó falsa, y eso hace que algunos de los muchachos se sientan incómodos al respecto (por ejemplo, si simplemente verificamos solo el valor de retorno, se oculta que la prueba es verde porque alguien cambió la validación y devuelve falso). Claro, sí, podemos cubrir todos los casos, pero eso sería una gran exageración en mi humilde opinión.

¿Alguien tiene una buena regla general para este tipo de problemas? O una recomendación? ¿Leyendo? ¿Hablar? ¿Entrada en el blog? ¿Algo sobre el tema?

¡Muchas gracias por adelantado!

PD: Sry por el feo ejemplo, pero es bastante difícil traducir una parte de código específica a un ejemplo. Sí, uno puede discutir sobre lanzar excepciones / usar un tipo de retorno diferente / etc. pero nuestra mano está más o menos atada debido a dependencias externas.

PS2: moví este tema de SO aquí (pregunta original, marcada en espera )

rlegendi
fuente

Respuestas:

6

Hay una escuela de pensamiento que cuestiona seriamente el valor de las pruebas de integración.

Sospecho que obtendrá un amplio espectro de respuestas aquí, pero en mi opinión, solo debe usarlas cuando brinden un valor claro.

En primer lugar, debe escribir tantas pruebas unitarias como pueda, porque a) son baratas yb) pueden ser las únicas pruebas que se ejecutan en el servidor de compilación (si tiene una).

Es tentador escribir pruebas del lado del cliente para verificar la base de datos o alguna otra capa, pero esto debería suceder realmente al nivel apropiado, si es posible, en lugar de idear una prueba de integración. Por supuesto, esto puede requerir algunas bases en forma de interfaces, etc. para que la burla y cosas similares funcionen.

Considere también el alcance de sus pruebas. Si simplemente está escribiendo una prueba de integración para ocultar lo que sucede de todos modos cuando se ejecuta su suite o duplicar una prueba de humo, entonces esto tiene un valor limitado. Además, piense si más registros en lugares pertinentes sería una mejor opción en lugar de recibir un mensaje oscuro de una docena de componentes interconectados y tener que rastrearlo.

Entonces, suponiendo que haya decidido escribir algunos, debe pensar cuándo se ejecutarán. Si pueden detectar algún problema desagradable, entonces eso es genial, pero eso se vuelve bastante inútil si los desarrolladores nunca recuerdan ejecutarlos.

Finalmente, las pruebas de integración son un reemplazo totalmente inadecuado para las pruebas de humo y las pruebas de usuario. Si se molesta con ellos, deberían formar una pequeña parte de un proceso de prueba bien diseñado.

Robbie Dee
fuente
44
Solo un comentario: tenga en cuenta que, por el contrario, hay una escuela de pensamiento que cuestiona seriamente el valor de las pruebas unitarias (DHH afirma estar cuestionando TDD, pero si lee su publicación, también cuestiona las pruebas unitarias). Para ser honesto, encuentro cosas que están de acuerdo y en desacuerdo con ambas escuelas extremistas de pensamiento :)
Andres F.
1
Gran parte del dogma en torno a TDD es no escribir nada que no necesite que cualquier desarrollador experimentado conozca a través de YAGNI de todos modos ...
Robbie Dee
44
Su respuesta está bien (+1), el artículo que citó, sin embargo, tiene el problema que el autor da la impresión solo porque las pruebas de integración no funcionaron para su caso, no funcionarán para nadie más. En nuestro equipo, estamos usando pruebas de integración aquí para nuestro producto durante más de 10 años en la práctica, y nos impidieron implementar errores graves muchas veces, por lo que creo que en realidad es posible escribir pruebas de integración que ofrezcan un alto valor.
Doc Brown
El autor también escribe en un comentario "Pruebas integradas (¡no" pruebas de integración "!) [...]" - No estoy seguro de la diferencia, pero me parece que hay muchos matices involucrados en si una prueba de integración es útil o bueno
Carson Myers
En mi experiencia, solo las pruebas de integración realmente brindan valor. Las pruebas unitarias, en particular las que usan burlas, son más problemáticas de lo que valen. En mi proyecto actual, por ejemplo, tenemos 650 pruebas de integración basadas en JUnit que se ejecutan en cada confirmación en un servidor Jenkins, con la construcción completa en menos de 10 minutos. Por supuesto, también ejecutamos pruebas en nuestros IDEs, mientras hacemos TDD. No vemos la necesidad de tener un conjunto adicional de pruebas unitarias; agregaría mucho más esfuerzo sin ganancia aparente. ¿Quizás la razón por la que algunos desarrolladores evitan las pruebas de integración es simplemente que realmente no lo han intentado?
Rogério
8

Contrariamente a esta respuesta , considero que las pruebas en diferentes niveles son parte importante del proceso de prueba de software. Las pruebas unitarias, funcionales, de integración, de humo, de aceptación y de otro tipo están probando cosas diferentes, y cuanto más, mejor.

Y si logra automatizarlos, entonces pueden ejecutarse como un trabajo de su integración continua (como jenkins). Nadie necesita ejecutarlos para ver si se rompieron, ya que todos pueden ver si las pruebas fallaron.

En mis pruebas de integración, no entro en detalles: los detalles y los casos de esquina son para pruebas unitarias. Lo que pruebo es solo la funcionalidad principal, pasando todos los parámetros correctos. Eso significa que, en su ejemplo, en las pruebas de integración, no cubriría rutas falsas.

BЈовић
fuente
1
+1 Sí, si puede hacer pruebas de integración en la compilación, mucho mejor, pero esto puede ser una tarea importante en soluciones de nivel empresarial.
Robbie Dee