Estoy investigando técnicas y estrategias para escalar nuestro creciente número de pruebas de integración en nuestro producto actual, para que puedan (humanamente) seguir siendo parte de nuestro proceso de desarrollo y CI.
En más de 200 pruebas de integración, ya estamos alcanzando la marca de 1 hora para completar una ejecución de prueba completa (en una máquina de desarrollo de escritorio), y esto está afectando negativamente la capacidad de un desarrollador para tolerar la ejecución de todo el conjunto como parte de los procesos de inserción rutinarios. Lo que está afectando la motivación para ser disciplinado sobre cómo crearlos bien. Probamos la integración solo en escenarios clave de adelante hacia atrás, y utilizamos un entorno que refleja la producción, que se construye desde cero en cada ejecución de prueba.
Debido al tiempo que lleva ejecutar, está generando un ciclo de retroalimentación terrible y muchos ciclos desperdiciados esperando que las máquinas terminen las ejecuciones de prueba, sin importar cuán enfocadas estén las ejecuciones de prueba. No importa el impacto negativo más costoso en el flujo y el progreso, la cordura y la sostenibilidad.
Esperamos tener 10 veces más pruebas de integración antes de que este producto comience a ralentizarse (en realidad, no tengo idea, pero parece que aún no estamos comenzando en términos de características). Tenemos que esperar razonablemente estar en los pocos cientos o miles de pruebas de integración, supongo que en algún momento.
Para ser claros, para tratar de evitar que esto se convierta en una discusión sobre las pruebas unitarias versus las pruebas de integración (que nunca deberían intercambiarse). Estamos realizando pruebas unitarias con TDD Y pruebas de integración en este producto. De hecho, hacemos pruebas de integración en las diversas capas de la arquitectura de servicios que tenemos, donde tiene sentido para nosotros, ya que necesitamos verificar dónde introducimos cambios importantes al cambiar los patrones de nuestra arquitectura a las otras áreas del sistema.
Un poco sobre nuestra pila tecnológica. Actualmente estamos probando en un entorno de emulación (CPU y memoria intensiva) para ejecutar nuestras pruebas de principio a fin. Que se compone de los servicios web REST de Azure frente a un back-end noSql (ATS). Estamos simulando nuestro entorno de producción al ejecutar el emulador de escritorio Azure + IISExpress. Estamos limitados a un emulador y un repositorio backend local por máquina de desarrollo.
También tenemos un CI basado en la nube, que ejecuta la misma prueba en el mismo entorno emulado, y las ejecuciones de prueba están tardando el doble (2 horas +) en la nube con nuestro proveedor actual de CI. Hemos alcanzado los límites del SLA de los proveedores de CI en la nube en términos de rendimiento de hardware, y excedimos su límite de tiempo de ejecución de prueba. Para ser justos con ellos, sus especificaciones no son malas, pero claramente la mitad de buenas que una máquina de escritorio desagradable.
Estamos utilizando una estrategia de prueba para reconstruir nuestro almacén de datos para cada grupo lógico de pruebas y precargar con datos de prueba. Si bien asegura integralmente la integridad de los datos, esto agrega un impacto del 5-15% en cada prueba. Por lo tanto, creemos que hay poco que ganar al optimizar esa estrategia de prueba en este punto del desarrollo del producto.
En resumidas cuentas, si bien podríamos optimizar el rendimiento de cada prueba (aunque sea entre un 30% y un 50% cada una), todavía no escalaremos de manera efectiva en el futuro cercano con varios cientos de pruebas. 1 hora ahora es aún mucho más que tolerable para el ser humano, necesitamos un orden de mejora de magnitud en el proceso general para que sea sostenible.
Por lo tanto, estoy investigando qué técnicas y estrategias podemos emplear para reducir drásticamente el tiempo de prueba.
- Escribir menos pruebas no es una opción. No discutamos ese tema en este hilo.
- Usar hardware más rápido es definitivamente una opción, aunque muy costosa.
- Ejecutar grupos de pruebas / escenarios en hardware separado en paralelo también es definitivamente una opción preferida.
- Crear grupos de pruebas en torno a características y escenarios en desarrollo es plausible, pero en última instancia no es confiable para probar la cobertura total o la confianza de que el sistema no se ve afectado por un cambio.
- Es técnicamente posible ejecutar en un entorno de ensayo a escala de la nube en lugar de ejecutarse en el emulador de escritorio, aunque comenzamos a agregar tiempos de implementación a las ejecuciones de prueba (~ 20 minutos cada una al comienzo de la ejecución de prueba para implementar las cosas).
- Dividir los componentes del sistema en piezas logiales independientes es plausible hasta cierto punto, pero esperamos un kilometraje limitado, ya que se espera que las interacciones entre los componentes aumenten con el tiempo. (es decir, es probable que un cambio afecte a otros en formas inesperadas, como sucede a menudo cuando un sistema se desarrolla de forma incremental)
Quería ver qué estrategias (y herramientas) están usando otros en este espacio.
(Tengo que creer que otros pueden estar viendo este tipo de dificultad al usar ciertos conjuntos de tecnología).
[Actualización: 16/12/2016: Terminamos invirtiendo más en pruebas paralelas de CI, para una discusión del resultado: http://www.mindkin.co.nz/blog/2015/12/16/16-jobs]