Importing correctly with pytest
Question: I just got set up to use pytest with Python 2.6. It has worked well so far
with the exception of handling "import" statements: I can't seem to get pytest
to respond to imports in the same way that my program does.

My directory structure is as follows:

    
    
    src/
        main.py
        util.py
        test/
            test_util.py
        geom/
            vector.py
            region.py
            test/
                test_vector.py
                test_region.py
    

To run, I call `python main.py` from src/.

In main.py, I import both vector and region with

    
    
    from geom.region import Region
    from geom.vector import Vector
    

In vector.py, I import region with

    
    
    from geom.region import Region
    

These all work fine when I run the code in a standard run. However, when I
call "py.test" from src/, it consistently exits with import errors.

* * *

## Some Problems and My Solution Attempts

My first problem was that, when running "test/test_foo.py", py.test could not
"import foo.py" directly. I solved this by using the "imp" tool. In
"test_util.py":

    
    
    import imp
    util = imp.load_source("util", "util.py")
    

This works great for many files. It also seems to imply that when pytest is
running "path/test/test_foo.py" to test "path/foo.py", it is based in the
directory "path".

However, this fails for "test_vector.py". Pytest can find and import the
`vector` module, but it **cannot** locate any of `vector`'s imports. The
following imports (from "vector.py") both fail when using pytest:

    
    
    from geom.region import *
    from region import *
    

These both give errors of the form

    
    
    ImportError: No module named [geom.region / region]
    

I don't know what to do next to solve this problem; my understanding of
imports in Python is limited.

**What is the proper way to handle imports when using pytest?**

* * *

## Edit: Extremely Hacky Solution

In `vector.py`, I changed the import statement from

    
    
    from geom.region import Region
    

to simply

    
    
    from region import Region
    

This makes the import relative to the directory of "vector.py".

Next, in "test/test_vector.py", I add the directory of "vector.py" to the path
as follows:

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

This enables Python to find "../region.py" from "geom/test/test_vector.py".

This works, but it seems extremely problematic because I am adding a ton of
new directories to the path. What I'm looking for is either

1) An import strategy that is compatible with pytest, or

2) An option in pytest that makes it compatible with my import strategy

So I am leaving this question open for answers of these kinds.


Answer: **_import_** looks in the following directories to find a module:

  1. The **home directory** of the program. This is the directory of your root script. When you are running pytest your home directory is where it is installed (/usr/local/bin probably). No matter that you are running it from your src directory because the location of your pytest determines your home directory. That is the reason why it doesn't find the modules. 
  2. **PYTHONPATH**. This is an environment variable. You can set it from the command line of your operating system. In Linux/Unix systems you can do this by executing: '_export PYTHONPATH=/your/custom/path_ ' If you wanted Python to find your modules from the test directory you should include the src path in this variable.
  3. The **standard libraries** directory. This is the directory where all your libraries are installed. 
  4. There is a less common option using a **pth** file.

**_sys.path_** is the result of combining the **home directory** ,
**PYTHONPATH** and the **standard libraries** directory. What you are doing,
modifying **_sys.path_** is correct. It is something I do regularly. You could
try using **PYTHONPATH** if you don't like messing with **_sys.path_**

