I'm writing a test suit with nose, and would like failing cases to display an output like
"FAILED: is_even(5): Not even"
instead of the default output:
======================================================================
FAIL: seed_db.test_generator(5,)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/usr/local/lib/python2.7/dist-packages/nose/case.py", line 197, in runTest
self.test(*self.arg)
File "/home/apurcell/tests/prism/seed_db.py", line 59, in is_even
nose.tools.eq_(x % 2, 0, msg="Not even")
File "/usr/local/lib/python2.7/dist-packages/nose/tools.py", line 31, in eq_
assert a == b, msg or "%r != %r" % (a, b)
AssertionError: Not even
----------------------------------------------------------------------
Is there an option for nose than can do this?
If you want to change nose behavior, you should write a plug-in (see API documentation here). In your case, it sounds like you want to change the way that errors are reported, so you'd want to provide formatError()
and formatFailure()
. Probably you'd want to edit the exception message (to include the line number), and limit the size of the traceback.
One possible solution is to redirect the error stream into a stream like object and handle the different output there. This could look like the following code snippet:
import sys
class MyErrorStream():
def write(self, txt):
# Do something if
# output contains
# special exception
altered_txt = 'My special exception is:\n' + txt
sys.__stderr__.write(altered_txt)
if(__name__ == '__main__'):
error_stream = MyErrorStream()
sys.stderr = error_stream
assert(1 == 0)
But this solution is not the nicest one. Another way to alter the stack trace is to modify the internal class of nose which handles the output. You could subclass it and overwrite/extend the methods which create the output text. Because I'm not using nose I can't give a minimal code snippet.
Nevertheless I hope I could help you.
The following has output similar to but not identical to what you want (and it also changes the successful test output, which may not be what you want). It uses tap.py to output TAP (test anything protocol) instead of the usual unittest output.
nosetests --with-tap --tap-stream testcases-rsysflow.py
The output looks like:
bjb@rhino$ nosetests testcases-rrrr.py --with-tap --tap-stream
# TAP results for TestThing
ok 1 - test_create_and_get (testcases-rrrr.TestThing)
ok 2 - test_del_one (testcases-rrrr.TestThing)
ok 3 - test_get_all (testcases-rrrr.TestThing)
not ok 4 - test_get_not_exist (testcases-rrrr.TestThing)
ok 5 - test_get_wrong_indir (testcases-rrrr.TestThing)
ok 6 - test_replace_and_get (testcases-rrrr.TestThing)
ok 7 - test_set_should_fail (testcases-rrrr.TestThing)
1..7
With Test Anything Protocol (I'm speaking of the protocol, not this specific implementation) you can output diagnostic info after the dash on error - but I don't know how to do that with this implementation.
This implementation was handy because I just had to install tap.py (pip install tap.py
) and put those two command-line args on the nosetest invocation of my unittest tests, and poof - TAP formatted output. Can plug this in to Jenkins now.