简体   繁体   中英

Importing resources for unit testing using pytest: module level or test level?

I have been learning about the advantages of test-driven development, and am attempting to develop my first TDD app using pytest and the setuptools develop option. Going well so far. One question I have: where should resources that are to be tested be imported in my test_* modules?

For example, I could import thusly, at the module level:

from app.module1 import resource1, resource2

def test_resource1():
    assert test_resource1 == "expected value 1"

def test_resource2():
    assert test_resource2 == "expected value 2"

On the other hand, it seems like it makes more sense to do the imports in each test function:

def test_resource1():
    from app.module1 import resource1
    assert test_resource1 == "expected value 1"

def test_resource2():
    from app.module1 import resource2
    assert test_resource2 == "expected value 2"

This of course assumes the resources to be tested aren't needed anywhere else.

Aside from the difference in required characters to type, is there an advantage to doing one or the other?

The standard style guide tells "Imports are always put at the top of the file".

Function-level imports give no significant architectural or technical benefits.

The only valuable exceptions are temporarily inserted breakpoints, which are removed after debugging: import pdb; pdb.set_trace() import pdb; pdb.set_trace() or __import__('pdb').set_trace() .

If you import at the function/method level the objects will be in scope for a much shorter time, thus allowing them to be garbage collected much sooner than they otherwise would be. So it's mostly a memory consumption benefit.

question here is about scope of the test, if test A is intended to cover import of the module, then option B is good. keep in mind they all gonna fail on importing the same module (if there an issue with that module).

option is easier most of the time (less typing), cause if you have lots of tests, they won't actully run (you will fail on collect of the test)

one more thing to fear in this case is side-effects, and both options won't help in that regard, py.test has an option to clear/reload all loaded modules between test (it's not default)

to summarize, it's more of a reporting style concern.

Putting imports at the top is a standard convention and doing otherwise (except as noted in other answers for temporary debugging) will make your code less readable to most python developers.

There is no benefit to importing at the class/function level. If you are worried about namespace clashes between objects you are importing then instead of from app.module1 import resource1 do import app.module1 and call app.module1.resource1 in your test. This pattern is also recommended in the python docs Idioms and Anti-Idioms for reasons explained here https://docs.python.org/2/howto/doanddont.html .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM