Python tox: show stdout/prints on successful test run? - python

Sometimes I want to print some statements, to make sure unittests are running fine (even if it passes), but can't find an option that enables it.
If tests fail, then it does show custom prints as output, but if it passes, it does ignore prints or logs (I mean, it dont see them on terminal output).
I tried using verbosity, like -vvvv, but it still ignores my prints. With nose there is an option like --nologcapture. Is there something similar in tox?

tox as such is just a generic venv creator, deps installer and command executor. It doesn't do output capturing (unless you use --parallel). So it is on a different abstraction level from nose. tox can run your tests or anything else that is runnable via command line.
Like you already mentioned for nose: depending on your test runner you might need to deactivate output capturing to see prints coming from the tests. So if you use pytest for example you can use pytest -s to disable all output capturing (also see docs)
You can also print something after you ran the test by adding something like this in your tox.ini testenv:
[testenv:test]
[...]
commands =
<some test command>
python -c 'print("All is fine."))'

Related

Run pytest in PDB with pipenv

I saw this question: Can I debug with python debugger when using py.test somehow? but it doesn't really help, because I need to debug hooks, some of them not written by me, where modifying the code of the hook is really cumbersome.
Also, pytest runs through pipenv run. It's already difficult to make them both work together. I couldn't so far find a combination of pdb, pipenv and pytest that would launch each other.
Another way I could do it is by calling pytest.main() from my code, however, this means that other people who want to run my tests will have to use this "trampoline" to run other tests. I can live with this, but it still feels like it shouldn't be necessary.
I guess this is what you need, invoke pdb as early as possible:
`pipenv --py` -c 'import pdb, pytest; pdb.set_trace(); pytest.main()'

pytest run only the changed file?

I'm fairly new to Python, trying to learn the toolsets.
I've figured out how to get py.test -f to watch my tests as I code. One thing I haven't been able to figure out is if there's a way to do a smarter watcher, that works like Ruby's Guard library.
Using guard + minitest the behavior I get is if I save a file like my_class.rb then my_class_test.rb is executed, and if I hit enter in the cli it runs all tests.
With pytest so far I haven't been able to figure out a way to only run the test file corresponding to the last touched file, thus avoiding the wait for the entire test suite to run until I've got the current file passing.
How would you pythonistas go about that?
Thanks!
One possibility is using pytest-testmon together with pytest-watch.
It uses coverage.py to track which test touches which lines of code, and as soon as you change a line of code, it re-runs all tests which execute that line in some way.
To add to #The Compiler's answer above, you can get pytest-testmon and pytest-watch to play together by using pytest-watch's --runner option:
ptw --runner "pytest --testmon"
Or simply:
ptw -- --testmon
There is also pytest-xdist which has a feature called:
--looponfail: run your tests repeatedly in a subprocess. After each run py.test waits until a file in your project changes and then re-runs the previously failing tests. This is repeated until all tests pass after which again a full run is performed.
The fastest setup I got was when I combines #lmiguelvargasf #BenR and #TheCompiler answer into this
ptw --runner "pytest --picked --testmon"
you first gotta have them installed by
pip3 install pytest-picked pytest-testmon pytest-watch
If you are using git as version control, you could consider using pytest-picked. This is a plugin that according to the docs:
Run the tests related to the unstaged files or the current branch
Demo
Basic features
Run only tests from modified test files
Run tests from modified test files first, followed by all unmodified tests
Usage
pytest --picked

Using nose to test mixed python2 and python3 code

