Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Relative imports with unittest in Python

I am trying to use Python unittest and relative imports, and I can't seem to figure it out. I know there are a lot of related questions, but none of them have helped so far. Sorry if this is repetitive, but I would really appreciate any help. I was trying to use the syntax from PEP 328 http://www.python.org/dev/peps/pep-0328/ but I must have something wrong.

My directory structure is:

project/     __init__.py     main_program.py     lib/         __init__.py         lib_a         lib_b     tests/         __init__.py         test_a         test_b 

I run my tests using:

python -m unittest test_module1 test_module2 

test_a needs to import both lib/lib_a and main_program. This is the code from test_a I am trying to use for the import:

from ..lib import lib_a as lib from ...project import main_program 

both raise this error:

ValueError: Attempted relative import in non-package 

All of my init.py files are currently empty.

Any specific advice would be greatly appreciated!!

Edit:

This may be the answer: Python Packages? I'm still verifying if this will work.

Edit II:

To clarify, at this point I have attempted to run my test file in 3 different ways:

project/tests $ python -m unittest test_a project/tests $ python -m test_a project/tests $ ./test_a 

All three fail with the same error as above. When I use the same three syntaxes but in the project directory, I get this error:

ValueError: Attempted relative import beyond toplevel package 

Thanks again.

like image 347
J Jones Avatar asked Jan 31 '14 21:01

J Jones


People also ask

How do you use relative import in Python?

Relative imports use dot(.) notation to specify a location. A single dot specifies that the module is in the current directory, two dots indicate that the module is in its parent directory of the current location and three dots indicate that it is in the grandparent directory and so on.

Should I use relative or absolute imports Python?

With your new skills, you can confidently import packages and modules from the Python standard library, third party packages, and your own local packages. Remember that you should generally opt for absolute imports over relative ones, unless the path is complex and would make the statement too long.

Which is better Pytest or unittest?

Which is better – pytest or unittest? Although both the frameworks are great for performing testing in python, pytest is easier to work with. The code in pytest is simple, compact, and efficient. For unittest, we will have to import modules, create a class and define the testing functions within that class.


2 Answers

In my experience it is easiest if your project root is not a package, like so:

project/   test.py   run.py   package/     __init__.py     main_program.py     lib/       __init__.py       lib_a       lib_b     tests/       __init__.py       test_a       test_b 

However, as of python 3.2 , the unittest module provides the -t option, which lets you set the top level directory, so you could do (from package/):

python -m unittest discover -t .. 

More details at the unittest docs.

like image 127
kai Avatar answered Oct 14 '22 08:10

kai


I run with the same problem and kai's answer solved it. I just want to complement his answer with the content of test.py (as @gsanta asked). I've only tested it on Python 2.7:

from packages.tests import test_a, test_b import unittest  # for test_a unittest.main(test_a, exit=False)  # for test_b unittest.main(test_b) 

then you can just

../project $ python test.py 
like image 42
Rodrigo E. Principe Avatar answered Oct 14 '22 09:10

Rodrigo E. Principe