I try to organized my Python projects using a folder structure. When I need to make tests I use something like the following.
.
|-- src
|   |-- b.py
|   `-- main.py
`-- tests
    `-- test_main.py
There is just one big problem with this approach. Pytest won't run if main.py is importing b.py.
So far I've tried placing empty __init__.py files inside the src and tests folders, both independently and together, but any of those seems to work.
It seems to me this is a pretty standard project, but I haven't been able to find a solution online. Should I use a different folder structure? Is there any recommended way to use pytest with this kind of projects?
This are the contents of the files:
# b.py
def triplicate(x):
        return x * 3
# main.py
from b import triplicate
def duplicate(x):
        return x * 2
# test_main.py
from src.main import duplicate
def test_duplicate():
        assert duplicate(2) == 4
And this is the error I get when running pytest:
==================================================================================================== ERRORS ====================================================================================================
_____________________________________________________________________________________ ERROR collecting tests/test_main.py ______________________________________________________________________________________
ImportError while importing test module 'C:\Users\edwar\test_pytest\tests\test_main.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
c:\python39\lib\importlib\__init__.py:127: in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
tests\test_main.py:1: in <module>
    from src.main import duplicate
src\main.py:1: in <module>
    from b import triplicate
E   ModuleNotFoundError: No module named 'b'
=========================================================================================== short test summary info ============================================================================================
ERROR tests/test_main.py
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Interrupted: 1 error during collection !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
=============================================================================================== 1 error in 0.15s ===============================================================================================
                Python uses the 'environment variable' PYTHONPATH to look for sources to import code from. By default, the directory you execute a python program is automatically included, but you want to include something like this when you test:
PYTHONPATH=$PYTHONPATH,../src python test_main.py
This is if you're executing a test from the source directory. Tools like IntelliJ (PyCharm) will let you add this as a value in your test invocation. Alternatively you can use export PYTHONPATH=.... (Note this is for a *nix environment, your mileage on windows may vary.)
The upshot is that every directory in PYTHONPATH will be loaded and Python will attempt to use it as a 'root' for modules you try to import. Your basic directory structure is the most idiomatic.
PYTHONPATH correctly.PYTHONPATH is modified and used 'under the hood'.src directory when running pytest tests.autoenv (a Python library) to enable the usage of .env files to manage this for you (at least within a virtualenv setup - a good idea generally).setup.py is also idiomatic for including many modules, and may provide a more convenient path for the situation you're handling.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With