Tengo una aplicación Rails con más de 2000 ejemplos en mis pruebas RSpec. No hace falta decir que es una gran aplicación y hay mucho que probar. Ejecutar estas pruebas en este punto es muy ineficiente y debido a que lleva tanto tiempo, estamos casi al punto de desanimarnos de escribirlas antes de lanzar una nueva compilación. Agregué --profile a mi spec.opts para encontrar los ejemplos de ejecución más larga y hay al menos 10 de ellos que tardan un promedio de 10 segundos en ejecutarse. ¿Es eso normal entre ustedes, los expertos de RSpec? ¿Son 10 segundos demasiado largos para un ejemplo? Me doy cuenta de que con 2000 ejemplos, se necesitará una cantidad de tiempo no trivial para probar todo a fondo, pero en este punto, 4 horas es un poco ridículo.
¿Qué tipo de momentos está viendo para sus ejemplos más largos? ¿Qué puedo hacer para solucionar problemas de mis especificaciones existentes a fin de descubrir cuellos de botella y ayudar a acelerar las cosas? Cada minuto ayudaría mucho en este punto.
fuente
perftools.rb
junto con su marco de prueba para comprender qué está consumiendo la mayor parte de su tiempo. Tome las 10 principales llamadas e intente eliminarlas o eliminarlas. Luego repita, hasta que esté feliz.Respuestas:
10 segundos es mucho tiempo para que se ejecute una sola prueba. Mi intuición es que su objetivo de especificaciones está ejecutando pruebas unitarias y de integración al mismo tiempo. Esto es algo típico en lo que caen los proyectos y, en algún momento, deberá superar esta deuda técnica si desea producir más y más rápido. Hay una serie de estrategias que pueden ayudarlo a hacer esto ... y recomendaré algunas que he usado en el pasado.
1. Unidad separada de las pruebas de integración
Lo primero que haría es separar la unidad de las pruebas de integración. Puede hacer esto por:
La filosofía es que desea que sus compilaciones habituales sean rápidas; de lo contrario, la gente no estará muy feliz de ejecutarlas a menudo. Así que vuelve a ese territorio. Haga que sus pruebas habituales se ejecuten rápidamente y utilice un servidor de integración continua para ejecutar la compilación más completa.
Una prueba de integración es una prueba que involucra dependencias externas (por ejemplo, base de datos, servicio web, cola y algunos argumentarían que FileSystem). Una prueba unitaria solo prueba el elemento de código específico que desea verificar. Debería ejecutarse rápido (es posible 9000 en 45 segundos), es decir, la mayor parte debería ejecutarse en la memoria.
2. Convertir pruebas de integración en pruebas unitarias
Si la mayor parte de sus pruebas unitarias es más pequeña que su conjunto de pruebas de integración, tiene un problema. Lo que esto significa es que las inconsistencias comenzarán a aparecer más fácilmente. Entonces, a partir de aquí, comience a crear más pruebas unitarias para reemplazar las pruebas de integración. Las cosas que puede hacer para ayudar en este proceso son:
Una vez que tenga las pruebas unitarias adecuadas para reemplazar una prueba de integración, elimine la prueba de integración. Las pruebas duplicadas solo empeoran el mantenimiento.
3. No use accesorios
Los accesorios son malvados. En su lugar, utilice una fábrica (maquinista o robot de fábrica). Estos sistemas pueden crear gráficos de datos más adaptables y, lo que es más importante, pueden crear objetos en memoria que puede utilizar, en lugar de cargar cosas desde una fuente de datos externa.
4. Agregar comprobaciones para evitar que las pruebas unitarias se conviertan en pruebas de integración
Ahora que ha implementado pruebas más rápidas, es hora de realizar comprobaciones para DETENER que esto vuelva a ocurrir.
Hay bibliotecas que parchean el registro activo para arrojar un error al intentar acceder a la base de datos (UnitRecord).
También puede probar el emparejamiento y TDD, lo que puede ayudar a obligar a su equipo a escribir pruebas más rápidas porque:
5. Utilice otras bibliotecas para solucionar el problema
Alguien mencionó spork (acelera los tiempos de carga para el conjunto de pruebas bajo rieles3), hydra / parallel_tests: para ejecutar pruebas unitarias en paralelo (en varios núcleos).
Esto probablemente debería usarse por ÚLTIMO. Su problema real está en los pasos 1, 2, 3. Resuelva eso y estará en una mejor posición para desplegar infraestructura adicional.
fuente
Para obtener un excelente libro de cocina sobre cómo mejorar el rendimiento de su suite de pruebas, consulte Grease Your Suite .
Documenta una aceleración de 45 veces en el tiempo de ejecución de la suite de pruebas mediante el uso de técnicas como:
fuente
Puedes usar Spork. Tiene soporte para 2.3.x,
https://github.com/sporkrb/spork
o ./script/spec_server que puede funcionar para 2.x
También puede editar la configuración de la base de datos (que esencialmente acelera las consultas de la base de datos, etc.), lo que también aumentará el rendimiento de las pruebas.
fuente
10 segundos por ejemplo parece mucho tiempo. Nunca he visto una especificación que demore más de un segundo, y la mayoría toma mucho menos. ¿Está probando las conexiones de red? ¿Escrituras de base de datos? ¿El sistema de archivos escribe?
Use simulacros y talones tanto como sea posible, son mucho códigos más rápidos que escribir código que llega a la base de datos. Desafortunadamente, las burlas y los tapones también toman más tiempo para escribir (y son más difíciles de hacer correctamente). Debe equilibrar el tiempo dedicado a escribir pruebas con el tiempo dedicado a ejecutar pruebas.
Me segunda Andrew Grimm comentario 's de buscar en un sistema de CI que podría permitir que para paralelizar su serie de pruebas. Para algo de ese tamaño, podría ser la única solución viable.
fuente
Varias personas han mencionado a Hydra anteriormente. Lo hemos utilizado con gran éxito en el pasado. Recientemente documenté el proceso de puesta en marcha de Hydra: http://logicalfriday.com/2011/05/18/faster-rails-tests-with-hydra/
Estoy de acuerdo con la opinión de que este tipo de técnica no debería utilizarse como sustituto de las pruebas de redacción que están bien estructuradas y son rápidas por defecto.
fuente
Si está utilizando modelos ActiveRecord, también debe considerar el costo del cifrado BCrypt.
Puede leer más sobre esto en esta publicación de blog: http://blog.syncopelabs.co.uk/2012/12/speed-up-rspec-test.html
fuente
quick_require gem podría ayudarte. Además de eso, su única forma es (como lo hizo) perfilar y optimizar, o usar spork o algo que ejecute sus especificaciones en paralelo para usted. http://ruby-toolbox.com/categories/distributed_testing.html
fuente
Puede seguir algunos consejos simples para investigar primero dónde se pasa la mayor parte del tiempo si aún no los ha probado. Mira el artículo a continuación:
https://blog.mavenhive.in/7-tips-to-speed-up-your-webdriver-tests-4f4d043ad581
Supongo que la mayoría de estos son pasos genéricos que también se aplicarían independientemente de la herramienta utilizada para la prueba.
fuente
Elimine el conjunto de pruebas existente. Será increíblemente efectivo.
fuente