5

As suggested in the pytest documentation, I have set up my package with the intent not not distributing my tests along with my package:

setup.py
mypkg/
    __init__.py
    mypkg/
      appmodule.py  
tests/
    test_app.py
    ...

but I am confused about how to ensure that these tests will run correctly when present (e.g. on Travis CI, or in clones of the project directory).

I want the imports in my test scripts to apply to the source in the adjacent mypkg/ directory (and not to any mypkg that might be installed in site-packages), but I'm getting errors that puzzle me.

If I follow the advice in the pytest documentation and don't put an __init__.py in tests/ then with

from __future__ import absolute_import
from mypkg.appmodule import * 

I get

ImportError: No module named mypkg.appmodule

while with

from __future__ import absolute_import
from ..mypkg.appmodule import * 

I get

ValueError: Attempted relative import in non-package

And if I ignore the documentation and include an __init__.py, then with the latter I get

ValueError: Attempted relative import beyond top-level package

Only by including an __init__.py and using

from __future__ import absolute_import
from mypkg.appmodule import * 

will my tests run. But it isn't clear to me that this will import the source from the adjacent mypkg/ directory if a mypkg is installed in site-packages.

What is the correct way to organize my pytest tests so that they are separate from — and not distributed with — my projects source, but always import the adjacent source, and not version of the package that is installed elswehere?

azalea
  • 11,402
  • 3
  • 35
  • 46
orome
  • 45,163
  • 57
  • 202
  • 418

1 Answers1

2

The problem is just that python can't find your appmodule when you ask for it to look in the mypkg directory where it doesn't exist.

You've set the directories up correctly with:

setup.py
mypkg/
    __init__.py
    mypkg/
        appmodule.py  
tests/
    test_app.py
    ...

But since you've created another mypkg/ subdirectory to house your appmodule.py, you'll need to place __init__.py in that subdirectory for an import to work. The call would also be changed to:

from mypkg.mypkg.appmodule import *

Hope this helps.

Adam
  • 561
  • 3
  • 8
  • Yeah, so: the instructions are misleading in this case. – orome Dec 03 '15 at 21:40
  • @raxacoricofallapatorius why do you say that? I mean, the documentation says to use `mypkg/appmodule.py`. – Bruno Oliveira Dec 04 '15 at 01:12
  • I mean the `pytest` docs. They say not to have an `__init__.py` in `tests/`, which is (as you say) the only way this works. – orome Dec 04 '15 at 01:18
  • In this instance I meant that your mypkg/mypkg sub directory needs to contain \__init__.py as well. That's why python's throwing "ImportError: No module named mypkg.appmodule" at you -- because appmodule.py doesn't exist in the top mypkg/ directory. The pytest documentation you followed didn't account for the mypkg/mypkg sub-directory you created. – Adam Dec 04 '15 at 21:58
  • 1
    @raxacoricofallapatorius I actually had to just put a `__init__.py` in the `tests/` directory and called it a day. – trendsetter37 Feb 19 '16 at 16:39
  • @trendsetter37: Yes, that's clear. The question is why that contradicts the documentation. – orome Feb 19 '16 at 16:46
  • @raxacoricofallapatorius [here](https://github.com/trendsetter37/md5-checker/tree/dev) is an example of conftest.py working. Also note that I added `packages=find_packages(exclude=['contrib', 'docs', 'tests*']),` in my setup.py to prevent distribution of my test folder. – trendsetter37 Feb 23 '16 at 17:05