From the question on running a single test via command line when tests are located within a sibling folder, the answer suggests using the -v option alongside the module name and test name to run a specific test.
Why does the -v option make this work? Specifying the module name and the test name makes sense since it corresponds to the unittest documnetation and obviously you need to specify which test to run. However, from what I can tell, the -v option corresponds to verbose output which shouldn't change the tests that the unittest module runs.
Apologies in advance if I've missed something obvious here.
So the reason this wasn't working was because of a pretty obvious, but stupid, error on my part 😅.
tldr; Use the full command line to run the tests (e.g. python3 -m unittest tests.module_name.TestClass.test_func) or if you're using a bash function, make sure the function accepts other arguments.
I had setup a bash function called run_tests to run unittests and I was trying to specify the module name and test name after calling that method. I.e. I had the following in .bash_profile:
run_tests ()
{
python3 -m unittest
}
and on the terminal, I did:
run_tests tests.module_name.TestClass.test_func
Since the bash function was not setup to accept arguments, the specific test I wanted to run wasn't actually being passed as an argument to unittest.
Obviously, using -v makes no difference if you use the run_tests function to try and run a specific test.
When I tested with the -v option, I used the full command python3 -m unittest -v tests.module_name.TestClass.test_func which is why I thought the -v option made it work. To test whether the -v option actually worked, I was lazy and ran run_tests tests.module_name.TestClass.test_func again since it was in my shell history instead of typing out the full command, which is what caused this confusion.
I am trying to use pytest within VS code, running in red hat linux. The environment that I am using means that I need to load modules such as pandas before running pytest. In the terminal I can run:
module load pandas
pytest
and the tests are successfully run. I can do this in both the standard terminal, in the Python Debug Console within VS code, and int he bash terminal within VS code. If, however, I press the "Run All Tests" button within VS code, then I just get an error telling me that it cannot find the pandas module.
How can I tell the test environment to run my module load pandas command before running pytest?
In this case I would create a file named conftest.py in the directory containing the tests. pytest automatically executes this file before the tests are run. In this file you could have Python execute shell commands. For the latter there are different options, but first try one of the easier ones.
More information on conftest.py:
In pytest, what is the use of conftest.py files?
When running nosetests I would like to drop in to an interactive console. However if I put the following anywhere in my code:
import code
code.interact(local=locals())
Nose just prints (InteractiveConsole) and does not provides the console to type in commands. Pytest treats code.interact as a failure. Is there a way I can drop into the console when running tests while also watching files for changes?
One way to get an interactive session under pytest is to set a breakpoint with
import pdb
pdb.set_trace()
Normally, pytest will supress this interactive session and will just hang when it hits the breakpoint. You can get around that by running pytest with the -s flag, which disables command line output capturing.
In the newest version of pytest, you can just use pytest.set_trace() without the -s flag to get the same behavior. See the docs for info.
We started writing our functional and unit test cases in python using nose framework. We started learning python while writing these tests. Since there are lot of dependencies between our test classes/functions, we decided to use proboscis framework on top of nose to control order of execution.
We have quite a few 'print' statements in our tests and proboscis seems to be ignoring these! Tests are running in expected order and testing them all but not printing our print statement data to console. Any idea what we are missing here?
BTW, we stopped deriving our classes from 'unittest.TestCase' once we moved to proboscis and decorated all classes and their member functions with #test.
Note: According to the Proboscis documentation "unused arguments get passed along to Nose or the unittest module", so the following should apply to Proboscis by replacing nosetests with python run_tests.py.
As #Wooble has mentioned in his comment, by default nose captures stdout and only displays it for failed tests. You can override this behaviour with the nosetests -s or --nocapture switch:
$ nosetests --nocapture
Like #Wooble also mentions in his comment, I recommend using the logging module instead of print. Then you only need to pass nosetests the -l DEBUG or --debug=DEBUG switch, where DEBUG is replaced by a comma separated list of the names of the loggers you want to display, to enable displaying of the logging output from your modules:
$ nosetests --debug=your-logger-name
I am using py.test for unit testing my python program. I wish to debug my test code with the python debugger the normal way (by which I mean pdb.set_trace() in the code) but I can't make it work.
Putting pdb.set_trace() in the code doesn't work (raises IOError: reading from stdin while output is captured). I have also tried running py.test with the option --pdb but that doesn't seem to do the trick if I want to explore what happens before my assertion. It breaks when an assertion fails, and moving on from that line means terminating the program.
Does anyone know a way to get debugging, or is debugging and py.test just not meant to be together?
it's real simple: put an assert 0 where you want to start debugging in your code and run your tests with:
py.test --pdb
done :)
Alternatively, if you are using pytest-2.0.1 or above, there also is the pytest.set_trace() helper which you can put anywhere in your test code. Here are the docs. It will take care to internally disable capturing before sending you to the pdb debugger command-line.
I found that I can run py.test with capture disabled, then use pdb.set_trace() as usual.
> py.test --capture=no
============================= test session starts ==============================
platform linux2 -- Python 2.5.2 -- pytest-1.3.3
test path 1: project/lib/test/test_facet.py
project/lib/test/test_facet.py ...> /home/jaraco/projects/project/lib/functions.py(158)do_something()
-> code_about_to_run('')
(Pdb)
The easiest way is using the py.test mechanism to create breakpoint
http://pytest.org/latest/usage.html#setting-a-breakpoint-aka-set-trace
import pytest
def test_function():
...
pytest.set_trace() # invoke PDB debugger and tracing
Or if you want pytest's debugger as a one-liner, change your import pdb; pdb.set_trace() into import pytest; pytest.set_trace()
Similar to Peter Lyon's answer, but with the exact code you need for pytest, you can add the following to the bottom of your pytest module (my_test_module.py) :
if __name__ == "__main__":
pytest.main(["my_test_module.py", "-s"])
Then you can invoke the debugger from the command line:
pdb3 my_test_module.py
Boom. You're in the debugger and able to enter debugger commands. This method leaves your test code un-littered with set_trace() calls and will run inside pytest 'normally'.
Simply use: pytest --trace test_your_test.py.
This will invoke the Python debugger at the start of the test
I'm not familiar with py.test, but for unittest, you do the following. Maybe py.test is similar:
In your test module (mytestmodule.py):
if __name__ == "__main__":
unittest.main(module="mytestmodule")
Then run the test with
python -m pdb mytestmodule.py
You will get an interactive pdb shell.
Looking at the docs, it looks like py.test has a --pdb command line option:
https://docs.pytest.org/en/7.2.x/reference/reference.html#command-line-flags
Add and remove breakpoints without editing source files
Although you can add breakpoints by adding breakpoint() or set_trace() statements to your code, there are two issues with this approach:
Firstly, once you have started running your code, there is no way to remove your breakpoint. I often find that once I start running my code and reach an initial breakpoint, I want to place another one and remove the initial breakpoint. After breakpoint() drops me into the debugger I can add additional breakpoints, but I can't remove the initial one. Although this can be mitigated somewhat by putting the initial breakpoint statement higher up, if you have parametrised tests then even that is limited. I may find myself repeating cont very often.
Secondly, it requires changes to the source code. You need to remember to remove all breakpoint() commands before committing any code to version control, you have to remove them before switching branches, etc. I sometimes find I want to use the debugger to compare test runs between two branches, and having to edit the source code to add a breakpoint every time makes that a considerably slower and more error-prone exercise. I may even want to add a breakpoint in a library I'm calling, in which case the file I'm editing may not even me in my git repository but somewhere deep in my conda environment, increasing the risk of forgetting to remove it. Editing files to add break points is, in my humble opinion, ugly.
To add and remove breakpoints interactively without editing any source files, you can evoke pytest as follows (in the bash shell):
python -mipdb $(type -p pytest) -s test_fileset.py
The -s flag is crucial here, because it stops pytest from messing with stdin and stdout, and when running inside the debugger, pytest will fail to mess with stdin and stdout and everything will go wrong. The exact calling syntax will be different for different shells.