0

I've been changing directory structure around and adding random init.py and things all over the place for like two hours now and I can't figure out how to get pytest to run a test that imports a file from one directory level up.

Right now, my directory structure is:

├── conftest.py
├── junk
│   ├── __init__.py
│   └── ook.py
└── tests
    ├── test_ook.py

and the contents of ook.py are:

def ook():
    pass

and the contents of test_ook.py are:

from ook import ook


def test_horse():
    pass

The output of running both pytest and python -m pytest is:

ImportError while importing test module '/home/z9/repos/test/tests/test_ook.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
tests/test_ook.py:1: in <module>
    from ook import ook
E   ModuleNotFoundError: No module named 'ook'

This code is copied from this post: Ensuring py.test includes the application directory in sys.path

Other people say it works for them - it works for me in python, like when I write a script to from ook import ook that works fine, but in pytest it just can't figure it out.

Python 3.7, pytest 5.2.2

Ok so to update, the real problem is if ook.py needs to import something. It only works with absolute imports -> the behavior is different when you run "python -m pytest" than "python"

2 Answers2

1

Your code is in junk/ook.py so the import in tests/test_ook.py should read:

from junk.ook import ook

There really isn't anything special going when pytest is run regarding imports and how Python works. To use a relative import, ook and tests would need to belong to the same package. If you moved tests/ directory to junk/ where ook.py is, then in junk/tests/test_ook.py you could use:

from ..ook import ook
tmt
  • 7,611
  • 4
  • 32
  • 46
  • So that works but it doesn't solve my problem. I don't want to use absolute imports for literally everything -> like If I'm importing something that's in the same directory I shouldn't have to use them. It runs in python, like the python recursive finder thing that finds what you mean by the import can find the import, but for some reason pytest doesn't do the same thing. – Florian van Kampen-Wright Nov 13 '19 at 01:55
  • Your original `from ook import ook` is an absolute import. `from .ook import ook` would be a relative one and it's relative to the module where the import happens. See my updated answer on them belonging to the same `junk` package. – tmt Nov 13 '19 at 07:08
  • Ah ok so I looked up the absolute / relative terminology, you're right I'm a bit off. But I still can't import anything into ook, like when pytest runs it it can't deal with the imports Should I like, make an updated post or something? The problem is now a bit removed from the op – Florian van Kampen-Wright Nov 13 '19 at 18:52
  • So now everywhere in the project I'm using `from . import xxxx` and `from a.b.c import xxxx`. It's mostly just confusing that both my ide and python work with the other style. – Florian van Kampen-Wright Nov 13 '19 at 19:29
  • Pytest **is** Python. There is no magical import system in pytest itself. You can try it by creating a script within *tests/* with the import and then invoking it with Python and with pytest **not** involved in any way. You should observe the same error. The reason why it works in a Python console very much depends on your current working directory and thus PYTHONPATH currently set. The reason why your IDE might see the import as correct depends on some assumptions it makes because the IDE doesn't run your code. Python does. – tmt Nov 13 '19 at 19:45
0

For importing python modules from other directory path in the pytest execution, you have to modify the ini file of pytest (pytest.ini).

Add a file pytest.ini in the location next to conftest.py with the following format:-

[pytest]
python_paths = . junk/

After that, you could import it from all the location

Please refer:- pytest run tests inside a class with a constructor

nikhilesh_koshti
  • 393
  • 1
  • 10