2017-10-13 4 views
1

J'ai un objet global dans mon fichier principalComment monkeypatch l'environnement en utilisant pytest dans conftest.py?

# reporter.py 

from os import environ 
from influxdb import InfluxDBClient 

influxdb_client = InfluxDBClient(host=environ['INFLUXCLOUD_HOST'], 
           username=environ['INFLUXCLOUD_USERNAME'], 
           password=environ['INFLUXCLOUD_PASSWORD'], 
           ssl=True, 
           timeout=4*60) 

def foo(): 
    pass 

J'utilise pytest et je veux définir des valeurs fausses à ces variables d'environnement. J'ai ce qui suit dans mon conftest.py:

# conftest.py 

import pytest 

@pytest.fixture(scope='session', autouse=True) 
def setup_env(monkeypatch): 
    monkeypatch.setenv('INFLUXCLOUD_HOST', 'host') 
    monkeypatch.setenv('INFLUXCLOUD_USERNAME', 'username') 
    monkeypatch.setenv('INFLUXCLOUD_PASSWORD', 'password') 

Cependant, quand je import reporter dans mon dossier de test, je reçois un KeyError que INFLUXCLOUD_HOST manque dans env.

Pourquoi pytest n'exécute-t-il pas le setup_env et monkeypatch mon environnement? Y a-t-il un moyen de le faire?

+0

Pouvez-vous s'il vous plaît montrer votre fichier de test et comment votre reporter d'importation? –

Répondre

0

Le problème ici réside dans une mauvaise compréhension de la taille de la session.

Pour savoir quels tests & appareils autoused existent, pytest doit importer les fichiers de test & conftest plugins. Puis il scanne les modules importés, et recherche les appareils & fonctions de test & classes de test & etc. Ceci est appelé "collection" en termes de pytest. Ce n'est qu'après la collecte de tous les tests que pytest décide de les exécuter et d'organiser le plan d'exécution, en particulier lorsque les appareils sont préparés. Les projecteurs de la portée de la session sont préparés en premier et arrachés en dernier - avant que les tests ne commencent et après que tous les tests soient terminés.

Cependant, l'importation des fichiers de test & conftest suppose l'exécution de ces modules - comme l'importation de tout autre module Python, non lié à pytest. Donc, quand vous faites import reporter depuis votre fichier de test, ou même si vous mettez cette variable globale directement dans votre fichier de test, ce module est exécuté, et il essaie d'utiliser les variables env. Mais les appareils ne sont pas encore exécutés (et pytest ne sait pas encore leur existence). Par conséquent, cela échoue.

Même si vous allez import reporter à partir de l'intérieur de la fonction de test, cela n'aidera pas beaucoup, car pytest peut essayer d'importer ce module reporter.py avant pendant la phase de collecte. Pytest le filtrerait en raison de l'absence des fonctions/classes de test, mais la tentative d'importation sera effectuée et échouera.

La meilleure solution consiste ici à "emballer" le client dans un appareil et à l'utiliser à la place de la variable globale.