El único tipo de prueba que escribo
Dec 04 2022
Hay una conversación casi constante a nivel de fondo en el mundo de la ingeniería sobre qué tipos de pruebas son mejores; pruebas unitarias, pruebas de integración, pruebas de extremo a extremo, etc. Hace un tiempo, decidí que solo iba a escribir un tipo de prueba.
Hay una conversación casi constante a nivel de fondo en el mundo de la ingeniería sobre qué tipos de pruebas son mejores; pruebas unitarias, pruebas de integración, pruebas de extremo a extremo, etc.
Hace un tiempo, decidí que solo iba a escribir un tipo de prueba.
No estoy muy seguro de que encaje perfectamente en ninguna de las categorías anteriores. Tal vez la 'prueba de integración' sea más correcta, pero eso no lo cubre del todo, sobre todo porque nadie puede ponerse de acuerdo sobre cómo definir realmente lo que significan estas diferentes etiquetas.
Estos son los principios que sigo:
- No escribo una sola prueba hasta que tengo definida una interfaz pública clara.
- Mis pruebas deben emular lo más fielmente posible el comportamiento de un usuario real . Eso significa llamar solo a las API públicas, o si se trata de una interfaz frontal diseñada para un usuario final, hacer solo lo que haría un usuario final.
- Si una función o componente no es parte de la interfaz pública, no lo pruebo directamente. Si no es posible invocarlo indirectamente a través de alguna ruta pública, ¿cuál es exactamente su propósito?
- No hay llamadas de red remota. Si no es una llamada a localhost (por ejemplo, una base de datos de prueba local), entonces debe burlarse. Mis pruebas deberían pasar consistentemente sin red o conexión a Internet.
- No se burlan de las rutas de código interno. Burlarse de los límites de la red es excelente, pero burlarse de las funciones o API que existen dentro del código base que estoy probando es imposible.
- Ningún estado llevó a cabo diferentes pruebas. Si una prueba se basa en el estado de una prueba anterior, o podría verse afectada por ese estado de alguna manera, algo salió mal. Esto no tiene por qué significar 'borrar todo el estado después de cada prueba'.
- Sin pruebas de estado interno. Si tengo que inicializar o ajustar algún estado interno a mano en mi prueba (sin usar otra interfaz pública existente), mi prueba probablemente no sea buena.
- No hay pruebas de los detalles de implementación interna. Si la refactorización de mi código hace que la prueba falle, probablemente no sea una buena prueba.
- No hay 'pruebas unitarias' que invoquen funciones internas. Si siento el fuerte deseo de probar funciones como esta, probablemente deberían dividirse en su propio módulo o paquete independiente de antemano, con una interfaz clara que esté completamente desvinculada de cualquier lógica comercial.
- No hay pruebas de estilo 'extremo a extremo' que requieran activar un servidor y una base de datos completos y múltiples servicios y ejecutarlos todos juntos, a menos que sea extremadamente conveniente hacerlo en mi host local.
- Me concentro en la "cobertura de casos de uso" en lugar de la "cobertura de líneas de código".
- Escriba una prueba primero si está muy claro cómo se verá la interfaz pública de antemano. De lo contrario, escriba primero el código y luego pruébelo.
- Rompo cualquiera de las reglas anteriores cuando es mejor hacerlo que no escribir una prueba o dejar un caso de uso sin probar.