Unit tests#

[1]:
def add(a, b):
    return a + b
[2]:
import unittest

class TestNotebook(unittest.TestCase):

    def test_add(self):
        self.assertEqual(add(2, 2), 5)


unittest.main(argv=[''], verbosity=2, exit=False)
test_add (__main__.TestNotebook) ... FAIL

======================================================================
FAIL: test_add (__main__.TestNotebook)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "<ipython-input-2-26d0f87b13a5>", line 6, in test_add
    self.assertEqual(add(2, 2), 5)
AssertionError: 4 != 5

----------------------------------------------------------------------
Ran 1 test in 0.004s

FAILED (failures=1)
[2]:
<unittest.main.TestProgram at 0x105b909b0>

Alternatively, ipython-unittest can also be used. This enables the following Cell Magics to be used in iPython:

  • %%unittest_main executes test cases that are defined in a cell

  • %%unittest_testcase creates a test case with the function defined in a cell and executes it

  • %%unittestconverts Python assert to unit test functions

  • %%external to perform external unit tests

  • %%write {mode} to write external files

[3]:
%reload_ext ipython_unittest
[4]:
%%unittest_main
class MyTest(unittest.TestCase):
    def test_1_plus_1_equals_2(self):
        sum = 1 + 1
        self.assertEqual(sum, 2)

    def test_2_plus_2_equals_4(self):
        self.assertEqual(2 + 2, 4)
Success
..
----------------------------------------------------------------------
Ran 2 tests in 0.002s

OK
[4]:
<unittest.runner.TextTestResult run=2 errors=0 failures=0>
[5]:
%%unittest_testcase
def test_1_plus_1_equals_2(self):
    sum = 1 + 1
    self.assertEqual(sum, 2)

def test_2_plus_2_equals_4(self):
    self.assertEqual(2 + 2, 4)
Success
..
----------------------------------------------------------------------
Ran 2 tests in 0.000s

OK
[5]:
<unittest.runner.TextTestResult run=2 errors=0 failures=0>
[6]:
%%unittest
"1 plus 1 equals 2"
sum = 1 + 1
assert sum == 2
"2 plus 2 equals 4"
assert 2 + 2 == 4
Success
..
----------------------------------------------------------------------
Ran 2 tests in 0.000s

OK
[6]:
<unittest.runner.TextTestResult run=2 errors=0 failures=0>

By default, Docstring separates the unit test methods in this magic. However, if docstrings are not used, the Cell Magics create one for each assert method.

These Cell Magics support optional arguments:

  • -p (--previous) P

    puts the cursor in front of P cells (default -1 corresponds to the next cell)

    However, this only works if jupyter_dojo is also installed.

  • -s (--stream) S

    sets the ooutput stream (default is: sys.stdout)

  • -t (--testcase) T

    defines the name of the TestCase for %%unittest and %%unittest_testcase

  • -u (--unparse)

    outputs the source code after the transformations

Debugging#

[7]:
import doctest


doctest.testmod()

def multiply(a, b):
    '''
    This is a test:
    >>> multiply(2, 2)
    5
    '''
    import pdb; pdb.set_trace()
    return a * b
  1. import pdb imports the Python debugger

  2. pdb.set_trace() creates a breakpoint that starts the Python debugger.