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># orpython -m unittest discover -s <directory> -p '*_test.py'
You can read more in the python 2.7or 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
In python 3, if you're using unittest.TestCase
:
- You must have an empty (or otherwise)
__init__.py
file in yourtest
directory (must be namedtest/
) - Your test files inside
test/
match the patterntest_*.py
. They can be inside a subdirectory undertest/
, and those subdirs can be named as anything.
Then, you can run all the tests with:
python -m unittest
Done! A solution less than 100 lines. Hopefully another python beginner saves time by finding this.
You could use a test runner that would do this for you. nose is very good for example. When run, it will find tests in the current tree and run them.
Updated:
Here's some code from my pre-nose days. You probably don't want the explicit list of module names, but maybe the rest will be useful to you.
testmodules = [ 'cogapp.test_makefiles', 'cogapp.test_whiteutils', 'cogapp.test_cogapp', ]suite = unittest.TestSuite()for t in testmodules: try: # If the module defines a suite() function, call it to get the suite. mod = __import__(t, globals(), locals(), ['suite']) suitefn = getattr(mod, 'suite') suite.addTest(suitefn()) except (ImportError, AttributeError): # else, just load all the test cases from the module. suite.addTest(unittest.defaultTestLoader.loadTestsFromName(t))unittest.TextTestRunner().run(suite)