È questo l'uso corretto di conftest.py?
Sì. Le partite sono un uso potenziale e comune di conftest.py
. I dispositivi che definirai verranno condivisi tra tutti i test nella tua suite di test. Tuttavia, la definizione di dispositivi nella radice conftest.py
potrebbe essere inutile e rallenterebbe i test se tali dispositivi non fossero utilizzati da tutti i test.
Ha altri usi?
Sì lo fa.
Dispositivi : definire dispositivi per i dati statici utilizzati dai test. È possibile accedere a questi dati da tutti i test nella suite se non diversamente specificato. Questi potrebbero essere dati e aiutanti di moduli che verranno passati a tutti i test.
Caricamento plug-in esterno : conftest.py
viene utilizzato per importare plug-in o moduli esterni. Definendo la seguente variabile globale, pytest caricherà il modulo e lo renderà disponibile per il suo test. I plug-in sono generalmente file definiti nel progetto o in altri moduli che potrebbero essere necessari nei test. Puoi anche caricare un set di plugin predefiniti come spiegato qui .
pytest_plugins = "someapp.someplugin"
Hook : è possibile specificare hook come i metodi di installazione e smontaggio e molto altro per migliorare i test. Per un set di ganci disponibili, leggi qui . Esempio:
def pytest_runtest_setup(item):
""" called before ``pytest_runtest_call(item). """
#do some stuff`
Test percorso root : questa è una caratteristica nascosta. Definendo conftest.py
nel percorso di root, sarà necessario pytest
riconoscere i moduli dell'applicazione senza specificare PYTHONPATH
. In background, py.test modifica il tuo sys.path
includendo tutti i sottomoduli che si trovano dal percorso di root.
Posso avere più di un file conftest.py?
Sì, è possibile ed è fortemente raccomandato se la struttura del test è alquanto complessa. conftest.py
i file hanno ambito di directory. Pertanto, creare infissi e aiutanti mirati è una buona pratica.
Quando vorrei farlo? Gli esempi saranno apprezzati.
Diversi casi potrebbero adattarsi:
Creazione di un set di strumenti o ganci per un particolare gruppo di test.
radice / 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"
Caricamento di una serie di dispositivi per alcuni test ma non per altri.
radice / mod / conftest.py
@pytest.fixture()
def fixture():
return "some stuff"
radice / mod2 / conftest.py
@pytest.fixture()
def fixture():
return "some other stuff"
radice / mod2 / test.py
def test(fixture):
print(fixture)
Stampa "alcune altre cose".
Override degli hook ereditati dalla radice conftest.py
.
radice / mod / conftest.py
def pytest_runtest_setup(item):
print("I am mod")
#do some stuff
radice / conftest.py
def pytest_runtest_setup(item):
print("I am root")
#do some stuff
Eseguendo qualsiasi test all'interno root/mod
, viene stampato solo "I am mod".
Puoi leggere di più conftest.py
qui .
MODIFICARE:
E se avessi bisogno di chiamare funzioni di supporto semplici da una serie di test in diversi moduli: saranno disponibili per me se le inserissi in conftest.py? O dovrei semplicemente metterli in un modulo helpers.py e importarli e usarli nei miei moduli di test?
Puoi usare conftest.py
per definire i tuoi aiutanti. Tuttavia, dovresti seguire la pratica comune. Gli helper possono essere utilizzati come dispositivi almeno in pytest
. Ad esempio nei miei test ho un finto aiutante redis che inietto nei miei test in questo modo.
root / helper / Redis / redis.py
@pytest.fixture
def mock_redis():
return MockRedis()
root / test / stuff / conftest.py
pytest_plugin="helper.redis.redis"
root / test / stuff / test.py
def test(mock_redis):
print(mock_redis.get('stuff'))
Questo sarà un modulo di test che puoi importare liberamente nei tuoi test. NOTA che potresti potenzialmente nominare redis.py
come conftest.py
se il tuo modulo redis
contenga più test. Tuttavia, tale pratica è scoraggiata a causa dell'ambiguità.
Se vuoi usare conftest.py
, puoi semplicemente mettere quell'helper nella tua radice conftest.py
e iniettarlo quando necessario.
root / test / conftest.py
@pytest.fixture
def mock_redis():
return MockRedis()
root / test / stuff / test.py
def test(mock_redis):
print(mock_redis.get(stuff))
Un'altra cosa che puoi fare è scrivere un plugin installabile. In tal caso il tuo helper può essere scritto ovunque ma deve definire un punto di ingresso da installare nel tuo e in altri potenziali framework di test. Vedere questo .
Se non si desidera utilizzare gli apparecchi, è possibile ovviamente definire un semplice aiuto e utilizzare semplicemente la vecchia importazione ovunque sia necessaria.
root / test / helper / redis.py
class MockRedis():
# stuff
root / test / stuff / test.py
from helper.redis import MockRedis
def test():
print(MockRedis().get(stuff))
Tuttavia, qui potresti avere problemi con il percorso poiché il modulo non si trova in una cartella figlio del test. Dovresti essere in grado di superarlo (non testato) aggiungendo un __init__.py
aiuto
root / test / helper / __ init__.py
from .redis import MockRedis
O semplicemente aggiungendo il modulo helper al tuo PYTHONPATH
.
It seems great. However, I feel the documentation could be better.