Esse é o uso correto do conftest.py?
Sim, ele é. As luminárias são um uso comum e potencial conftest.py
. Os equipamentos que você definirá serão compartilhados entre todos os testes em seu conjunto de testes. No entanto, a definição de acessórios na raiz conftest.py
pode ser inútil e atrasaria o teste se esses acessórios não fossem usados em todos os testes.
Tem outros usos?
Sim.
Acessórios : defina acessórios para dados estáticos usados por testes. Esses dados podem ser acessados por todos os testes no conjunto, a menos que especificado de outra forma. Podem ser dados e auxiliares dos módulos que serão passados a todos os testes.
Carregamento de plug-in externo : conftest.py
é usado para importar plug-ins ou módulos externos. Ao definir a seguinte variável global, o pytest carregará o módulo e o disponibilizará para seu teste. Plugins geralmente são arquivos definidos em seu projeto ou outros módulos que podem ser necessários em seus testes. Você também pode carregar um conjunto de plugins predefinidos, conforme explicado aqui .
pytest_plugins = "someapp.someplugin"
Ganchos : você pode especificar ganchos como métodos de instalação e desmontagem e muito mais para melhorar seus testes. Para um conjunto de ganchos disponíveis, leia aqui . Exemplo:
def pytest_runtest_setup(item):
""" called before ``pytest_runtest_call(item). """
#do some stuff`
Caminho da raiz de teste : esse é um recurso oculto. Ao definir conftest.py
seu caminho raiz, você terá que pytest
reconhecer seus módulos de aplicativos sem especificar PYTHONPATH
. Em segundo plano, py.test modifica o seu sys.path
incluindo todos os submódulos encontrados no caminho raiz.
Posso ter mais de um arquivo conftest.py?
Sim, você pode e é altamente recomendável que sua estrutura de teste seja um pouco complexa. conftest.py
arquivos têm escopo de diretório. Portanto, a criação de equipamentos e auxiliares direcionados é uma boa prática.
Quando eu quero fazer isso? Exemplos serão apreciados.
Vários casos podem caber:
Criando um conjunto de ferramentas ou ganchos para um grupo específico de testes.
root / mod / conftest.py
def pytest_runtest_setup(item):
print("I am mod")
#do some stuff
test root/mod2/test.py will NOT produce "I am mod"
Carregando um conjunto de acessórios para alguns testes, mas não para outros.
root / mod / conftest.py
@pytest.fixture()
def fixture():
return "some stuff"
root / mod2 / conftest.py
@pytest.fixture()
def fixture():
return "some other stuff"
root / mod2 / test.py
def test(fixture):
print(fixture)
Irá imprimir "algumas outras coisas".
Substituindo ganchos herdados da raiz conftest.py
.
root / mod / conftest.py
def pytest_runtest_setup(item):
print("I am mod")
#do some stuff
root / conftest.py
def pytest_runtest_setup(item):
print("I am root")
#do some stuff
Ao executar qualquer teste interno root/mod
, apenas "I am mod" é impresso.
Você pode ler mais sobre conftest.py
aqui .
EDITAR:
E se eu precisar que funções auxiliares simples sejam chamadas de vários testes em módulos diferentes - elas estarão disponíveis para mim se eu as colocar em um conftest.py? Ou devo simplesmente colocá-los em um módulo helpers.py e importá-los e usá-los em meus módulos de teste?
Você pode usar conftest.py
para definir seus ajudantes. No entanto, você deve seguir a prática comum. Os ajudantes podem ser usados como acessórios pelo menos em pytest
. Por exemplo, em meus testes, tenho um auxiliar redis falsos que injeto nos meus testes dessa maneira.
root / helper / redis / redis.py
@pytest.fixture
def mock_redis():
return MockRedis()
root / tests / stuff / conftest.py
pytest_plugin="helper.redis.redis"
root / tests / stuff / test.py
def test(mock_redis):
print(mock_redis.get('stuff'))
Este será um módulo de teste que você pode importar livremente em seus testes. NOTE que você poderia nomear redis.py
como conftest.py
se seu módulo redis
contivesse mais testes. No entanto, essa prática é desencorajada por causa da ambiguidade.
Se você quiser usar conftest.py
, basta colocar esse auxiliar em sua raiz conftest.py
e injetá-lo quando necessário.
root / tests / conftest.py
@pytest.fixture
def mock_redis():
return MockRedis()
root / tests / stuff / test.py
def test(mock_redis):
print(mock_redis.get(stuff))
Outra coisa que você pode fazer é escrever um plugin instalável. Nesse caso, seu auxiliar pode ser gravado em qualquer lugar, mas ele precisa definir um ponto de entrada a ser instalado em sua e em outras estruturas de teste em potencial. Veja isso .
Se você não quiser usar acessórios, é claro que você pode definir um auxiliar simples e usar a importação antiga simples sempre que necessário.
root / tests / helper / redis.py
class MockRedis():
# stuff
root / tests / stuff / test.py
from helper.redis import MockRedis
def test():
print(MockRedis().get(stuff))
No entanto, aqui você pode ter problemas com o caminho, pois o módulo não está em uma pasta filho do teste. Você deve conseguir superar isso (não testado) adicionando um __init__.py
ao seu auxiliar
root / tests / helper / __ init__.py
from .redis import MockRedis
Ou simplesmente adicionando o módulo auxiliar ao seu PYTHONPATH
.
It seems great. However, I feel the documentation could be better.