Why I like `nose`

December 23, 2010 at 04:15 PM | Python | View Comments

Four reasons nose rocks:

Test discovery

After I've written my test_*.py files, I just run nosetests:

$ ls
foo.py bar.py test_foo.py test_bar.py
$ nosetests
........
--------
Ran 9 tests in 0.03s

Nose is more Pythonic

The xUnit-esque frameworks fit well in languages like Java where methods can be called without the this prefix, but they don't work so well in Python which forces the explicit self. xUnit-esque frameworks also assume that tests will always exist inside a class and camelCase is pretty. Compare:

from unittest import TestCase
class UnittestTestCase(TestCase):
    def testStuff(self):
        self.assertEqual(foo, bar)

from nose.tools import assert_equal
def test_stuff():
    assert_equal(foo, bar)
class NoseTestCase(object):
    def test_stuff(self):
        assert_equal(foo, bar)

Test generators

The name basically says it all:

$ cat test_add.py
add_tests = [ (1, 2, 3), (1, 3, 4), (0, 0, 0) ]
def test_add():
    def test_add_helper(a, b, expected):
        assert_equal(a + b, expected)
    for test in add_tests:
        yield (test_add_helper, test)
$ nosetests
...
------
Ran 3 tests in 0.03s

Logging/stdout capturing

Nose automatically captures all text sent to stdout during tests, discarding it if the test passes or printing it if the test fails. For example: $ cat test_stuff.py from nose.tools import assert_equals

def passing_test():
    print "everything is happy!"
    assert_equals(1+2, 3)

def failing_test():
    print "oh no..."
    assert_equals(1+2, 0)
$ nosetests
.F
======================================================================
FAIL: test_stuff.failing_test
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Library/Python/2.6/site-packages/nose/case.py", line 186, in runTest
    self.test(*self.arg)
  File "/private/tmp/test_stuff.py", line 9, in failing_test
    assert_equals(1+2, 0)
AssertionError: 3 != 0
-------------------- >> begin captured stdout << ---------------------
oh no...

--------------------- >> end captured stdout << ----------------------

----------------------------------------------------------------------
Ran 2 tests in 0.001s

FAILED (failures=1)

NOTE: Michael Foord has been doing some crazy stuff with unittest2, so it's possible that it may be as awesome as nose.