Python importing inside a project with pytest

46 views Asked by At

I am trying to add some unit tests to a project, but the imports inside the project are not working.

The project structure is as follows:

root
| src
| | __init__.py
| | bsp.py
| | helpers.py
| test
| | __init__.py
| | test_helpers.py

both init.py are empty. bsp.py looks as follows:

class BSP:
    # some class stuff

helpers.py looks as follows:

from bsp import BSP

def func(x: BSP) -> BSP:
    return x

Finally test_helpers.py looks as follows:

from src.helpers import func
from src.bsp import BSP
from unittest import TestCase

class TestFunc(TestCase):
    def test_func(self):
        x = BSP()
        assert func(x) == x

When I run pytest from root, importing does not work:

File "...\\root\\tests\\test_helpers.py", line 1, in \<module\>
from src.helpers import func
File "...\\root\\src\\helpers.py", line 1, in \<module\>  
from bsp import BSP
ModuleNotFoundError: No module named 'bsp'

However running the function from src does work.

I am probably doing something dumb, but I have been looking for a while and am unsure what I am doing wrong :sweat_smile:

I have already tried:

  • Adding . in front of bsp in from bsp import BSP in src/helpers.py; However now imports in the src are broken (e.g. src/main.py executes func from helper, raises an import error if a . is added)
  • Tried using pytest, py -m pytest, unittest, py -m unittest
  • Tried adding init.py in root, and adding/removing from src/test
2

There are 2 answers

2
ASK On

I had a similar issue recently. If you are using PyCharm, this might do the trick. Setting the 'sources root' folder.

  1. Right-click your src folder.
  2. Go to the last option "Mark directory as".
  3. Select 'Sources Root'.

Setting your sources root

Hope this helps. Let me know if it works.

1
Pieter van Beerendonk On

Adding;

import os, sys
sys.path.append(os.path.dirname(os.path.realpath(__file__)))

to src/\_\_init\_\_.py makes it work for both running the function inside the package, and from pytest. As suggested here.