Seria bom fazer algo como:
if settings.TESTING:
print("py.test is being ran")
"pytest" in sys.modules
?
Você mesmo pode adicionar uma configuração com um arquivo de configurações separado para testes
Acho que as abordagens sugeridas por @blueyed e @adamchainz devem ser suficientes se necessário. Geralmente, não é recomendado alterar a maneira como seu código funciona, introspectando se o código é ou não chamado a partir de testes. Se isso fosse feito, poderia ser feito de uma forma pytest geral (não é realmente específico para pytest-django). Obrigado pela sugestão, sinta-se à vontade para reabrir este problema se você tiver informações adicionais sobre ele!
Exemplo relevante da documentação do pytest Detecte se estiver executando a partir de uma execução do 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
O problema é que pytest_configure
é executado após settings.py
. Existe uma maneira de executar este código antes de settings.py
?
@axila
O que há de errado em usar 'pytest' in sys.modules
?
Hmm, sim, funcionou, embora pareça um pouco estranho para mim.
Outra maneira rápida e suja de verificar isso em settings.py é
TESTING = os.path.basename(sys.argv[0]) in ('pytest', 'py.test')
@axila
O que há de errado em usar'pytest' in sys.modules
?
O fato de o pytest ser importado não significa que pytest
esteja em execução e o código seja invocado a partir de um teste. Basicamente, basta importar pytest
para outra coisa. Além disso, o pytest está importando pytest
mesmo que apenas mostre uma ajuda CLI: pytest --help
Aqui está um caso de uso muito válido:
Eu tenho a configuração django configurável com arquivos locais e variáveis onde colocar várias credenciais e outras configurações de env dev local. Mas eu quero que meus testes de unidade nunca usem essas credenciais ou configurações específicas para não usá-los acidentalmente em algum sistema real (se falsificado incorretamente) ou passar / falhar na configuração de env de desenvolvimento local. Portanto, quero que essas configurações locais sejam excluídas quando executado com o pytest.
Eu tenho 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'
é uma maneira mais ou menos limpa de fazer isso, mas o problema é definir essa variável. Configurá-lo em conftest.py não funciona porque pytest-django importa as configurações antes de conftest.py ser executado. Configurá-lo na linha de comando ao executar o pytest é inconveniente e também anula o propósito: se alguém se esquecer de defini-lo, as credenciais reais serão usadas da configuração do env dev local.
os.path.basename (sys.argv [0]) em ('pytest', 'py.test')
Tive que alterá-lo para os.path.basename(os.path.dirname(sys.argv[0])) in ('pytest', 'py.test')
pois sys.argv[0]
estava saindo como /home/project/venv/lib/python3.8/site-packages/pytest/__main__.py
.
Comentários muito úteis
"pytest" in sys.modules
?