comment partager une variable entre les modules pour tous les tests dans py.test
J'ai plusieurs tests de la py.test qui sont situés dans plusieurs classes dans plusieurs fichiers.
Quelle est la façon la plus simple de partager un gros dictionnaire - que je ne veux pas de doublons avec toutes les méthodes de chaque classe dans chaque fichier pour être utilisé par py.test?
En bref, j'ai besoin de faire une "variable globale" pour chaque test. En dehors de py.de test, je n'ai pas besoin de cette variable, donc je ne veux pas de l'enregistrer dans les fichiers en cours d'essai. J'ai fait de l'utilisation fréquente de py.test de luminaires, mais cela semble exagéré pour ce besoin. C'est peut-être le seul moyen?
source d'informationauteur Trevor | 2014-03-31
Vous devez vous connecter pour publier un commentaire.
Mise à jour: faites défiler vers le bas pour une meilleure approche.
Hormis une meilleure pytest option spécifique proposé par @flub, vous pouvez créer une base
TestCase
classe, définir une variable de classe et sous-classe de la classe de base dans tous les tests que vous avez:Vous parler de la évidents et moins magique option: à l'aide d'un appareil. Vous pouvez l'appliquer à l'ensemble des modules à l'aide de
pytestmark = pytest.mark.usefixtures('big_dict')
dans votre module, mais alors il ne sera pas dans votre espace de noms de sorte demandant explicitement, il pourrait être la meilleure.Sinon, vous pouvez affecter des choses dans le pytest espace de noms à l'aide du crochet:
Et maintenant vous avez
pytest.my_big_dict
. Le luminaire est probablement encore plus agréable.Il ya des tonnes de choses que j'aime à propos de py.de test, mais une chose que je DÉTESTE absolument est mal comment il joue avec le code outils d'intelligence. Je suis en désaccord qu'un autouse luminaire déclarer une variable est le plus "clair" de la méthode dans ce cas, parce que non seulement il complètement déflecteur mon linter, mais aussi toute autre personne qui n'est pas familier avec py.test fonctionne. Il y a beaucoup de magie il y a, de l'omi.
Si, une chose que vous pouvez faire ne pas faire de votre linter exploser et ne nécessite pas de cas de test standard est de créer un module appelé globals. À l'intérieur de ce module, stub les noms des choses que vous voulez global {} ou Aucun et importer le module global dans vos tests. Puis dans votre conftest.py fichier, utilisez la py.test de crochets pour définir (ou réinitialiser) votre variable globale(s) selon le cas. Ceci a l'avantage de vous donner le stub pour travailler avec lors de la construction de tests et de l'ensemble des données pour les tests lors de l'exécution.
Par exemple, vous pouvez utiliser le
pytest_configure()
crochet pour définir votre dict droit lors de la py.le test démarre. Ou, si vous voulez vous assurer que les données était vierge entre chaque test, vous pouvez autouse un appareil à attribuer à votre variable globale de votre état connu avant chaque test.Un autre avantage de cette approche est que vous pouvez utiliser le type de l'affinage dans votre globals module pour vous donner la complétion de code sur les objets globaux dans votre test, qui n'est probablement pas nécessaire pour un dict, mais je trouve ça pratique quand je suis en utilisant un objet (comme webdriver). 🙂
D'avoir un gros dictionnaire de variables globales que chaque test est probablement une mauvaise idée. Si possible, je vous suggère de refactoring vos tests pour éviter ce genre de chose.
Cela dit, voici comment j'allais le faire: définir un autouse luminaire qui ajoute une référence au dictionnaire dans l'espace de noms global de chaque fonction.
Voici un peu de code. Tout est dans le même fichier, mais vous pouvez déplacer l'appareil à
conftest.py
au plus haut niveau de vos tests.Voici la sortie de lorsque j'exécute ce code:
Notez que vous ne pouvez pas utiliser une session dans l'étendue du luminaire, car alors vous n'avez pas accès à chaque fonction de l'objet. De ce fait, je suis en train de faire assurez-vous de définir mon grand mondial dictionnaire une fois et utiliser des références à -- si j'ai défini le dictionnaire que l'instruction d'affectation, une nouvelle copie sera faite à chaque fois.
En conclusion, de faire quelque chose comme ceci est probablement une mauvaise idée. Bonne chance 🙂
Vous pouvez ajouter votre variable globale comme une option à l'intérieur de la
pytest_addoption
crochet.Il est possible de le faire de façon explicite avec
addoption
ou de l'utilisationset_defaults
méthode si vous voulez que votre attribut être déterminée sans une inspection de la ligne de commande, docsLorsque l'option a été défini, vous pouvez le coller à l'intérieur de n'importe quelle fixation avec
request.config.getoption
et ensuite de le passer le test explicitement ou avec autouse.Alternativement, vous pouvez passer votre option dans presque n'importe quel crochet à l'intérieur de la
config
objet.Je suis surpris pas de réponse mentionné la mise en cache pas: depuis la version 2.8,
pytest
a un puissant mécanisme de cache.Exemple d'utilisation
Accéder aux données dict dans les tests via builtin
request
appareil:Le partage des données entre les séries de tests
La chose cool à propos de
request.cache
est qu'il est conservé sur le disque, de sorte qu'il peut même être partagé entre les séries de tests. C'est pratique lorsque vous exécutez des tests distribués (pytest-xdist
) ou ont une longue génération de données qui ne changent pas une fois généré:Maintenant les tests n'aurez pas besoin de recalculer la valeur sur les différentes séries de tests, à moins de vider le cache sur disque de manière explicite. Prendre un coup d'oeil ce qui est actuellement dans le cache:
Relancer les tests avec le
--cache-clear
drapeau de supprimer le cache et forcer les données à être recalculé. Ou tout simplement supprimer le.pytest_cache
dans le répertoire racine du projet dir.Où aller à partir d'ici
La section dans
pytest
docs: Cache: travailler avec la croix-testrun état.