I made my project with setuptools
and I want to test it with tox
. I listed dependencies in a variable and added to setup()
parameter (tests_require
and extras_require
). My project needs to install all of the dependencies listed in tests_require
to test but pip install
is not installing them.
I tried this but it did not work:
install_command = pip install {opts} {packages}[tests]
How can I install test dependencies without having to manage multiple dependency lists (i.e. Having all dependencies listed in both test_requirements.txt
and the tests_require
variable)?
I've achieved this by committing a slight abuse of extra requirements. You were almost there trying the extras syntax, just that tests_require
deps aren't automatically available that way.
With a setup.py
like this:
from setuptools import setup
test_deps = [
'coverage',
'pytest',
]
extras = {
'test': test_deps,
}
setup(
# Other metadata...
tests_require=test_deps,
extras_require=extras,
)
You can then get the test dependencies installed with the extras syntax, e.g. from the project root directory:
$ pip install .[test]
Give that same syntax to Tox in tox.ini
, no need to adjust the default install_command
:
[testenv]
commands = {posargs:pytest}
deps = .[test]
Now you don't need to maintain the dependency list in two places, and they're expressed where they should be for a published package: in the packaging metadata instead of requirements.txt
files.
It seems this little extras hack is not all that uncommon.
What you can do is have a single file (called test_requirements.txt
) and list out the test dependencies like so:
dnspython==1.12.0
easydev==0.8.3
enum34==1.0.4
fabric==1.10.1
...
Then, in setup.py
, parse and store the file contents in a list and pass that list to setup
:
tests_require = [line.strip() for line in
open('test_requirements.txt')
if line.strip() and not line.strip().startswith('--')]
setuptools.setup(
...
tests_require=tests_require,
...
)
If you use the following command, Tox will install your test_requires
before running the tests:
commands = {envpython} setup.py test
You'll also need to add to setup.py where are the tests with this:
test_suite="tests_module"
Finally, here's an answer for a similar question with a nice example.