=Description=

http://code.google.com/p/unittestplus/

Test utilities built on unittest.

Includes an augmented TestCase class with improved (stricter and more
informative) assert methods; test autodiscovery; utility functions for running
tests and combining TestCase classes into suites and  prettier verbose test
output. For convenience, also includes a copy of
[http://www.voidspace.org.uk/python/mock/ Michael Foord's Mock module].

The intention is for this to be a reusable, drop-in 'testutils' package for
most or all of my own personal Python projects.

As a bonus, running verbose tests with TestCasePlus also looks prettier (shown
below.)


=Status=

Complete & working, but not yet in use.


=Plans=

  * Remove our copy of Mock from this package - 'require' it instead?
  * run() should auto-combine all testcases in the module it was called from, like unittest.main()
  * TestCasePlus.assertEquals should output diffs on fail for long strings
  * Pretty much all of this package is obsoleted by the latest changes to unittest, if you can use a version of Python that includes them.


=To Install=

To get the current stable published version, either use:

    `easy_install unittestplus`

or download a zip from [http://pypi.python.org/pypi/unittestplus/ PyPI]

Alternatively, for the very latest unstable version from the Subversion
repository, see the instructions on
[http://code.google.com/p/unittestplus/source/checkout the source tab].


=To Use=

==TestCasePlus==

Use as you would unittest.TestCase, with the following changes:


====New methods====

  * `assertNone(value, message='')`
  * `assertNotNone(value, message='')`
  * `assertTrue(value, message='')` # fails unless value is boolean and True
  * `assertFalse(value, message='')` # fails unless value is boolean and False


====assertEquals====

    `assertEquals(actual, expected, message='', epsilon=0)`

assertEquals now actually shows you the two compared values if it fails.
Also, I've added an 'epsilon' keyword parameter, which supplants the use of
'assertAlmostEquals'. If it is absent, all comparisons are exact. If it is
specified, then assertEquals will only fail if the different between two
floats is greater or equal to epsilon. If iterables are compared, the given
epsilon is used to compare each of their elements. This is not recursively
applied to nested iterables.

As in unittest, assertEqual is a synonym for assertEquals. None of the
'failXXX' aliases are supported by TestCasePlus.


====assertRaises====

    `assertRaises(callable, expectedException, expected_message='')`

Note that this is a reversal of the argument order in unittest. I wanted
assertRaises to follow a (to me) more consistent and memorable 'actual,
expected' ordering of its arguments. Uses of the traditional ordering are
detected and warned about.

This also allows you to specify the message that the expected exception should
contain, which can't be done in unittest.


==run==

Use 'run' as you would unittest.main(). It can be passed a TestCase (or
TestCasePlus) class, or an instance of TestSuite.

{{{
from unittestplus.run import run
from unittestplus.testcaseplus import TestCasePlus

class MyTest(TestCasePlus):
    pass # etc...

if __name__ == "__main__":
    run(MyTest)
}}}

The 'run' function also accepts 'verbosity' (int) and 'descriptions' (bool)
keyword args, which it passes on to unittest.TextTestRunner. Pass verbosity=2 and descriptions=1 to see the prettier output described below.


==combine==

Combine can be given any number of TestCase clases or TestSuites, and will
combine them all into a single TestSuite.

{{{
from unittestplus.run import combine, run
from unittestplus.testcaseplus import TestCasePlus

class FirstTest(TestCasePlus):
    pass

class SecondTest(TestCasePlus):
    pass

AllTests = combine(FirstTest, SecondTest)

if __name__ == '__main__':
    run(AllTests)
}}}

==get_all_tests==

Your top-level 'run_all_tests.py' script can easily auto-discover all tests
in a package and all its sub-packages, using:

{{{
#!/usr/bin/env python

from unittestplus.run import get_all_tests, run
run(get_all_tests('unittestplus'))
}}}


==Prettier Output==

Running verbose tests with TestCasePlus outputs:
{{{
testcaseplus_test.ModuleFunctionsTest.test_is_int_indexable ... ok
run_test.CombineTest.test_combine_raises_on_nontests ... ok
run_test.CombineTest.test_combine_suites ... ok
run_test.RunFuncTest.test_run_creates_testrunner ... ok
}}}

As opposed to the unittest.TestCase output:
{{{
test_is_int_indexable (unittestplus.tests.testcaseplus_test.ModuleFunctionsTest)
 ... ok
test_combine_raises_on_nontests (unittestplus.tests.run_test.CombineTest) ... ok

test_combine_suites (unittestplus.tests.run_test.CombineTest) ... ok
test_run_creates_testrunner (unittestplus.tests.run_test.RunFuncTest) ... ok
}}}


