83

My source files are located under src and my test files are located under tests. When I want to run a test file, say python myTest.py, I get an import error: "No module named ASourceModule.py".

How do I import all the modules from source needed to run my tests?

0

5 Answers 5

46

You could add that directory to the path:

import sys
sys.path.append('../src')

Maybe put this into a module if you are using it a lot.

Although this solution works for some situations, there are better solutions. See for example this answer.

Sign up to request clarification or add additional context in comments.

3 Comments

This is not OS agnostic. See the answer for having the same code work on both linux and Windows.
This is a code smell. Don't do that!
Agreed. Since this is still somehow the accepted and most upvoted answer, I added a link to a preferred solution.
27

If you don't want to add the source path to each test file or change your PYTHONPATH, you can use nose to run the tests.

Suppose your directory structure is like this:

project
    package
        __init__.py
        module.py
    tests
        __init__.py
        test_module.py

You should import the module normally in the test_module.py (e.g. from package import module). Then run the tests by running nosetests in the project folder. You can also run specific tests by doing nosetests tests/test_module.py.

The __init__.py in the tests directory is necessary if you want to run the tests from inside it.

You can install nose easily with easy_install or pip:

easy_install nose

or

pip install nose

nose extends unittest in a lot more ways, to learn more about it you can check their website: https://nose.readthedocs.org/en/latest/

2 Comments

+1 for "The __init__.py in the tests directory is necessary if you want to run the tests from inside it."
Nose is deprecated, but there is nose2 project you could use instead. The rest is the same as explained in this answer. Run nose2 command to automatically execute all tests. Nose2 looks for all files starting with test word.
24

The best (most manageable) solution appears to be using a virtualenv and setuptools/distribute to install a development copy of your (src) package. That way your tests execute against a fully "installed" system.

In the pystest docs there is a section on "good practices" explaining this approach, see here.

2 Comments

This is the best solution. The other two work, but are not as clean. The thing is for a beginner it might be simpler to just use the hacks above rather than spending hours understanding Python Packaging. If you have the time, go with this one.
I found using both solutions has its benefits. If I am iterating quickly and want to test my code in my src directory without building and standing up a virtual environment then using the sys.path trick is helpful. Then using tox for a full end-to-end test with an installed package when things are in a "good" state. I control this by setting an environment variable locally (LOCAL_PYTEST=true) and then checking that in tests/__init__.py and conditionally adding to sys.path.
20

On my system (Windows 10), I was required to do something like this:

import sys
import os
sys.path.append(os.path.dirname(os.path.realpath(__file__)) + "/../src")

Appending the relative directory directly to sys.path did not work

Comments

7

For those using Pytest:

  • You should not call your package src. That's meaningless and leads to confusing import statements such as from src import module. Rename the src folder to the name of your package (mypackage for the sake of this example)!
  • Make sure mypackage is recognized as a package by putting an empty __init__.py inside.
  • Put an empty conftest.py in the project folder.
  • Make sure there is no __init__.py in the test directory.

Looks like this:

myproject
    conftest.py
    mypackage
        __init__.py
        mymodule.py
    test
        test_mymodule.py

And make sure test_module.py contains the line:

from mypackage import mymodule

Source: Pytest docs

5 Comments

Indeed but that's what the OP asked for and it works. The "src" folder is quite nonstandard in Python. Just using the package name would be better.
from the pytest docs, "Good Integration Practices": Generally, but especially if you use the default import mode prepend, it is strongly suggested to use a src layout. Here, your application root package resides in a sub-directory of your root, i.e. src/mypkg/ instead of mypkg.
I see that using the src structure is more correct but it also adds many extra steps. E.g. the project has to be installed before it can be tested and so on.
or just add src to path, which is how pytest handles it
Having a src directory is not unfamiliar practice in Pyhon. It is even recommended by setuptools setuptools.pypa.io/en/stable/userguide/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.