Est-ce l'utilisation correcte de conftest.py?
Oui, ça l'est. Les luminaires sont une utilisation potentielle et courante de conftest.py
. Les fixtures que vous définirez seront partagées entre tous les tests de votre suite de tests. Cependant, la définition de fixtures à la racine conftest.py
peut être inutile et ralentirait les tests si ces fixtures n'étaient pas utilisées par tous les tests.
A-t-il d'autres utilisations?
Oui.
Fixtures : définissez les fixtures pour les données statiques utilisées par les tests. Ces données sont accessibles par tous les tests de la suite, sauf indication contraire. Cela pourrait être des données ainsi que des aides de modules qui seront transmises à tous les tests.
Chargement de plugins externes : conftest.py
permet d'importer des plugins ou modules externes. En définissant la variable globale suivante, pytest chargera le module et le rendra disponible pour son test. Les plugins sont généralement des fichiers définis dans votre projet ou d'autres modules qui pourraient être nécessaires dans vos tests. Vous pouvez également charger un ensemble de plugins prédéfinis comme expliqué ici .
pytest_plugins = "someapp.someplugin"
Crochets : vous pouvez spécifier des crochets tels que les méthodes de configuration et de démontage et bien plus encore pour améliorer vos tests. Pour un ensemble de crochets disponibles, lisez ici . Exemple:
def pytest_runtest_setup(item):
""" called before ``pytest_runtest_call(item). """
#do some stuff`
Tester le chemin racine : c'est un peu une fonction cachée. En définissant conftest.py
dans votre chemin racine, vous aurezpytest
reconnaître vos modules d'application sans spécifier PYTHONPATH
. En arrière-plan, py.test modifie votre sys.path
en incluant tous les sous-modules trouvés depuis le chemin racine.
Puis-je avoir plus d'un fichier conftest.py?
Oui, vous le pouvez et il est fortement recommandé si votre structure de test est quelque peu complexe. conftest.py
les fichiers ont une portée de répertoire. Par conséquent, la création d'appareils et d'aides ciblés est une bonne pratique.
Quand voudrais-je faire ça? Des exemples seront appréciés.
Plusieurs cas pourraient convenir:
Création d'un ensemble d'outils ou de crochets pour un groupe particulier de tests.
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"
Chargement d'un ensemble d' appareils pour certains tests mais pas pour d'autres.
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)
Imprime "quelques autres trucs".
Remplacer les crochets hérités de la racine 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
En exécutant un test à l'intérieur root/mod
, seul "I am mod" est imprimé.
Vous pouvez en savoir plus conftest.py
ici .
ÉDITER:
Que se passe-t-il si j'ai besoin que des fonctions d'assistance simples soient appelées à partir d'un certain nombre de tests dans différents modules - seront-elles disponibles si je les place dans un fichier conftest.py? Ou devrais-je simplement les mettre dans un module helpers.py et les importer et les utiliser dans mes modules de test?
Vous pouvez utiliser conftest.py
pour définir vos assistants. Cependant, vous devez suivre la pratique courante. Les assistants peuvent être utilisés comme appareils au moins danspytest
. Par exemple, dans mes tests, j'ai un simulateur d'aide redis que j'injecte dans mes tests de cette façon.
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'))
Ce sera un module de test que vous pourrez importer librement dans vos tests. NOTEZ que vous pourriez potentiellement nommer redis.py
comme conftest.py
si votre module redis
contient plus de tests. Cependant, cette pratique est découragée en raison de l'ambiguïté.
Si vous souhaitez l'utiliser conftest.py
, vous pouvez simplement mettre cet assistant dans votre racine conftest.py
et l'injecter en cas de besoin.
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))
Une autre chose que vous pouvez faire est d'écrire un plugin installable. Dans ce cas, votre assistant peut être écrit n'importe où, mais il doit définir un point d'entrée à installer dans votre et les autres cadres de test potentiels. Voir ça .
Si vous ne souhaitez pas utiliser de fixtures, vous pouvez bien sûr définir un assistant simple et utiliser simplement la vieille importation partout où cela est nécessaire.
root / tests / helper / redis.py
class MockRedis():
# stuff
root / tests / stuff / test.py
from helper.redis import MockRedis
def test():
print(MockRedis().get(stuff))
Cependant, ici, vous pourriez avoir des problèmes avec le chemin, car le module ne se trouve pas dans un dossier enfant du test. Vous devriez pouvoir surmonter cela (non testé) en ajoutant un __init__.py
à votre assistant
root / tests / helper / __ init__.py
from .redis import MockRedis
Ou ajoutez simplement le module d'assistance à votre PYTHONPATH
.
It seems great. However, I feel the documentation could be better.