I have a project that has both python2 and python3 code in it (its a client/server thing; the server is python3 but there are python2 and python3 clients). I'm using nose to handle unit testing. The directory layout is (currently) basically like
client2
tests
client3
tests
server
tests
Is there a way to set up or use nose so that running node with python2 gets just the python2 tests, and similarly python3. For instance, something like:
client2
tests2
client3
tests3
server
tests3
... with some suitable nose arguments. I messed around with the -m option but couldn't get anywhere.
Looks like you will need a combo of --where and --py3where:
--py3where:
Look for tests in this directory under Python 3.x. Functions the same
as 'where', but only applies if running under Python 3.x or above.
Note that, if present under 3.x, this option completely replaces any
directories specified with 'where', so the 'where' option becomes
ineffective. [NOSE_PY3WHERE]
So for you it would be something like this:
nosetests --where=. --where=client2 --py3where=. --py3where=client3 --py3where=server -v
When using nosetests with python3 it will run client3 and server tests only. When running on python2 it will run client2 tests only.
Also, have a look at this question and answers for alternatives.

List tests with Nose in a machine-readable form

I know I can
list what tests would run with nosetests --collect-only
and run particular test with nosetests path/to/module:TestClass.test_method.
But I don't know how to combine these two steps. The output from "--collect-only" mode outputs the test docstrings, which is not usable for the other syntax.
I would like to do something like this somewhere in my bash script:
#!/bin/bash
nosetests --some-mode | while read test_spec;
do
nosetests $test_spec
# i.e. nosetest test/SomeTest:ATestSomeClass.test_something
# and then do something else with $? and $test_spec
done
So is there "--some-mode" like this? Or another way to obtain list of test_specs?
Background is that I have a test suite from an upstream project which is laid out to run by simply calling nosetests. However, in our situation it would make lot of sense to perform tests separately (even at the cost of losing ability to parallelize).
I could catch the output and parse it but that's dirty and would not allow early termination.
You can also use nosetests --with-xunit to output XUnit-formatted XML representation of test results, which will all pass when --collect-only is used. You'll have nosetests.xml to work with so that you do not have to rely on stdout.
I have put together a Perl script that naively parses debug output from nosetests -vvv --collect-only and reports it so that it can be used as above (noselist | while read test_spec;...).
It works for me now, althought it's kind of a hack so I'd rather have nosetests be able to do this, or have a more sane utility script, e.g. using internal Nose library.

How to use `pytest` from Python?

I'm working in a project that recently switched to the pytest unittest framework. I was used to calling my tests from Eclipse, so that I can use the debugger (e.g. placing breakpoints to analyze how a test failure develops). Now this is no longer possible, since the only way to run the tests is via the command line blackbox.
Is there some way to use pytest from within Python, so that one is not forced to drop out of the IDE? The tests should of course not be run in a separate process.
I think I can now answer my own question, it's pretty simple:
import pytest
pytest.main(args)
which is documented in the Section "Calling pytest from Python code".
Then I can run this module and/or start it with the integrated debugger.
args is the list of command-line arguments, so for example to run only particular tests I can use something like:
args_str = "-k test_myfavorite"
args = args_str.split(" ")
pytest.main(args)
It seems that now (py.test version 2.0+) someone can also do this :
import pytest
pytest.main('-x {0}'.format(argument))
# Or
# pytest.main(['-x', 'argument'])
Ref
This is now supported by pytest and described nicely in the documentation.
You can invoke pytest from Python code directly:
import pytest
pytest.main()
this acts as if you would call “pytest” from the command line. It will not raise SystemExit but return the exitcode instead. You can pass in options and arguments:
pytest.main(["-x", "mytestdir"])
For me it was this:
pytest.main(["-x", "path to test file", "args"])
For example:
import pytest
pytest.main(["-x", "/api/test", "-vv"])
Maybe you could give a try to pycharm it has direct integration with py.test (I use it at work) and debugger runs perfectly.
I have not tried with eclipse, but as was suggested in a related question, it is possible to use the --pdb command line option with py.test. Maybe it is possible to configure eclipse that way.
However, calling the standard import pdb;pdb.set_trace() will not directly call the debugger. First it will issue an error which in turn will activate the debugger. This might or might not make things work differently.
You can just run py.test --pdb if you just want to a debugger and don't need the IDE

Categories