I'm trying to figure out how to get python setup.py test
to run the equivalent of python -m unittest discover
. I don't want to use a run_tests.py script and I don't want to use any external test tools (like nose
or py.test
). It's OK if the solution only works on python 2.7.
In setup.py
, I think I need to add something to the test_suite
and/or test_loader
fields in config, but I can't seem to find a combination that works correctly:
config = { 'name': name, 'version': version, 'url': url, 'test_suite': '???', 'test_loader': '???', }
Is this possible using only unittest
built into python 2.7?
FYI, my project structure looks like this:
project/ package/ __init__.py module.py tests/ __init__.py test_module.py run_tests.py <- I want to delete this setup.py
Update: This is possible with unittest2
but I want find something equivalent using only unittest
From https://pypi.python.org/pypi/unittest2
unittest2 includes a very basic setuptools compatible test collector. Specify test_suite = 'unittest2.collector' in your setup.py. This starts test discovery with the default parameters from the directory containing setup.py, so it is perhaps most useful as an example (see unittest2/collector.py).
For now, I'm just using a script called run_tests.py
, but I'm hoping I can get rid of this by moving to a solution that only uses python setup.py test
.
Here's the run_tests.py
I'm hoping to remove:
import unittest if __name__ == '__main__': # use the default shared TestLoader instance test_loader = unittest.defaultTestLoader # use the basic test runner that outputs to sys.stderr test_runner = unittest.TextTestRunner() # automatically discover all tests in the current dir of the form test*.py # NOTE: only works for python 2.7 and later test_suite = test_loader.discover('.') # run the test suite test_runner.run(test_suite)
The command to run the tests is python -m unittest filename.py . In our case, the command to run the tests is python -m unittest test_utils.py .
The TestLoader class has a discover() function. Python testing framework uses this for simple test discovery. In order to be compatible, modules and packages containing tests must be importable from top level directory.
pytest supports running Python unittest -based tests out of the box. It's meant for leveraging existing unittest -based test suites to use pytest as a test runner and also allow to incrementally adapt the test suite to take full advantage of pytest's features.
If you use py27+ or py32+, the solution is pretty simple:
test_suite="tests",
From Building and Distributing Packages with Setuptools (emphasis mine):
test_suite
A string naming a unittest.TestCase subclass (or a package or module containing one or more of them, or a method of such a subclass), or naming a function that can be called with no arguments and returns a unittest.TestSuite.
Hence, in setup.py
you would add a function that returns a TestSuite:
import unittest def my_test_suite(): test_loader = unittest.TestLoader() test_suite = test_loader.discover('tests', pattern='test_*.py') return test_suite
Then, you would specify the command setup
as follows:
setup( ... test_suite='setup.my_test_suite', ... )
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With