test AssertionError with generators


I want to use a generator in the assertion_error project.


preview

I have these tests by the end of the chapter

assertion_error/tests/test_assertion_error.py
1import itertools
2import unittest
3
4
5def assert_not_equal(x, y):
6    assert x != y
7
8
9def assert_equal(x, y):
assertion_error/tests/test_assertion_error.py
12
13class TestAssertionError(unittest.TestCase):
14
15    basic_objects = (
16        None, False, True,
17        0, 0.0, '', (), [], set(), {},
assertion_error/tests/test_assertion_error.py
19
20    def test_assertion_error(self):
21        # for first, second in (
22        #     (first, second) for first in self.basic_objects
23        #                     for second in self.basic_objects
24        # ):
25        for first, second in itertools.product(
26            self.basic_objects, repeat=2
27        ):
28            with self.subTest(pair=(first, second)):
29                try:
30                    assert first is second
31                except AssertionError:
32                    assert first is not second
33
34                try:
35                    self.assertIsNot(first, second)
36                except AssertionError:
assertion_error/tests/test_assertion_error.py
38
39                try:
40                    self.assertEqual(first, second)
41                except AssertionError:
42                    self.assertNotEqual(first, second)
43
44    def test_assert_keyword(self):
45        for reality, my_expectation in (
46            (1 + 1, 2),
assertion_error/tests/test_assertion_error.py
48            ('I am' + ' alive', 'I am alive')
49        ):
50            with self.subTest((reality, my_expectation)):
51                assert_equal(reality, my_expectation)
52                self.assertEqual(reality, my_expectation)
53
54    def test_assertion_error_w_none(self):
assertion_error/tests/test_assertion_error.py
56            with self.subTest(object=an_object):
57                try:
58                    self.assertIsNotNone(an_object)
59                except AssertionError:
60                    self.assertIsNone(an_object)
61
62    def will_not_run():
63        # will not run because
64        # the name does not start with test
65        assert False == True
66        self.assertEqual(False, True)
67

open the project


test_assertion_error with a generator

RED: make it fail


I add a generator expression for the for loops in test_assertion_error

assertion_error/tests/test_assertion_error.py
38    def test_assertion_error(self):
39        # for first in self.basic_objects:
40        #     for second in self.basic_objects:
41        for first, second in (
42            (first, second)
43            for first in self.basic_objects
44            for second in self.basic_objects
45        ):
46                with self.subTest(pair=(first, second)):
47                    raise Exception
48                    try:
49                        assert first is second
50                    except AssertionError:
51                        assert first is not second

the terminal shows AssertionError for one hundred sub tests.

terminal SUBFAILED[(2, 2)] …test_assert_keyword - AssertionError: assert 2 == ‘BOOM!!!’

SUBFAILED[(‘11’, ‘11’)] …test_assert_keyword -

AssertionError: assert ‘11’ == ‘BOOM!!!’

SUBFAILED[(‘I am alive’, ‘I am alive’)] …test_assert_keyword -

AssertionError: assert ‘I am alive’ == ‘BOOM!!!’


GREEN: make it pass


  • I change the expectation of assert_equal(reality, 'BOOM!!!')

    assertion_error/tests/test_assertion_error.py
    44            with self.subTest((reality, my_expectation)):
    45                assert_equal(reality, my_expectation)
    46                self.assertEqual(reality, 'BAP!!!')
    47
    48        reality = 1 + 1
    

    the terminal is my friend, and shows AssertionError

    terminal
    SUBFAILED[(2, 2)] ...test_assert_keyword -
        AssertionError: 2 != 'BAP!!!'
    SUBFAILED[('11', '11')] ...test_assert_keyword -
        AssertionError: '11' != 'BAP!!!'
    SUBFAILED[('I am alive', 'I am alive')] ...test_assert_keyword -
        AssertionError: 'I am alive' != 'BAP!!!'
    
  • I change the expectation of self.assertEqual(reality, 'BAP!!!')

    assertion_error/tests/test_assertion_error.py
    44            with self.subTest((reality, my_expectation)):
    45                assert_equal(reality, my_expectation)
    46                self.assertEqual(reality, my_expectation)
    47
    48        reality = 1 + 1
    

    the test passes.


REFACTOR: make it better


  • I remove the other statements from test_assert_keyword because they are now covered by the for loop

    assertion_error/tests/test_assertion_error.py
    38    def test_assert_keyword(self):
    39        for reality, my_expectation in (
    40            (1 + 1, 2),
    41            ('1' + '1', '11'),
    42            ('I am' + ' alive', 'I am alive')
    43        ):
    44            with self.subTest((reality, my_expectation)):
    45                assert_equal(reality, my_expectation)
    46                self.assertEqual(reality, my_expectation)
    47
    48    def test_assertion_error_w_none(self):
    
  • I open a new terminal then make sure I am in the assertion_error folder

    terminal
    cd assertion_error
    
  • I add a git commit message in the new terminal

    terminal
    git commit -am 'test_assert_keyword with a for loop'
    

test_assertion_error_w_none with for loop

RED: make it fail


I add a for loop to test_assertion_error_w_none

48    def test_assertion_error_w_none(self):
49        assert None is None
50        self.assertIs(None, None)
51        self.assertIsNone(None)
52
53        for an_object in (
54            False, True, self.an_integer,
55            self.a_float, self.a_string,
56            self.a_tuple, self.a_list,
57            self.a_set, self.a_dictionary,
58        ):
59            with self.subTest(object=an_object):
60                assert_is_not_none(None)
61                self.assertIsNot(an_object, object)
62                self.assertIsNotNone(None)
63
64        assert_is_not_none(False)

the terminal is my friend, and shows AssertionError

terminal AssertionError: assert None is not None


GREEN: make it pass


  • I change None to an_object in assert_is_not_none(None)

    assertion_error/tests/test_assertion_error.py
    59            with self.subTest(object=an_object):
    60                assert_is_not_none(an_object)
    61                self.assertIsNot(an_object, an_object)
    62                self.assertIsNotNone(None)
    

    the terminal is my friend, and shows AssertionError

    
    
    caption:

    terminal SUBFAILED(object=False) ::test_assertion_error_w_none - AssertionError: unexpectedly identical: False

    SUBFAILED(object=True) ::test_assertion_error_w_none -

    AssertionError: unexpectedly identical: True

    SUBFAILED(object=0) ::test_assertion_error_w_none -

    AssertionError: unexpectedly identical: 0

    SUBFAILED(object=0.0) ::test_assertion_error_w_none -

    AssertionError: unexpectedly identical: 0.0

    SUBFAILED(object=’’) ::test_assertion_error_w_none -

    AssertionError: unexpectedly identical: ‘’

    SUBFAILED(object=()) ::test_assertion_error_w_none -

    AssertionError: unexpectedly identical: ()

    SUBFAILED(object=[]) ::test_assertion_error_w_none -

    AssertionError: unexpectedly identical: []

    SUBFAILED(object=set()) ::test_assertion_error_w_none -

    AssertionError: unexpectedly identical: set()

    SUBFAILED(object={}) ::test_assertion_error_w_none -

    AssertionError: unexpectedly identical: {}

  • I change the second an_object to None in self.assertIsNot(an_object, an_object)

    assertion_error/tests/test_assertion_error.py
    59            with self.subTest(object=an_object):
    60                assert_is_not_none(an_object)
    61                self.assertIsNot(an_object, None)
    62                self.assertIsNotNone(None)
    

    the terminal is my friend, and shows AssertionError

    
    
    caption:

    terminal AssertionError: unexpectedly None

  • I change None to an_object

    assertion_error/tests/test_assertion_error.py
    59            with self.subTest(object=an_object):
    60                assert_is_not_none(an_object)
    61                self.assertIsNot(an_object, None)
    62                self.assertIsNotNone(an_object)
    63
    64        assert_is_not_none(False)
    

    the test passes.


REFACTOR: make it better


  • I remove the other statements from test_assertion_error_w_none because they are now covered by the for loop

    assertion_error/tests/test_assertion_error.py
    48    def test_assertion_error_w_none(self):
    49        assert None is None
    50        self.assertIs(None, None)
    51        self.assertIsNone(None)
    52
    53        for an_object in (
    54            False, True, self.an_integer,
    55            self.a_float, self.a_string,
    56            self.a_tuple, self.a_list,
    57            self.a_set, self.a_dictionary,
    58        ):
    59            with self.subTest(object=an_object):
    60                assert_is_not_none(an_object)
    61                self.assertIsNot(an_object, None)
    62                self.assertIsNotNone(an_object)
    63
    64    def test_assertion_error_w_false(self):
    
  • I add a git commit message

    terminal
    git commit -am \
    'test_assertion_error_w_none with a for loop'
    

test_assertion_error_w_false with a for loop

RED: make it fail


I add a for loop to test_assertion_error_w_false

64      def test_assertion_error_w_false(self):
65          assert False is False
66          self.assertIs(False, False)
67
68          for an_object in (
69              None, True, self.an_integer,
70              self.a_float, self.a_string,
71              self.a_tuple, self.a_list,
72              self.a_set, self.a_dictionary,
73          ):
74              with self.subTest(object=an_object):
75                  assert_is_not_false(False)
76                  self.assertIsNot(an_object, True)
77
78          assert_is_not_false(None)

the terminal is my friend, and shows AssertionError

terminal AssertionError: assert False is not False


GREEN: make it pass


  • I change False to an_object in assert_is_not_false(False)

    assertion_error/tests/test_assertion_error.py
    74            with self.subTest(object=an_object):
    75                assert_is_not_false(an_object)
    76                self.assertIsNot(an_object, True)
    77
    78        assert_is_not_false(None)
    

    the terminal is my friend, and shows AssertionError

    
    
    caption:

    terminal SUBFAILED(object=True) test_assertion_error_w_false - AssertionError: unexpectedly identical: True

  • I change True to False in self.assertIsNot(an_object, True)

    assertion_error/tests/test_assertion_error.py
    74        with self.subTest(object=an_object):
    75            assert_is_not_false(an_object)
    76            self.assertIsNot(an_object, False)
    77
    78    assert_is_not_false(None)
    

    the test passes.


REFACTOR: make it better


  • I remove the other statements from test_assertion_error_w_false because they are now covered by the for loop

    assertion_error/tests/test_assertion_error.py
    64    def test_assertion_error_w_false(self):
    65        assert False is False
    66        self.assertIs(False, False)
    67
    68        for an_object in (
    69            None, True, self.an_integer,
    70            self.a_float, self.a_string,
    71            self.a_tuple, self.a_list,
    72            self.a_set, self.a_dictionary,
    73        ):
    74            with self.subTest(object=an_object):
    75                assert_is_not_false(an_object)
    76                self.assertIsNot(an_object, False)
    77
    78    def test_assertion_error_w_true(self):
    
  • I add a git commit message

    terminal
    git commit -am \
    'test_assertion_error_w_false with a for loop'
    

test_assertion_error_w_true with a for loop

RED: make it fail


I add a for loop to test_assertion_error_w_true

78    def test_assertion_error_w_true(self):
79        assert True is True
80        self.assertIs(True, True)
81
82        for an_object in (
83            None, False, self.an_integer,
84            self.a_float, self.a_string,
85            self.a_tuple, self.a_list,
86            self.a_set, self.a_dictionary,
87        ):
88            with self.subTest(object=an_object):
89                assert_is_not_true(True)
90                self.assertIsNot(an_object, False)
91
92        assert_is_not_true(None)

the terminal is my friend, and shows AssertionError


caption:

terminal AssertionError: assert True is not True


GREEN: make it pass


  • I change True to an_object in assert_is_not_true(True)

    assertion_error/tests/test_assertion_error.py
    88            with self.subTest(object=an_object):
    89                assert_is_not_true(an_object)
    90                self.assertIsNot(an_object, False)
    91
    92        assert_is_not_true(None)
    

    the terminal is my friend, and shows AssertionError

    
    
    caption:

    terminal SUBFAILED(object=False) …test_assertion_error_w_true - AssertionError: unexpectedly identical: False

  • I change False to True in self.assertIsNot(an_object, False)

    assertion_error/tests/test_assertion_error.py
    88        with self.subTest(object=an_object):
    89            assert_is_not_true(an_object)
    90            self.assertIsNot(an_object, True)
    91
    92    assert_is_not_true(None)
    

    the test passes.


REFACTOR: make it better


  • I remove the other statements from test_assertion_error_w_true because they are now covered by the for loop

    assertion_error/tests/test_assertion_error.py
    78    def test_assertion_error_w_true(self):
    79        assert True is True
    80        self.assertIs(True, True)
    81
    82        for an_object in (
    83            None, False, self.an_integer,
    84            self.a_float, self.a_string,
    85            self.a_tuple, self.a_list,
    86            self.a_set, self.a_dictionary,
    87        ):
    88            with self.subTest(object=an_object):
    89                assert_is_not_true(an_object)
    90                self.assertIsNot(an_object, True)
    91
    92    def test_assertion_error_w_equality(self):
    
  • I add a git commit message

    terminal
    git commit -am \
    'test_assertion_error_w_true w a for loop'
    

extract basic_objects object attribute

test_assertion_error_w_true, test_assertion_error_w_false and test_assertion_error_w_none all use a tuple with self.an_integer, self.a_float, self.a_string, self.a_tuple, self.a_list, self.a_set and self.a_dictionary.

I can use an object attribute with a single starred expression to remove the repetition.


RED: make it fail


  • I add an object attribute to the TestAssertionError object

    assertion_error/tests/test_assertion_error.py
    28class TestAssertionError(unittest.TestCase):
    29
    30    an_integer = 0
    31    a_float = 0.0
    32    a_string = ''
    33    a_tuple = ()
    34    a_list = []
    35    a_set = set()
    36    a_dictionary = {}
    37    basic_objects = (
    38        an_integer, a_float, a_string,
    39        a_tuple, a_list, a_set,
    40        a_dictionary,
    41    )
    42
    43    def test_assert_keyword(self):
    
  • I use the new object attribute with a single starred expression in test_assertion_error_w_none

    assertion_error/tests/test_assertion_error.py
    53    def test_assertion_error_w_none(self):
    54        assert None is None
    55        self.assertIs(None, None)
    56        self.assertIsNone(None)
    57
    58        for an_object in (
    59            False, True, *self.basic_objects
    60        ):
    61            with self.subTest(object=an_object):
    62                assert_is_not_none(an_object)
    63                self.assertIsNot(an_object, None)
    64                self.assertIsNotNone(an_object)
    65
    66    def test_assertion_error_w_false(self):
    

    the test is still green.

  • I change an_object to None in assert_is_not_none(an_object) to make sure the test still works as expected

    assertion_error/tests/test_assertion_error.py
    61            with self.subTest(object=an_object):
    62                assert_is_not_none(None)
    63                self.assertIsNot(an_object, None)
    64                self.assertIsNotNone(an_object)
    

    the terminal is my friend, and shows AssertionError

    
    
    caption:

    terminal SUBFAILED(object=False) test_assertion_error_w_none - AssertionError: assert None is not None

    SUBFAILED(object=True) test_assertion_error_w_none -

    AssertionError: assert None is not None

    SUBFAILED(object=0) test_assertion_error_w_none -

    AssertionError: assert None is not None

    SUBFAILED(object=0.0) test_assertion_error_w_none -

    AssertionError: assert None is not None

    SUBFAILED(object=’’) test_assertion_error_w_none -

    AssertionError: assert None is not None

    SUBFAILED(object=()) test_assertion_error_w_none -

    AssertionError: assert None is not None

    SUBFAILED(object=[]) test_assertion_error_w_none -

    AssertionError: assert None is not None

    SUBFAILED(object=set()) test_assertion_error_w_none -

    AssertionError: assert None is not None

    SUBFAILED(object={}) test_assertion_error_w_none -

    AssertionError: assert None is not None

    it works.


GREEN: make it pass


I undo the change

            with self.subTest(object=an_object):
                assert_is_not_none(an_object)
                self.assertIsNot(an_object, None)
                self.assertIsNotNone(an_object)

    def test_assertion_error_w_false(self):

the test is green again.


REFACTOR: make it better


  • I use the new object attribute with a single starred expression in test_assertion_error_w_false

    assertion_error/tests/test_assertion_error.py
    66    def test_assertion_error_w_false(self):
    67        assert False is False
    68        self.assertIs(False, False)
    69
    70        for an_object in (
    71            None, True, *self.basic_objects,
    72        ):
    73            with self.subTest(object=an_object):
    74                assert_is_not_false(an_object)
    75                self.assertIsNot(an_object, False)
    76
    77    def test_assertion_error_w_true(self):
    

    the test is still green.

  • I use the new object attribute with a single starred expression in test_assertion_error_w_true

    assertion_error/tests/test_assertion_error.py
    77    def test_assertion_error_w_true(self):
    78        assert True is True
    79        self.assertIs(True, True)
    80
    81        for an_object in (
    82            None, False, *self.basic_objects,
    83        ):
    84            with self.subTest(object=an_object):
    85                assert_is_not_true(an_object)
    86                self.assertIsNot(an_object, True)
    87
    88    def test_assertion_error_w_equality(self):
    

    still green.

  • I remove the other object attributes because they are only used by the basic_objects object attribute

    assertion_error/tests/test_assertion_error.py
    28class TestAssertionError(unittest.TestCase):
    29
    30    basic_objects = (0, 0.0, '', (), [], set(), {},)
    31
    32    def test_assert_keyword(self):
    

    green.

  • I add a git commit message

    terminal
    git commit -am \
    'extract basic_objects object attribute'
    

test_assertion_error_w_equality with a for loop

RED: make it fail


  • I add two for loops to test_assertion_error_w_equality

    assertion_error/tests/test_assertion_error.py
    77    def test_assertion_error_w_equality(self):
    78        objects = (None, False, True)
    79        for first in objects:
    80            for second in objects:
    81                with self.subTest(pair=(first, second)):
    82                    self.assertEqual(first, second)
    83
    84        assert_equal(None, None)
    

    the terminal is my friend, and shows AssertionError

    
    
    caption:

    terminal SUBFAILED(pair=(None, False)) …test_assertion_error_w_equality - AssertionError: None != False

    SUBFAILED(pair=(None, True)) …test_assertion_error_w_equality -

    AssertionError: None != True

    SUBFAILED(pair=(False, None)) …test_assertion_error_w_equality -

    AssertionError: False != None

    SUBFAILED(pair=(False, True)) …test_assertion_error_w_equality -

    AssertionError: False != True

    SUBFAILED(pair=(True, None)) …test_assertion_error_w_equality -

    AssertionError: True != None

    SUBFAILED(pair=(True, False)) …test_assertion_error_w_equality -

    AssertionError: True != False


GREEN: make it pass


I move self.assertEqual(first, second) into a try statement to handle the cases where the pairings are not equal

77    def test_assertion_error_w_equality(self):
78        objects = (None, False, True)
79        for first in objects:
80            for second in objects:
81                with self.subTest(pair=(first, second)):
82                    try:
83                        self.assertEqual(first, second)
84                    except AssertionError:
85                        self.assertNotEqual(first, second)
86
87        assert_equal(None, None)

the test passes.


REFACTOR: make it better


  • I remove the other statements from test_assertion_error_w_equality because they are now covered by the for loops

    assertion_error/tests/test_assertion_error.py
    77    def test_assertion_error_w_equality(self):
    78        objects = (None, False, True)
    79        for first in objects:
    80            for second in objects:
    81                with self.subTest(pair=(first, second)):
    82                    try:
    83                        self.assertEqual(first, second)
    84                    except AssertionError:
    85                        self.assertNotEqual(first, second)
    86
    87    def test_assertion_error_w_is_vs_equal(self):
    
  • I add a git commit message

    terminal
    git commit -am \
    'test_assertion_error_w_equality with a for loop'
    

add to basic_objects object attribute

test_assertion_error_w_true, test_assertion_error_w_false and test_assertion_error_w_none look the same, the only difference is

terminal False, True, *self.basic_objects # test_assertion_error_w_none

None, True, *self.basic_objects # test_assertion_error_w_false None, False, *self.basic_objects # test_assertion_error_w_true

which looks like some of the pairs from test_assertion_error_w_equality

  SUBFAILED(pair=(None, False))
  SUBFAILED(pair=(None, True))
  SUBFAILED(pair=(False, None))
  SUBFAILED(pair=(False, True))
  SUBFAILED(pair=(True, None))
  SUBFAILED(pair=(True, False))

RED: make it fail


I add True to the tuple in test_assertion_error_w_true

66      def test_assertion_error_w_true(self):
67          assert True is True
68          self.assertIs(True, True)
69
70          for an_object in (
71              None, False, True, *self.basic_objects,
72          ):
73              with self.subTest(object=an_object):

the terminal is my friend, and shows AssertionError

terminal SUBFAILED(object=True) … AssertionError: assert True is not True


GREEN: make it pass


  • I move assert_is_not_true(an_object) into a try statement for the case where an_object is the same object as True

    assertion_error/tests/test_assertion_error.py
    73            with self.subTest(object=an_object):
    74                try:
    75                    assert_is_not_true(an_object)
    76                except AssertionError:
    77                    assert an_object is True
    78
    79                self.assertIsNot(an_object, True)
    

    the terminal is my friend, and shows AssertionError

    
    
    caption:

    terminal AssertionError: unexpectedly identical: True

  • I move self.assertIsNot(an_object, True) into a try statement for the case where an_object is the same object as True

    assertion_error/tests/test_assertion_error.py
    73            with self.subTest(object=an_object):
    74                try:
    75                    assert_is_not_true(an_object)
    76                except AssertionError:
    77                    assert an_object is True
    78
    79                try:
    80                    self.assertIsNot(an_object, True)
    81                except AssertionError:
    82                    self.assertIs(an_object, True)
    83
    84    def test_assertion_error_w_equality(self):
    

    the test passes.


REFACTOR: make it better


  • I remove the first assertions from test_assertion_error_w_true because they are now covered by the for loop and try statements

    assertion_error/tests/test_assertion_error.py
    66    def test_assertion_error_w_true(self):
    67        for an_object in (
    68            None, False, True, *self.basic_objects,
    69        ):
    70            with self.subTest(object=an_object):
    71                try:
    72                    assert_is_not_true(an_object)
    73                except AssertionError:
    74                    assert an_object is True
    75
    76                try:
    77                    self.assertIsNot(an_object, True)
    78                except AssertionError:
    79                    self.assertIs(an_object, True)
    80
    81    def test_assertion_error_w_equality(self):
    
  • I add False to the tuple in test_assertion_error_w_false

    assertion_error/tests/test_assertion_error.py
    55    def test_assertion_error_w_false(self):
    56        assert False is False
    57        self.assertIs(False, False)
    58
    59        for an_object in (
    60            None, False, True, *self.basic_objects,
    61        ):
    62            with self.subTest(object=an_object):
    

    the terminal is my friend, and shows AssertionError

    
    
    caption:

    terminal SUBFAILED(object=False) … AssertionError: assert False is not False

  • I move assert_is_not_false(an_object) into a try statement for the case where an_object is the same object as False

    assertion_error/tests/test_assertion_error.py
    62            with self.subTest(object=an_object):
    63                try:
    64                    assert_is_not_false(an_object)
    65                except AssertionError:
    66                    assert an_object is False
    67
    68                self.assertIsNot(an_object, False)
    

    the terminal is my friend, and shows AssertionError

    
    
    caption:

    terminal AssertionError: unexpectedly identical: False

  • I move self.assertIsNot(an_object, False) into a try statement for the case where an_object is the same object as False

    assertion_error/tests/test_assertion_error.py
    62            with self.subTest(object=an_object):
    63                try:
    64                    assert_is_not_false(an_object)
    65                except AssertionError:
    66                    assert an_object is False
    67
    68                try:
    69                    self.assertIsNot(an_object, False)
    70                except AssertionError:
    71                    self.assertIs(an_object, False)
    72
    73    def test_assertion_error_w_true(self):
    

    the test passes.

  • I remove the first assertions from test_assertion_error_w_false because they are now covered by the for loop and try statements

    assertion_error/tests/test_assertion_error.py
    55    def test_assertion_error_w_false(self):
    56        for an_object in (
    57            None, False, True, *self.basic_objects,
    58        ):
    59            with self.subTest(object=an_object):
    60                try:
    61                    assert_is_not_false(an_object)
    62                except AssertionError:
    63                    assert an_object is False
    64
    65                try:
    66                    self.assertIsNot(an_object, False)
    67                except AssertionError:
    68                    self.assertIs(an_object, False)
    69
    70    def test_assertion_error_w_true(self):
    
  • I add None to the tuple in test_assertion_error_w_none

    assertion_error/tests/test_assertion_error.py
    42    def test_assertion_error_w_none(self):
    43        assert None is None
    44        self.assertIs(None, None)
    45        self.assertIsNone(None)
    46
    47        for an_object in (
    48            None, False, True, *self.basic_objects
    49        ):
    50            with self.subTest(object=an_object):
    

    the terminal is my friend, and shows AssertionError

    
    
    caption:

    terminal SUBFAILED(object=None) … AssertionError: assert None is not None

  • I move assert_is_not_none(an_object) into a try statement for the case where an_object is the same object as None

    assertion_error/tests/test_assertion_error.py
    50            with self.subTest(object=an_object):
    51                try:
    52                    assert_is_not_none(an_object)
    53                except AssertionError:
    54                    assert an_object is None
    55
    56                self.assertIsNot(an_object, None)
    57                self.assertIsNotNone(an_object)
    

    the terminal is my friend, and shows AssertionError

    
    
    caption:

    terminal SUBFAILED(object=None)… AssertionError: unexpectedly identical: None

  • I move self.assertIsNot(an_object, None) into a try statement for the case where an_object is the same object as None

    assertion_error/tests/test_assertion_error.py
    50            with self.subTest(object=an_object):
    51                try:
    52                    assert_is_not_none(an_object)
    53                except AssertionError:
    54                    assert an_object is None
    55
    56                try:
    57                    self.assertIsNot(an_object, None)
    58                except AssertionError:
    59                    self.assertIs(an_object, None)
    60
    61                self.assertIsNotNone(an_object)
    

    the terminal is my friend, and shows AssertionError

    
    
    caption:

    terminal SUBFAILED(object=None) … AssertionError: unexpectedly None

  • I move self.assertIsNotNone(an_object) into a try statement for the case where an_object is the same object as None

    assertion_error/tests/test_assertion_error.py
    56                try:
    57                    self.assertIsNot(an_object, None)
    58                except AssertionError:
    59                    self.assertIs(an_object, None)
    60
    61                try:
    62                    self.assertIsNotNone(an_object)
    63                except AssertionError:
    64                    self.assertIsNone(an_object)
    65
    66    def test_assertion_error_w_false(self):
    

    the test passes.

  • I remove the first assertions from test_assertion_error_w_none because they are now covered by the for loop and try statements

    assertion_error/tests/test_assertion_error.py
    42    def test_assertion_error_w_none(self):
    43        for an_object in (
    44            None, False, True, *self.basic_objects
    45        ):
    46            with self.subTest(object=an_object):
    47                try:
    48                    assert_is_not_none(an_object)
    49                except AssertionError:
    50                    assert an_object is None
    51
    52                try:
    53                    self.assertIsNot(an_object, None)
    54                except AssertionError:
    55                    self.assertIs(an_object, None)
    56
    57                try:
    58                    self.assertIsNotNone(an_object)
    59                except AssertionError:
    60                    self.assertIsNone(an_object)
    61
    62    def test_assertion_error_w_false(self):
    
  • I add None, False and True to the basic_objects object attribute

    assertion_error/tests/test_assertion_error.py
    28class TestAssertionError(unittest.TestCase):
    29
    30    basic_objects = (
    31        None, False, True,
    32        0, 0.0, '', (), [], set(), {},
    33    )
    34
    35    def test_assert_keyword(self):
    

    the tests are still green.

  • I remove None, False and True from test_assertion_error_w_none because they are now part of the basic_objects object attribute

    assertion_error/tests/test_assertion_error.py
    45    def test_assertion_error_w_none(self):
    46        for an_object in self.basic_objects:
    47            with self.subTest(object=an_object):
    

    still green.

  • I make the same change to test_assertion_error_w_false

    assertion_error/tests/test_assertion_error.py
    63    def test_assertion_error_w_false(self):
    64        for an_object in self.basic_objects:
    65            with self.subTest(object=an_object):
    

    green.

  • I do the same thing to test_assertion_error_w_true

    assertion_error/tests/test_assertion_error.py
    76    def test_assertion_error_w_true(self):
    77        for an_object in self.basic_objects:
    78            with self.subTest(object=an_object):
    

    still green.

  • I do the same thing to test_assertion_error_w_equality

    assertion_error/tests/test_assertion_error.py
    89    def test_assertion_error_w_equality(self):
    90        for first in self.basic_objects:
    91            for second in self.basic_objects:
    92                with self.subTest(pair=(first, second)):
    

    the tests are still green.

  • I add a git commit message

    terminal
    git commit -am \
    'add to basic_objects object attribute'
    

extract test_assertion_error

test_assertion_error_w_none, test_assertion_error_w_false and test_assertion_error_w_true still look similar, they all have this assertion

terminal try: self.assertIsNot(an_object, something)

except AssertionError:

self.assertIs(an_object, something)

I can make a function with a for loop to remove the repetition.


RED: make it fail


I add a function with two for loops like I did in test_assertion_error_w_equality

28class TestAssertionError(unittest.TestCase):
29
30    basic_objects = (
31        None, False, True,
32        0, 0.0, '', (), [], set(), {},
33    )
34
35    def test_assertion_error(self):
36        for first in self.basic_objects:
37            for second in self.basic_objects:
38                with self.subTest(pair=(first, second)):
39                    self.assertIsNot(first, second)
40
41    def test_assert_keyword(self):

the terminal is my friend, and shows AssertionError

terminal SUBFAILED(pair=(None, None)) …test_assertion_error - AssertionError: unexpectedly identical: None

SUBFAILED(pair=(False, False)) …test_assertion_error -

AssertionError: unexpectedly identical: False

SUBFAILED(pair=(True, True)) …test_assertion_error -

AssertionError: unexpectedly identical: True

SUBFAILED(pair=(0, 0)) …test_assertion_error -

AssertionError: unexpectedly identical: 0

SUBFAILED(pair=(0.0, 0.0)) …test_assertion_error -

AssertionError: unexpectedly identical: 0.0

SUBFAILED(pair=(‘’, ‘’)) …test_assertion_error -

AssertionError: unexpectedly identical: ‘’

SUBFAILED(pair=((), ())) …test_assertion_error -

AssertionError: unexpectedly identical: ()

SUBFAILED(pair=([], [])) …test_assertion_error -

AssertionError: unexpectedly identical: []

SUBFAILED(pair=(set(), set())) …test_assertion_error -

AssertionError: unexpectedly identical: set()

SUBFAILED(pair=({}, {})) …test_assertion_error -

AssertionError: unexpectedly identical: {}


GREEN: make it pass


I move self.assertIsNot(first, second) into a try statement for the cases where the first item is the same object as the second one

35                with self.subTest(pair=(first, second)):
36                    try:
37                        self.assertIsNot(first, second)
38                    except AssertionError:
39                        self.assertIs(first, second)
40
41    def test_assert_keyword(self):

the test passes.


REFACTOR: make it better


  • I remove the try statement for the calls to the assertIsNot and assertIs methods in test_assertion_error_w_none since it is now covered by test_assertion_error

    assertion_error/tests/test_assertion_error.py
    54    def test_assertion_error_w_none(self):
    55        for an_object in self.basic_objects:
    56            with self.subTest(object=an_object):
    57                try:
    58                    assert_is_not_none(an_object)
    59                except AssertionError:
    60                    assert an_object is None
    61
    62                try:
    63                    self.assertIsNotNone(an_object)
    64                except AssertionError:
    65                    self.assertIsNone(an_object)
    66
    67    def test_assertion_error_w_false(self):
    
  • I remove the try statement for the calls to the assertIsNot and assertIs methods in test_assertion_error_w_false since it is now covered by test_assertion_error

    assertion_error/tests/test_assertion_error.py
    67    def test_assertion_error_w_false(self):
    68        for an_object in self.basic_objects:
    69            with self.subTest(object=an_object):
    70                try:
    71                    assert_is_not_false(an_object)
    72                except AssertionError:
    73                    assert an_object is False
    74
    75    def test_assertion_error_w_true(self):
    
  • I remove the try statement for the calls to the assertIsNot and assertIs methods in test_assertion_error_w_true since it is now covered by test_assertion_error

    assertion_error/tests/test_assertion_error.py
    75    def test_assertion_error_w_true(self):
    76        for an_object in self.basic_objects:
    77            with self.subTest(object=an_object):
    78                try:
    79                    assert_is_not_true(an_object)
    80                except AssertionError:
    81                    assert an_object is True
    82
    83    def test_assertion_error_w_equality(self):
    
  • I add an assertion for equality to test_assertion_error

    assertion_error/tests/test_assertion_error.py
    35    def test_assertion_error(self):
    36        for first in self.basic_objects:
    37            for second in self.basic_objects:
    38                with self.subTest(pair=(first, second)):
    39                    try:
    40                        self.assertIsNot(first, second)
    41                    except AssertionError:
    42                        self.assertIs(first, second)
    43
    44                    self.assertEqual(first, second)
    45
    46    def test_assert_keyword(self):
    

    the terminal is my friend, and shows AssertionError for eighty four sub tests

    
    
    caption:

    terminal ============ 84 failed, 8 passed in A.BCs ==============

    yikes!

  • I move self.assertEqual(first, second) into a try statement for the cases where the first item is equal to the second one

    assertion_error/tests/test_assertion_error.py
    38                with self.subTest(pair=(first, second)):
    39                    try:
    40                        self.assertIsNot(first, second)
    41                    except AssertionError:
    42                        self.assertIs(first, second)
    43
    44                    try:
    45                        self.assertEqual(first, second)
    46                    except AssertionError:
    47                        self.assertNotEqual(first, second)
    48
    49    def test_assert_keyword(self):
    

    the test passes.

  • I remove test_assertion_error_w_equality because it is now covered by test_assertion_error

  • I remove test_assertion_error_w_is_vs_equal because it is now covered by test_assertion_error

    assertion_error/tests/test_assertion_error.py
    80    def test_assertion_error_w_true(self):
    81        for an_object in self.basic_objects:
    82            with self.subTest(object=an_object):
    83                try:
    84                    assert_is_not_true(an_object)
    85                except AssertionError:
    86                    assert an_object is True
    87
    88    def will_not_run():
    

test_assertion_error_w_true, test_assertion_error_w_false and test_assertion_error_w_none use helper functions which hides their similarities

terminal assert_is_not_true(an_object) -> assert_is_not(x, True)

assert_is_not_false(an_object) -> assert_is_not(x, False) assert_is_not_none(an_object) -> assert_is_not(x, None)

assert_is_not(x, y) -> assert x is not y

  • I change the call to assert_is_not_true back to the assert statement in the assert_is_not function, in test_assertion_error_w_true

    assertion_error/tests/test_assertion_error.py
    80    def test_assertion_error_w_true(self):
    81        for an_object in self.basic_objects:
    82            with self.subTest(object=an_object):
    83                try:
    84                    assert an_object is not True
    85                except AssertionError:
    86                    assert an_object is True
    87
    88    def will_not_run():
    

    the test is still green.

  • I change the call to assert_is_not_false back to the assert statement in the assert_is_not function, in test_assertion_error_w_false

    assertion_error/tests/test_assertion_error.py
    72    def test_assertion_error_w_false(self):
    73        for an_object in self.basic_objects:
    74            with self.subTest(object=an_object):
    75                try:
    76                    assert an_object is not False
    77                except AssertionError:
    78                    assert an_object is False
    79
    80    def test_assertion_error_w_true(self):
    

    still green.

  • I change the call to assert_is_not_none back to the assert statement in the assert_is_not function, in test_assertion_error_w_none

    assertion_error/tests/test_assertion_error.py
    59    def test_assertion_error_w_none(self):
    60        for an_object in self.basic_objects:
    61            with self.subTest(object=an_object):
    62                try:
    63                    assert an_object is not None
    64                except AssertionError:
    65                    assert an_object is None
    

    green.

  • I add a simple assert statement for when the first object for the cases where the first item is the same object as the second one

    assertion_error/tests/test_assertion_error.py
    35    def test_assertion_error(self):
    36        for first in self.basic_objects:
    37            for second in self.basic_objects:
    38                with self.subTest(pair=(first, second)):
    39                    assert first is second
    40
    41                    try:
    42                        self.assertIsNot(first, second)
    43                    except AssertionError:
    44                        self.assertIs(first, second)
    

    the terminal is my friend, and shows AssertionError for ninety sub tests

    
    
    caption:

    terminal ============ 90 failed, 6 passed in A.BCs ==============

    I do not think I would have written one hundred individual tests for AssertionError

  • I move assert first is second into a try statement for the cases where the first item is NOT the same object as the second one

    assertion_error/tests/test_assertion_error.py
    35    def test_assertion_error(self):
    36        for first in self.basic_objects:
    37            for second in self.basic_objects:
    38                with self.subTest(pair=(first, second)):
    39                    try:
    40                        assert first is second
    41                    except AssertionError:
    42                        assert first is not second
    43
    44                    try:
    45                        self.assertIsNot(first, second)
    46                    except AssertionError:
    47                        self.assertIs(first, second)
    48
    49                    try:
    50                        self.assertEqual(first, second)
    51                    except AssertionError:
    52                        self.assertNotEqual(first, second)
    53
    54    def test_assert_keyword(self):
    

    the test passes.

  • I remove the try statement for the simple assert statements in test_assertion_error_w_none since it is now covered by test_assertion_error

    assertion_error/tests/test_assertion_error.py
    64    def test_assertion_error_w_none(self):
    65        for an_object in self.basic_objects:
    66            with self.subTest(object=an_object):
    67                try:
    68                    self.assertIsNotNone(an_object)
    69                except AssertionError:
    70                    self.assertIsNone(an_object)
    71
    72    def test_assertion_error_w_false(self):
    
  • I remove test_assertion_error_w_false because it is now covered by test_assertion_error

    assertion_error/tests/test_assertion_error.py
    64    def test_assertion_error_w_none(self):
    65        for an_object in self.basic_objects:
    66            with self.subTest(object=an_object):
    67                try:
    68                    self.assertIsNotNone(an_object)
    69                except AssertionError:
    70                    self.assertIsNone(an_object)
    71
    72    def will_not_run():
    
  • I remove the assert_is_not function because it is no longer used

  • I remove the assert_is_not_none, assert_is_not_false and assert_is_not_true functions because they are no longer used

    1import unittest
    2
    3
    4def assert_not_equal(x, y):
    5    assert x != y
    

    the tests are still green.

  • I add a git commit message

    terminal
    git commit -am \
    'extract test_assertion_error'
    

close the project

  • I close test_assertion_error.py

  • I click in the terminal where the tests are running

  • I use q on the keyboard to leave the tests. The terminal goes back to the command line.

  • I change directory to the parent of assertion_error

    terminal
    cd ..
    

review

I can use for loops, object attributes and functions to remove repetition. In this case I used them to make a test that has one hundred sub tests which would not have been fun to write one at a time, yet there is a problem. Can you tell just by looking at the code, that all test_assertion_error is doing is asserting that


code from the chapter

Do you want to see all the CODE I typed in this chapter?


what is next?

Would you like to test the ATM project with loops?


rate pumping python

If this has been a 7 star experience for you, please CLICK HERE to leave a 5 star review of pumping python. It helps other people get into the book too.