2017-09-08 1 views
0

je la structure suivante:Pourquoi pytest exécutent des fonctions à l'importation

main/ 
|-- __init__.py 
|-- foo.py 
|-- bar.py 
|-- tests/ 
    |-- __init__.py 
    |-- test_foo.py 
    |-- test_bar.py 

intérieur test_foo.py Je l'importation de certains paquets (par exemple os, sys), j'importer également une fonction d'assistance de foo.py:

from main.foo import testAllLevels 

Lorsque j'essaie d'exécuter des tests de main/:

$ pytest tests/ 

Je vois que la fonction testAllLevels a également été collectée et exécutée comme un test et (obstinément) échoué. Ma question est comment puis-je sauter cette fonction de la découverte de test?

+0

Essayez de décorer la fonction avec '@ pytest.mark.skip' – Mangohero1

+0

Est-ce vraiment appelé' testAllLevels'? Selon [les docs] (https://docs.pytest.org/en/latest/goodpractices.html # conventions-for-python-test-discovery), pytest ne doit collecter que des fonctions dont le nom commence par 'test_'. – BrenBarn

+0

@ mangoHero1 lorsque je marque la fonction dans 'foo.py', elle ignore tous les tests dans' test_foo.py'. – mfedoten

Répondre

1

Si vous voulez éviter testAllLevels d'être collectées comme un test, vous devez créer un fichier appelé pytest.ini et le mettre à l'intérieur dossier main ou tests.

Le contenu de pytest.ini devrait être quelque chose comme ceci:

[pytest] 
python_functions=test_ 

Notez que cela signifie aussi que toutes vos fonctions de test doivent avoir un préfixe de test_ à partir de maintenant. Le comportement par défaut de pytest consiste à collecter des fonctions avec le préfixe test (pas test_).

Pour répondre à la question à propos de why functions are run on import?, essayez l'expérience suivante. Dans votre test_foo.py, ajoutez une ligne pour obtenir une référence interne au module test_foo.py lui-même.

from main.foo import testAllLevels 
reference_to_current_module = sys.modules[__name__] 

Ensuite, dans le même module, créez un test qui ressemble à ceci:

def test_01(): 
    print(dir(reference_to_current_module)) 
    reference_to_current_module.testAllLevels() 

La sortie du dir() vous montrera que testAllLevels est devenu une fonction légitime appartenant à test_foo.py après l'importation L'instruction est exécutée. Cela a été vérifié en appelant la fonction via la référence à test_foo.py. Je pense qu'il a été collecté par pytest parce que c'est une fonction "appartenant à" un module de test et son nom de fonction a un préfixe test.

+0

Super, ça a marché. Encore serait intéressant de savoir pourquoi les fonctions sont exécutées sur l'importation, parce que pour moi, il ne semble pas intuitive – mfedoten

+0

Bon, j'ai édité ma réponse pour inclure ce que je crois que pytest collecter la fonction importée. – ldiary

0

La solution est de changer

from main.foo import testAllLevels 

à

from main import foo 

Et puis appelez avec foo.testAllLevels. Comme ça testAllLevels n'est pas exécuté comme un test. Quelque chose me dit que ce n'est pas la solution optimale.

Donc la question est toujours ouverte. Si quelqu'un connaît une raison pour ce comportement qui aiderait beaucoup.