Where Do the Python Unit Tests Go

Running unittest with typical test directory structure

The best solution in my opinion is to use the unittest command line interface which will add the directory to the sys.path so you don't have to (done in the TestLoader class).

For example for a directory structure like this:

new_project
├── antigravity.py
└── test_antigravity.py

You can just run:

$ cd new_project
$ python -m unittest test_antigravity

For a directory structure like yours:

new_project
├── antigravity
│   ├── __init__.py # make it a package
│   └── antigravity.py
└── test
├── __init__.py # also make test a package
└── test_antigravity.py

And in the test modules inside the test package, you can import the antigravity package and its modules as usual:

# import the package
import antigravity

# import the antigravity module
from antigravity import antigravity

# or an object inside the antigravity module
from antigravity.antigravity import my_object

Running a single test module:

To run a single test module, in this case test_antigravity.py:

$ cd new_project
$ python -m unittest test.test_antigravity

Just reference the test module the same way you import it.

Running a single test case or test method:

Also you can run a single TestCase or a single test method:

$ python -m unittest test.test_antigravity.GravityTestCase
$ python -m unittest test.test_antigravity.GravityTestCase.test_method

Running all tests:

You can also use test discovery which will discover and run all the tests for you, they must be modules or packages named test*.py (can be changed with the -p, --pattern flag):

$ cd new_project
$ python -m unittest discover
$ # Also works without discover for Python 3
$ # as suggested by @Burrito in the comments
$ python -m unittest

This will run all the test*.py modules inside the test package.

How do I run all Python unit tests in a directory?

With Python 2.7 and higher you don't have to write new code or use third-party tools to do this; recursive test execution via the command line is built-in. Put an __init__.py in your test directory and:

python -m unittest discover <test_directory>
# or
python -m unittest discover -s <directory> -p '*_test.py'

You can read more in the python 2.7
or python 3.x unittest documentation.


Update for 2021:

Lots of modern python projects use more advanced tools like pytest. For example, pull down matplotlib or scikit-learn and you will see they both use it.

It is important to know about these newer tools because when you have more than 7000 tests you need:

  • more advanced ways to summarize what passes, skipped, warnings, errors
  • easy ways to see how they failed
  • percent complete as it is running
  • total run time
  • ways to generate a test report
  • etc etc

Unittest tests order

You can disable it by setting sortTestMethodsUsing to None:

import unittest
unittest.TestLoader.sortTestMethodsUsing = None

For pure unit tests, you folks are right; but for component tests and integration tests...
I do not agree that you shall assume nothing about the state.
What if you are testing the state?

For example, your test validates that a service is auto-started upon installation. If in your setup, you start the service, then do the assertion, and then you are no longer testing the state, but you are testing the "service start" functionality.

Another example is when your setup takes a long time or requires a lot of space and it just becomes impractical to run the setup frequently.

Many developers tend to use "unit test" frameworks for component testing...so stop and ask yourself, am I doing unit testing or component testing?

Where should I put tests when packaging python modules?

You should put your test module inside the module it tests according to The Hitchhiker's Guide to Packaging.

Here is their example:

TowelStuff/
bin/
CHANGES.txt
docs/
LICENSE.txt
MANIFEST.in
README.txt
setup.py
towelstuff/
__init__.py
location.py
utils.py
test/
__init__.py
test_location.py
test_utils.py

This way your module will be distributed with its tests and users can use them to verify that it works with their set up.

See http://the-hitchhikers-guide-to-packaging.readthedocs.org/en/latest/creation.html.

python unit test not finding another folder module

I would recommend running python -m unittest from the parent directory. This will start automatic test discovery. But for this to work, you must create an empty __init__.py file in your tests folder.

Update: as a quick way to run test_validator.py itself (e.g. from an IDE), add this to the beginning:

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

and this to the end:

if __name__ == '__main__':
unittest.main()

Python unit test that uses an external data file

Usually what I do is define

THIS_DIR = os.path.dirname(os.path.abspath(__file__))

at the top of each test module. Then it doesn't matter what working directory you're in - the file path is always the same relative to the where the test module sits.

Then I use something like this is in my test (or test setup):

my_data_path = os.path.join(THIS_DIR, os.pardir, 'data_folder/data.csv')

Or in your case, since the data source is in the test directory:

my_data_path = os.path.join(THIS_DIR, 'testdata.csv')

Edit: for modern python

from pathlib import Path

THIS_DIR = Path(__file__).parent

my_data_path = THIS_DIR.parent / 'data_folder/data.csv'

# or if it's in the same directory
my_data_path = THIS_DIR / 'testdata.csv'

How to make my Python unit tests to import the tested modules if they are in sister folders?

The code you want is for using src/module_name.py

from src import module_name 

and the root directory is on your PYTHONPATH e.g. you run from the root directory

Your directory structure is what I use but with the model name instead from src. I got this structure from J Calderone's blog and



Related Topics



Leave a reply



Submit