6.1. Testing Doctest vs Unittest

6.1.1. Code

>>> class User:
...     def __init__(self, firstname, lastname):
...         self.firstname = firstname
...         self.lastname = lastname
...         self._authenticated = False
...
...     def login(self, username, password):
...         self._authenticated = True
...
...     def logout(self):
...         self._authenticated = False
...
...     def edit_profile(self, firstname=None, lastname=None):
...         if firstname is not None:
...             self.firstname = firstname
...         if lastname is not None:
...             self.lastname = lastname
...
...     def get_profile(self):
...         return {'firstname': self.firstname, 'lastname': self.lastname}

6.1.2. Doctest

  • Primary focus on documentation

  • Shows how to use the code (your API)

>>> """
... >>> user = User('Mark', 'Watney')
... >>> user.login(username='mwatney', password='Ares3')
...
... Edit profile allows to change user's first and last name.
... You can do this by calling edit_profile method twice:
...
... >>> user.edit_profile(firstname='Melissa')
... >>> user.edit_profile(lastname='Lewis')
... >>> user.get_profile()
... {'firstname': 'Melissa', 'lastname': 'Lewis'}
...
... Or you can do this in one call:
...
... >>> user.edit_profile(firstname='Rick', lastname='Martinez')
... >>> user.get_profile()
... {'firstname': 'Rick', 'lastname': 'Martinez'}
...
... At the end, you can logout:
...
... >>> user.logout()
... """

6.1.3. Unittest

  • Testing each possible action

  • Unit does not refer to the size of the test (single class)

  • Unit refers to the smallest testable part of the application (feature)

  • Split tests into separate classes by feature (test cases)

>>> from unittest import TestCase
>>>
>>>
>>> class TestUserInit(TestCase):
...     def test_user_init(self):
...         user = User('Mark', 'Watney')
...         self.assertEqual(user.firstname, 'Mark')
...         self.assertEqual(user.lastname, 'Watney')
>>>
>>>
>>> class TestUserAuth(TestCase):
...     def setUp(self):
...         self.user = User('Mark', 'Watney')
...
...     def test_login(self):
...         self.user.login(username='mwatney', password='Ares3')
...         self.assertEqual(self.user._authenticated, True)
...
...     def test_logout(self):
...         self.user.logout()
...         self.assertEqual(self.user._authenticated, False)
>>>
>>>
>>> class TestUserPofile(TestCase):
...     def setUp(self):
...         self.user = User('Mark', 'Watney')
...
...     def test_edit_profile_firstname(self):
...         self.user.edit_profile(firstname='Melissa')
...         self.assertEqual(self.user.firstname, 'Melissa')
...
...     def test_edit_profile_lastname(self):
...         self.user.edit_profile(lastname='Lewis')
...         self.assertEqual(self.user.lastname, 'Lewis')
...
...     def test_edit_profile_firstname_lastname(self):
...         self.user.edit_profile(firstname='Rick', lastname='Martinez')
...         self.assertEqual(self.user.firstname, 'Rick')
...         self.assertEqual(self.user.lastname, 'Martinez')
...
...     def test_profile_get(self):
...         self.assertDictEqual(self.user.get_profile(), {'firstname': 'Mark', 'lastname': 'Watney'})