Why is using the verbose flag necessary to run a specific unittest? - python

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.

Related

pytest: how to override command line option in python program?

By default, pytest inflates the error traceback massively and printly some information into sysout stream that are redundant: Considering that I'm using PyCharm, it is really obfuscating to see code snippet out of context, while they are already available in the IDE & debugging interface.
As a result, I intend to set pytest traceback to native permanently. However, according to the documentation, the only way to do so is to add extra command line argument when launching the test runner:
-tb=native
I would like to make my test to always use the native traceback regardless of how it was run. Is it possible to use a TestCase API to do so?
Thanks a lot for your help.
You can add this option to the pytest.ini file and it would be automatically picked by pytest. For your specific case, a pytest.ini with following contents should work:
[pytest]
addopts = --tb=native
Note the double hyphens with tb; I am using pytest 4.6.4 and that is how it works for me.
Also, Refer pytest docs for another alternative by modifying PYTEST_ADDOPTS env variable.
I'm not sure how you can do this using pytest, nor am I familiar with this package. With that being said, you can always create a bash function to accomplish this:
function pytest() {
pytest -tb=native "$#"
}
The "$#" symbol will pass all arguments following pyt to the function (kind of like *args in python), so running pyt arg1 arg2 ... argn will be the same as running
pytest -tb=native arg1 arg2 ... argn
If you are unfamiliar with creating bash shortcuts, see this question.
Update
I misunderstood and thought OP was calling pytest from the cli. Instead of creating the pyt function, if you override pytest directly, PyCharm might invoke your bash version of it instead (I'm not really sure though).
That being said, yaniv's answer seems superior to this, if it works.

Get pytest traceback for non-test modules

The traceback provided by pytest is great and super useful for debugging.
Is there a way to run a script using the pytest api even if the script itself does not contain any test modules? Essentially, I would like a way to pinpoint and run a certain function in a script as if it were a test, but get the pytest-formatted traceback.
The pytest documentation on test discovery states that normally only functions whose name begins with test_ are run. This behaviour can be changed however with the python_functions configuration option. Try entering in the command line:
pytest [script.py] -o python_functions=[script_function]
in which you should replace [script.py] with your python script file path and replace [script_function] with the name of the function that you want to be run.

Make each run of python interpreter automatically call `coverage`?

I have test.sh that runs python command on many different scripts. Is there a way to emit coverage -a for each python call without prepending each command with coverage -a?
See the coverage.py docs about subprocess measurement for a way to invoke coverage automatically when starting Python: http://coverage.readthedocs.io/en/latest/subprocess.html . It will require some fiddling.
It might be easier to alias in the shell script. For things like "nosetests", change it to "python -m nose".

executing python unittest with ipdb

Typically I run my python unit test with:
python -m unittest test.<module-name>
I would like to debug my tests using ipdb but I cannot figure out how to invoke theunittest module in manner similar to the command above.
The directory structure is:
base/src for the source code
base/test for the test code
Tests run from the base directory.
The preference is to 'run' & 'debug' test cases in the same manner, specifically the preference is to debug with ipdb in a similar manner to the python command above.
FYI
Interpreter is python2
I don't know how to do this with the unittest module from the standardlib, but the testrunner pytest has at least pdb (not ipdb) support. Just invoke it with
pytest --pdb
and it drops into pdb with the first failure.

Setuptools, explicitely separate multiple commands calls in one line

I would like to write an alias in my setup.py file to multiple tests commands for my project.
But, I have problems when I try to run multiple commands on one line, when 'nosetests' command is invoked before other commands.
This works
$ python setup.py lint nosetests
pylint output
nosetests output
But if I exchange the commands, I only gets nosetests output.
I think the lint command is eaten by the nosetests argument parser.
$ python setup.py nosetests lint
nosetests output
# No pylint output
So, I would like to know if there is a way to explicitly separate the commands ?
Thanks
New answer
By the looks of it, setuptools assumes all options begin with -- and all commands don't begin with --, so there's no explicit way to separate commands, because it's unnecessary.
If the custom nosetests command is accepting lint as an option, then it's a bug in that command, which ought to ignore anything which doesn't begin with --.
However, it might be possible to work around the bug with the traditional Unix idiom of using -- to indicate the end of options, so the following might work...
$ python setup.py nosetests -- lint
...otherwise you'll either have to fix the bug, or find an alternative to using that particular custom command.
Old answer
From the docs...
The basic usage of setup.py is:
$ python setup.py <some_command> <options>
...so it sounds like the fact that it executed both commands on your first example is a bug, or a fluke.
It's probably safest to run them as two separate commands...
$ python setup.py nosetests && python setup.py lint
nosetests output
pylint output

Categories

Resources