With the code
import unittest
import logging
class LoggingTest(unittest.TestCase):
def test_that_logs(self):
logging.warning("Hello")
logging.info("World")
for a in xrange(100000000000000000):
pass
I get this unexpected output:
$ nosetests --version
nosetests version 1.3.7
$ nosetests log_from_nosetest.py --nocapture --nologcapture
WARNING:root:Hello
^C
----------------------------------------------------------------------
Ran 1 test in 105.376s
OK
As can be seen. The WARNING log level message is printed, but not the INFO level one.
I've tried using the --logging-level setting but without success.
It seems a missing feature. If --nologcapture is set, nose simply ignores all logging setup, e.g. --logging-level is not used at all. You can remedy that with a
logging.basicConfig(level=logging.INFO)
in your code - not sure if that's what you want, because this kind of setup shouldn't be in library-code at all. It would be fine within the test-setup though.
This is because the default log level is warning. Set it with
logging.getLogger('').setLevel(logging.INFO)
Related
I run pylint -E as part of the tests on my Python project to ensure that errors don't creep into untested code. Generally this works quite well. But recently I've been running into problems with voluptuous and pylint.
The problem is that pylint thinks that the values returned by voluptuous Schemas are lists, which is simply not the case. Here's a toy program:
import voluptuous
MyType = voluptuous.Schema({
'q': str
})
def foo(bar):
bar = MyType(bar)
q = bar.get('q')
print q
foo({'q': '1324'})
It runs just fine:
$ python toy.py
1234
pylint, however, flags the .get() call:
$ pylint -E toy.py
No config file found, using default configuration
************* Module toy
E: 11, 8: Instance of 'list' has no 'get' member (no-member)
How can I get this program to pass pylint -E?
One option is to ignore the voluptuous module entirely, e.g.
$ pylint -E --ignored-modules=voluptuous toy.py
(passes)
If would be nice if pylint understood voluptuous better, though.
I am having some trouble trying to debug some unit tests through the pudb debugger.
The tests run fine with python, but I had no luck runnign them with pudb.
I isolated the problem, getting to the following sample code:
class Math:
def pow(self, x, y):
return x ** y
import unittest
class MathTest(unittest.TestCase):
def testPow23(self):
self.assertEquals(8, Math().pow(2, 3))
def testPow24(self):
self.assertEquals(16, Math().pow(2, 4))
if __name__ == '__main__':
unittest.main()
The tests run fine:
$ python amodule.py
.
----------------------------------------------------------------------
Ran 2 tests in 0.001s
OK
But if running through pudb, it gives me the output:
----------------------------------------------------------------------
Ran 0 tests in 0.000s
OK
I've tried running using pudb amodule.py and also with python -m pudb.run amodule.py, but it makes no difference -- no tests are run in one or another way.
Should I be doing something different to debug unit tests using pudb?
Try placing a breakpoint on a useful line in your code:
from pudb import set_trace; set_trace()
The ways you tried to launch it might interfere with test discovery and/or not run your script with a __name__ of '__main__'.
Since this is a popular question, I feel I should also mention that most test running tools will require you to pass in a switch to prevent it from capturing the standard output and input (usually it's -s).
So, remember to run pytest -s when using Pytest, or nosetests -s for Nose, python manage.py test -s for Django tests, or check the documentation for your test running tool.
You can set a breakpoint even easier by:
import pudb; pu.db
I'm using pytest for my test suite. While catching bugs in complex inter-components test, I would like to place import ipdb; ipdb.set_trace() in the middle of my code to allow me to debug it.
However, since pytest traps sys.stdin/sys.stdout ipdb fails. How can I use ipdb while testing with pytest.
I'm not interested in jumping to pdb or ipdb after a failure, but to place breaks anywhere in the code and be able to debug it there before the failure occurs.
The error is raised because pytest captures output by default.
You can run pytest with -s option (turn off capture output). For example:
py.test -s my_test.py
and then in my_test.py:
import ipdb;
ipdb.set_trace()
pytest-ipdb is unfortunately not supported anymore.
The solution is to run
pytest my_test.py --pdb --pdbcls=IPython.terminal.debugger:Pdb
From the help command:
pytest -h
--pdb start the interactive Python debugger on errors.
--pdbcls=modulename:classname
start a custom interactive Python debugger on errors.
For example:
--pdbcls=IPython.terminal.debugger:TerminalPdb
The difference is just that TerminalPdb seems to throw erros, but Pdb not (Ipython docs).
As of 2019-11 here is what should fix it:
pip install ipdb gnureadline ptpython
export PYTEST_ADDOPTS='--pdb --pdbcls=IPython.terminal.debugger:Pdb'
This is what I use
py.test tests/ --pdbcls=IPython.core.debugger:Pdb -s
You may want to give pdbpp a try. I've had more success with it, compared to ipdb when used with pytest. See my answer here: https://stackoverflow.com/a/69320311/2896799.
I'm trying to suppress all sqlalchemy warnings while running my test suite with nosetests. I read Turn off a warning in sqlalchemy
.............................../Users/ca/.pythonbrew/venvs/Python-2.7.3/api/lib/python2.7/site-packages/SQLAlchemy-0.7.5-py2.7-macosx-10.7-x86_64.egg/sqlalchemy/engine/default.py:330: Warning: Field 'random_id' doesn't have a default value
cursor.execute(statement, parameters)
I included this in my package's __init__.py file:
def setup_package():
"""Setup the test during the whole session.
Run by nosetests
"""
# Suppress all SQLAlchemy warnings
warnings.filterwarnings("ignore", category=sa_exc.SAWarning)
With the proper imports. I know it is run by nosetests because I tried some other stuff which raised error. The only thing is that it has no effect whatsoever. Warnings are still displayed.
Any idea?
Thanks!
It seems that nose overwrites whatever you set with:
warnings.filterwarnings("ignore")
However you can filter warnings during nose test with a command line option to nose. e.g.:
$ nosetests --logging-filter=SAWarning
I found that this still may not work under all circumstances. If this is the case you can try:
$ python -W ignore `which nosetests`
I know this is possible, I'm a newbie on Python. Looked at nose. But nose is not what we require. There should be some way to customize when I run python unittest.py --help on my own. Can any python people throw some light on this on how or where we can change. I'm using python 2.6.6
Alright, you're looking at customizing unittest.TestProgram. You'll want to create something like myunittest.py and in that module you'll do something like:
# myunittest.py
from unittest import TestProgram
class MyTestProgram(TestProgram):
USAGE = """\
Usage: %(progName)s [options] [test] [...]
Options:
-h, --help Show this message
-v, --verbose Verbose output
-q, --quiet Minimal output
Examples:
%(progName)s - run default set of tests
%(progName)s MyTestSuite - run suite 'MyTestSuite'
%(progName)s MyTestCase.testSomething - run MyTestCase.testSomething
%(progName)s MyTestCase - run all 'test*' test methods
in MyTestCase
"""
# additional changes here...
main = MyTestProgram
if __name__ == "__main__":
main(module=None)
Just changing USAGE may be all you really care about as that's the text printed by python unittest.py --help but you could obviously customize more.
Note this is specific to Python2.6. Python 2.7+ uses unittest2 which I'm not really familiar with at this point.