python - run - test form django
¿Cómo ejecutar la base de datos de prueba de Django solo en la memoria? (7)
Las pruebas de mi unidad Django tardan mucho tiempo en ejecutarse, así que estoy buscando formas de acelerar eso. Estoy considerando instalar un SSD , pero sé que tiene sus desventajas también. Por supuesto, hay cosas que podría hacer con mi código, pero estoy buscando una solución estructural. Incluso ejecutar una sola prueba es lento ya que la base de datos debe ser reconstruida / migrada al sur cada vez. Así que esta es mi idea ...
Como sé que la base de datos de prueba siempre será bastante pequeña, ¿por qué no puedo simplemente configurar el sistema para mantener siempre la base de datos de prueba completa en la memoria RAM? Nunca toque el disco en absoluto. ¿Cómo configuro esto en Django? Preferiría seguir usando MySQL ya que eso es lo que uso en producción, pero si SQLite 3 u otra cosa lo hace fácil, iría de esa manera.
¿Tiene SQLite o MySQL una opción para ejecutarse por completo en la memoria? Debería ser posible configurar un disco RAM y luego configurar la base de datos de prueba para almacenar sus datos allí, pero no estoy seguro de cómo decirle a Django / MySQL que use un directorio de datos diferente para una determinada base de datos, especialmente porque sigue borrándose y recreado cada carrera. (Estoy en un Mac FWIW.)
Ampliando la respuesta de Anurag, simplifiqué el proceso creando los mismos ajustes de prueba y agregando lo siguiente a manage.py
if len(sys.argv) > 1 and sys.argv[1] == "test":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.test_settings")
else:
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings")
parece más limpio ya que sys ya se importó y manage.py solo se utiliza a través de la línea de comandos, por lo que no hay necesidad de complicar la configuración
MySQL admite un motor de almacenamiento llamado "MEMORIA", que puede configurar en la configuración de su base de datos ( settings.py
) como tal:
''USER'': ''root'', # Not used with sqlite3.
''PASSWORD'': '''', # Not used with sqlite3.
''OPTIONS'': {
"init_command": "SET storage_engine=MEMORY",
}
Tenga en cuenta que el motor de almacenamiento MEMORY no admite columnas blob / text, por lo que si usa django.db.models.TextField
esto no funcionará para usted.
No puedo responder a tu pregunta principal, pero hay un par de cosas que puedes hacer para acelerar las cosas.
En primer lugar, asegúrese de que su base de datos MySQL esté configurada para usar InnoDB. Luego puede usar transacciones para deshacer el estado de la base de datos antes de cada prueba, lo que en mi experiencia ha llevado a una aceleración masiva. Puede pasar un comando init de base de datos en su settings.py (sintaxis Django 1.2):
DATABASES = {
''default'': {
''ENGINE'':''django.db.backends.mysql'',
''HOST'':''localhost'',
''NAME'':''mydb'',
''USER'':''whoever'',
''PASSWORD'':''whatever'',
''OPTIONS'':{"init_command": "SET storage_engine=INNODB" }
}
}
En segundo lugar, no necesita ejecutar las migraciones del Sur cada vez. Establezca SOUTH_TESTS_MIGRATE = False
en su settings.py y la base de datos se creará con syncdb simple, que será mucho más rápido que ejecutar todas las migraciones históricas.
Otro enfoque: tener otra instancia de MySQL ejecutándose en un tempfs que use un Disco RAM. Instrucciones en esta publicación de blog: Acelerar MySQL para probar en Django .
Ventajas:
- Utiliza exactamente la misma base de datos que usa su servidor de producción
- no es necesario cambiar la configuración predeterminada de mysql
Por lo general, creo un archivo de configuración separado para las pruebas y lo uso en el comando de prueba, por ejemplo
python manage.py test --settings=mysite.test_settings myapp
Tiene dos beneficios:
No es necesario que compruebe la
test
ni ninguna palabra mágica en sys.argv,test_settings.py
puede simplemente serfrom settings import * # make tests faster SOUTH_TESTS_MIGRATE = False DATABASES[''default''] = {''ENGINE'': ''django.db.backends.sqlite3''}
O puede modificarlo según sus necesidades, separando claramente la configuración de prueba de la configuración de producción.
Otra ventaja es que puede ejecutar la prueba con el motor de base de datos de producción en lugar de sqlite3 evitando errores sutiles, por lo que mientras desarrolla el uso
python manage.py test --settings=mysite.test_settings myapp
y antes de ejecutar el código ejecutar una vez
python manage.py test myapp
solo para estar seguro de que todas las pruebas realmente están pasando.
Puedes hacer doble ajuste:
- utilice tablas transaccionales: el estado de los accesorios iniciales se establecerá mediante la reversión de la base de datos después de cada TestCase.
- pon el directorio de datos de la base de datos en ramdisk: ganarás mucho en lo que se refiere a la creación de la base de datos y la prueba de ejecución será más rápida.
Estoy usando ambos trucos y estoy bastante feliz.
Cómo configurarlo para MySQL en Ubuntu:
$ sudo service mysql stop
$ sudo cp -pRL /var/lib/mysql /dev/shm/mysql
$ vim /etc/mysql/my.cnf
# datadir = /dev/shm/mysql
$ sudo service mysql start
¡Cuidado, es solo para probar, después de reiniciar su base de datos se pierde la memoria!
Si configura su motor de base de datos en sqlite3 cuando ejecuta las pruebas, Django utilizará una base de datos en memoria .
Estoy usando un código como este en mi settings.py
para configurar el motor en sqlite cuando ejecuto mis pruebas:
if ''test'' in sys.argv:
DATABASE_ENGINE = ''sqlite3''
O en Django 1.2:
if ''test'' in sys.argv:
DATABASES[''default''] = {''ENGINE'': ''sqlite3''}
Y finalmente en Django 1.3 y 1.4:
if ''test'' in sys.argv:
DATABASES[''default''] = {''ENGINE'': ''django.db.backends.sqlite3''}
(La ruta completa al servidor no es estrictamente necesaria con Django 1.3, pero hace que la configuración sea compatible).
También puede agregar la siguiente línea, en caso de que tenga problemas con las migraciones del sur:
SOUTH_TESTS_MIGRATE = False