How to run tests without installing package?

Question:

I have some Python package and some tests. The files are layed out following http://pytest.org/latest/goodpractices.html#choosing-a-test-layout-import-rules

Putting tests into an extra directory outside your actual application
code, useful if you have many functional tests or for other reasons
want to keep tests separate from actual application code (often a good
idea):

setup.py   # your distutils/setuptools Python package metadata
mypkg/
    __init__.py
    appmodule.py
tests/
        test_app.py

My problem is, when I run the tests py.test, I get an error

ImportError: No module named ‘mypkg’

I can solve this by installing the package python setup.py install but this means the tests run against the installed package, not the local one, which makes development very tedious. Whenever I make a change and want to run the tests, I need to reinstall, else I am testing the old code.

What can I do?

Asked By: Colonel Panic

||

Answers:

Import the package using from .. import mypkg. For this to work you will need to add (empty) __init__.py files to the tests directory and the containing directory. py.test should take care of the rest.

Answered By: otus

The normal approach for development is to use a virtualenv and use pip install -e . in the virtualenv (this is almost equivalent to python setup.py develop). Now your source directory is used as installed package on sys.path.

There are of course a bunch of other ways to get your package on sys.path for testing, see Ensuring py.test includes the application directory in sys.path for a question with a more complete answer for this exact same problem.

Answered By: flub

I know this question has been already closed, but a simple way I often use is to call pytest via python -m, from the root (the parent of the package).

$ python -m pytest tests

This works because -m option adds the current directory to the python path, and hence mypkg is detected as a local package (not as the installed).

See:
https://docs.pytest.org/en/latest/usage.html#calling-pytest-through-python-m-pytest

Answered By: Kota Mori

On my side, while developing, I prefer to run tests from the IDE (using a runner extension) rather than using the command line. However, before pushing my code or prior to a release, I like to use the command line.

Here is a way to deal with this issue, allowing you to run tests from both the test runner used by your IDE and the command line.

My setup:

  • IDE: Visual Studio Code

  • Testing: pytest

  • Extension (test runner): https://marketplace.visualstudio.com/items?itemName=LittleFoxTeam.vscode-python-test-adapter

  • Work directory structure (my solution should be easily adaptable to your context):

    project_folder/
    
        src/
            mypkg/
                __init__.py
                appmodule.py
        tests/
             mypkg/
                appmodule_test.py
        pytest.ini           <- Use so pytest can locate pkgs from ./src 
        .env                 <- Use so VsCode and its extention can locate pkgs from ./src
    
  • .env:

     PYTHONPATH="${PYTHONPATH};./src;"
    
  • pytest.ini (tried with pytest 7.1.2):

     [pytest]
     pythonpath = . src
    
  • ./src/mypkg/appmodule.py:

     def i_hate_configuring_python():
         return "Finally..."
    
  • ./tests/mypkg/appmodule_test.py:

    from mypkg import app_module
    
    
    def test_demo(): 
        print(app_module.i_hate_configuring_python())
    

This should do the trick

Answered By: Greg7000
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.