La mayoría de los desarrolladores que han agregado funciones a edx-platform están familiarizados con Caso de prueba de módulo de tienda. Si sus pruebas ejercitan algo relacionado con el contenido del material didáctico (incluso si solo se trata de crear un curso vacío), la herencia de esta clase garantizará que los datos se limpien correctamente entre las pruebas individuales. Esto es extremadamente valioso, pero también puede ser un desperdicio en muchas situaciones. Durante el hackathon de la semana pasada, creé una alternativa más rápida , que son SharedModuleStoreTestCase.
Diferente a los Caso de prueba de módulo de tienda, SharedModuleStoreTestCase solo lo hace MóduloTienda limpieza en el desgarrarClase() nivel. Está destinado a ser empleado en situaciones en las que uno o un pequeño puñado de cursos se pueden inicializar por adelantado y luego se comparten de manera de solo lectura en muchas pruebas. Este patrón de uso se encuentra comúnmente en las pruebas de LMS, que a menudo simplemente recrean el mismo curso una y otra vez en su configuración() métodos.
Impacto en el rendimiento
Para tener una idea del efecto que podría tener, cambié algunos módulos de prueba como parte de mi trabajo de hackatón. Estas son solo cifras aproximadas, ya que se basan en un número relativamente pequeño de ejecuciones de prueba de Jenkins. Dicho esto, los resultados son prometedores:
| Archive | # Pruebas | Antes | Después | Delta |
| lms/djangoapps/ccx/tests/test_ccx_modulestore.py | 5 | Años 38 | 4s | -89% |
| lms/djangoapps/discusión_api/pruebas/prueba_api.py | 409 | 2m 45s | Años 51 | -69% |
| lms/djangoapps/equipos/pruebas/test_views.py | 152 | 1m 17s | Años 33 | -57% |
Entonces, ¿cómo conviertes tus propias pruebas?
Haciendo el cambio
La mayoría de las clases que heredan de Caso de prueba de módulo de tienda comenzar algo como esto:

Si está modificando auto.curso en sus funciones de prueba individuales, entonces esto es perfecto, y debe continuar usando Caso de prueba de módulo de tienda. Sin embargo, si solo configura el curso una vez y lo trata como de solo lectura en sus pruebas, ahora puede hacer esto en su lugar:

Es importante que las operaciones ORM de Django permanezcan en configuración(). Cualquier modelo que cree en setUpClass () debe eliminarse manualmente en su desgarrarClase() método — SharedModuleStoreTestCase no los limpiará correctamente. Incluso si tiene cuidado, es probable que rompa otras pruebas en el sistema de manera impredecible porque hacen suposiciones erróneas sobre las secuencias y qué ID se crearán cuando configuren sus datos. Esto puede ser extremadamente tedioso para depurar.
Cuando actualicemos a Django 1.8, podrá usar configurar datos de prueba () para realizar de forma segura la inicialización a nivel de clase de los modelos de Django con limpieza automática. Espere esa actualización y coloque las manipulaciones del modelo en configuración() por ahora, aunque sea un poco más lento.
¿Qué pruebas debo convertir?
El lugar más fácil para buscar objetivos de optimización de pruebas es el Informe de compilación de prueba de Jenkins. Haga clic en "Duración" para ordenar por esa columna.

Principalmente queremos apuntar a pruebas costosas que crean datos de cursos complejos (por ejemplo, CCX) o tienen datos de cursos simples pero muchas, muchas pruebas (por ejemplo, discusiones). Crear incluso el curso más simple toma alrededor de 250-300 ms, lo que realmente suma cuando se usan herramientas como ddt que efectivamente multiplican el número de pruebas en una clase.
Conclusión general
El acceso a la base de datos es una parte costosa de la ejecución de pruebas, y el MóduloTienda es un excelente ejemplo de eso. espero que SharedModuleStoreTestCase puede ser una herramienta útil para reducir los tiempos de ejecución de las pruebas. Pero más allá de eso, espero que comprender por qué funciona nos permita diseñar conjuntos de pruebas más rápidos en general.
Dave Ormsbee es arquitecto sénior en edX. Este post fue publicado originalmente en su blog, Castillo del pantano.
![]()