The results of python tests are cached for only a short time in the VSCode MS python extension.
Whether they succeeded or failed is only cached for a short while, and then they revert back to question marks again.
How to retain the results of the tests?
I think it has to do with this some logs that I see in the Output for "Python Test Log", which shows many (~30) of these lines:
python /home/.../.vscode/extensions/ms-python.python-2020.6.89148/pythonFiles/testing_tools/run_adapter.py discover pytest -- --rootdir /home/projectdir --cache-clear -s
In particular the --cache-clear is suspicious, however I don't know what is triggering these outputs.
So my question is: how to remove --cache-clear from the call? Or maybe something else is going on entirely?
I too found myself in need of disabling this vscode behaviour.
I'm using pytest with the pytest-html plugin, and after all tests have run, as soon as i change a test file and save, this command is automatically run by vscode:
python c:\Users\username\.vscode\extensions\ms-python.python-2021.6.944021595\pythonFiles\testing_tools\run_adapter.py discover pytest -- --rootdir c:\Users\username\app\app-test-automation -s --cache-clear --html=report.html --self-contained-html tests
Which inevitably overwrite the .html test report.
I haven't found a way to remove the --cache-clear from the call.
BUT
You can disable the auto discovery of test (guilty of rerunning the command with the --cache-clear flag) by changing the following vscode setting:
Picture of the setting from the vscode settings menu
Related
Everything works fine with PyCharm and pytest, except if I have failing tests, then it duplicates the error output:
One of actual failures if the red one and other is white. This is really annoys, and I haven't found any way to disable such behaviour.
There is an option to disable log via py.test, however it will disable all logging.
Note: everything works as expected if I run python -m pytest test.py.
I think that is a feature not a bug. The top level is being emitted during the testing which allows you to review the failure before the testing is complete. The second copy of the results is the summary which effectively removes any of the text that was showing test progress.
You can easily view just part of the test output by clicking on the test hierarchy:
The duplicated output can be elimited by running pytest with the -q or --quiet parameter.
You can configure the parameter to be applied to all PyCharm pytest tests by setting it in Edit Configurations --> Templates --> Python Tests --> pytest --> Additional Arguments.
This will then apply those arguments to all new run configurations. If you have a bunch of existing test run configurations, deleting all of them and then re-generating them by running a test or tests using the gutter icon is the quickest way to reset the output.
I have a Python project and a tests task, set up to run pytest from the project's working directory.
Doing Run 'tests' with coverage from the Run menu successfully runs the tests, and the console results shows that coverage was measured - e.g. 53% cover for mws.py.
The automatically applied coverage (as on the right) is 0% for all files, I'm not sure why. I'm using IntelliJ 2017.2.2 EAP.
NB: there is a related five year old question here, but the top rated solution there doesn't apply. There is no error message in the results console in this case.
I had a similar issue, but the accepted solution here didn't solve it.
I had pytest automatically run coverage in its configuration file.
In PyCharm, I added a Run Configuration to run all my tests with pytest.
It seemed to work, and I saw all tests running and got their results to display in PyCharm's run window.
But soon I noticed there were two problems:
When I selected "Run with coverage" I got an error like "coverage results not found", and all files showed 0% coverage.
Breakpoints in tests were not hit when running test in Debug mode.
Both problems disappeared when I added --no-cov to the "Additional Arguments" passed to to pytest (this option is in the Run Configuration).
So It seems the fix was to tell pytest to not run coverage when running it from PyCharm. Both "Run with coverage" option and the Breakpoints in tests now work.
I think the problem lies in you use pytest-cov, so Pycharm cannot parse the result which is shown in text like 53% generated by pytest-cov;
So Changes option in pytest.ini to addopts = -s -v when you want to use Pycharm built in coverage tools.
In this command -v stands for verbosity and -s for disabling all output.
Take a look at my answer for other question about same issue: https://stackoverflow.com/a/45729723/1229510
Basically if you use symlinks - coverage display won't work.
How do I debug py.test in PyCharm when coverage is enabled?
Coverage is enabled using --cov=project --cov-report=term-missing, removing this and breakpoints are hit.
Versions: pycharm 5.0.3, pytest==2.8.5, pytest-cache==1.0, pytest-cov==2.2.0, pytest-pep8==1.0.6, pytest-xdist==1.13.1, python-coveralls==2.6.0.
(thanks for jon's advice on further diagnosing the issue)
There is now a flag in py.test to disable coverage which you can activate when running tests from PyCharm.
The flag to use is --no-cov. If you want this to apply to all your test runs you can add this to the default pytest configuration as below:
Extra tip: You probably also want a -s flag in there so output isn't swallowed by py.test. See https://stackoverflow.com/a/17810324/238166 for details.
In case you receive an "unrecognized argument" error, you may need to install pytest-cov, e.g. by pip install pytest-cov.
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.
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.