2017-06-14 1 views
3

J'ai un morceau de code avec une suite de tests étendue, que nous exécutons en utilisant py.test. J'ai récemment rencontré un problème où un nouveau module aurait dû importer un module différent pour fonctionner correctement. Toutefois, étant donné que ce module a été importé ailleurs dans la suite de tests, py.test n'a pas généré d'erreur. Ce n'est que bien plus tard que ce bug a surgi. J'ai créé un exemple reproductible minimal.Les masques Py.test manquant les importations

Exemple minimal Reproductibles

Structure du projet:

set.py 
fail/ 
    __init__.py 
    thing.py 
    other.py 
tests/ 
    test_thing.py 
    test_other.py 

Lorsque ces fichiers contiennent le code suivant:

fail/thing.py:

import fail 

def needs_do_it(): 
    return fail.other.do_it() + 100 

fail/other.py:

def do_it(): 
    return 100 

tests/test_thing.py:

import fail.thing 

def test_needs_do_it(): 
    assert fail.thing.needs_do_it() == 200 

tests/test_other.py:

import fail.other 

def test_do_it(): 
    assert fail.other.do_it() == 100 

Comportement attendu

Si vous essayez d'exécuter la fonction needs_do_it, vous devriez obtenir une erreur, puisque seul fail est importé, non fail.other:

>>> import fail.thing 
>>> fail.thing.needs_do_it() 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "fail/thing.py", line 4, in needs_do_it 
    return fail.other.do_it() + 100 
AttributeError: 'module' object has no attribute 'other' 

Je me attends donc qu'un test en cours d'exécution sous py. test exposerait cette erreur lors de l'importation. Cependant, il masque totalement ce problème.

comportement réel

Because test_other.py importations test.other, py.test masque l'erreur.

$ py.test 

========== test session starts ========== 
platform darwin -- Python 2.7.13, pytest-3.1.2, py-1.4.34, pluggy-0.4.0 
rootdir: /Users/eswanson/Sandbox/pytest-test, inifile: 
collected 2 items 

tests/test_other.py . 
tests/test_thing.py . 
========== 2 passed in 0.01 seconds ========== 

Ma question

Mon quesiton est en trois parties:

  1. Quelle est la cause profonde de ce problème?
  2. Est-ce que ce comportement attendu pour py.test ou quelque chose que je devrais soulever un problème?
  3. Est-ce que je peux faire en tant qu'utilisateur de pytest pour moi d'obtenir de meilleures garanties que je ne suis pas en plissant les importations dans l'avenir

Répondre

0

La même chose se produit lorsque vous importez fail.other dans le shell Python Eh bien, parce que les modules Python sont des singletons:

>>> import fail.thing 
>>> fail.thing.needs_do_it() 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/home/florian/tmp/fo/fail/thing.py", line 4, in needs_do_it 
    return fail.other.do_it() + 100 
AttributeError: module 'fail' has no attribute 'other' 
>>> import fail.other 
>>> fail.thing.needs_do_it() 
200