Sería bueno hacer algo como:
if settings.TESTING:
print("py.test is being ran")
"pytest" in sys.modules
?
Puede agregar una configuración usted mismo con un archivo de configuración separado para las pruebas
Creo que los enfoques sugeridos por @blueyed y @adamchainz deberían ser suficientes si es necesario. En general, no se recomienda cambiar la forma en que funciona el código mediante la introspección de si el código se llama o no desde las pruebas. Si esto se hiciera, se podría hacer de una manera pytest general (no es realmente específico de pytest-django). Gracias por la sugerencia, no dude en volver a abrir este problema si tiene información adicional sobre este problema.
Ejemplo relevante de pytest docs Detectar si se ejecuta desde dentro de una ejecución de pytest :
# content of conftest.py
def pytest_configure(config):
import sys
sys._called_from_test = True
def pytest_unconfigure(config):
import sys
del sys._called_from_test
El problema es que pytest_configure
se ejecuta después de settings.py
. ¿Hay alguna forma de ejecutar este código antes de settings.py
?
@axila
¿Qué hay de malo en usar 'pytest' in sys.modules
?
Hmm, sí, lo hice funcionar, aunque me parece un poco extraño.
Otra forma rápida y sucia de verificar esto en settings.py es
TESTING = os.path.basename(sys.argv[0]) in ('pytest', 'py.test')
@axila
¿Qué hay de malo en usar'pytest' in sys.modules
?
El hecho de que el pytest sea importado no significa que pytest
esté ejecutando y el código se invoque desde una prueba. Básicamente, uno de mis import pytest
para otra cosa. También pytest está importando pytest
incluso si solo muestra una ayuda CLI: pytest --help
Aquí hay un caso de uso muy válido:
Tengo la configuración de django configurable con archivos y variables locales donde coloco varias credenciales y otra configuración de entorno de desarrollo local. Pero quiero que mis pruebas unitarias nunca usen estas credenciales o configuraciones específicas para no usarlas accidentalmente en algún sistema real (si se burlan incorrectamente) o aprobar / fallar en la configuración del entorno de desarrollo local. Por lo tanto, quiero que se excluyan estas configuraciones locales cuando se ejecuten con pytest.
Tengo algo como:
import os
import os.path
import sys
from split_settings.tools import include, optional
def is_pytest_running():
return (os.getenv('PYTEST_RUNNING') == 'true' or
os.path.basename(sys.argv[0]) in ('pytest', 'py.test'))
ENVVAR_SETTINGS_PREFIX = 'MV_SERVER_'
local_settings_path = os.getenv(f'{ENVVAR_SETTINGS_PREFIX}SETTINGS', '../../../local/settings.py')
includes = [
'base.py',
'logging.py',
'custom.py',
]
if not is_pytest_running():
includes.append(optional(local_settings_path))
includes.append('envvars.py')
include(*includes)
Usar os.getenv('PYTEST_RUNNING') == 'true'
es una forma más o menos limpia de hacerlo, pero el problema es establecer esta variable. Configurarlo en conftest.py no funciona porque pytest-django importa la configuración antes de que se ejecute conftest.py. Establecerlo en la línea de comandos cuando se ejecuta pytest es inconveniente y también frustra el propósito: si alguien se olvida de configurarlo, se usarán las credenciales reales de la configuración del entorno de desarrollo local.
os.path.basename (sys.argv [0]) en ('pytest', 'py.test')
Tuve que cambiarlo a os.path.basename(os.path.dirname(sys.argv[0])) in ('pytest', 'py.test')
ya que sys.argv[0]
salía como /home/project/venv/lib/python3.8/site-packages/pytest/__main__.py
.
Comentario más útil
"pytest" in sys.modules
?