test objects with loops

I want to use for loops in the objects project.


preview

I have these tests by the end of the chapter

objects/tests/test_objects.py
 1import unittest
 2
 3
 4class WPass: pass
 5
 6
 7class WParentheses(): pass
 8
 9
10class WObject(object): pass
objects/tests/test_objects.py
13class TestObjects(unittest.TestCase):
14
15    def test_what_is_an_object(self):
16        for an_object in (
17            WPass, WParentheses, WObject,
18            bool, int, float, str,
19            tuple, list, set, dict
20        ):
21            with self.subTest(an_object):
22                assert isinstance(an_object(), object)
23                self.assertIsInstance(an_object(), object)
24                assert issubclass(an_object, object)
25                self.assertIsSubclass(an_object, object)
objects/tests/test_objects.py
27    def test_is_none_an_object(self):
28        assert isinstance(None, object)
29        self.assertIsInstance(None, object)
30
31        # fails because None is not a class
32        # assert issubclass(None, object)
33        # self.assertIsSubclass(None, object)
objects/tests/test_objects.py
35    def test_dir_object(self):
36        reality = dir(object)
37        my_expectation = [
38            '__class__', '__delattr__', '__dir__',
39            '__doc__', '__eq__', '__format__',
40            '__ge__', '__getattribute__',
41            '__getstate__', '__gt__', '__hash__',
42            '__init__', '__init_subclass__', '__le__',
43            '__lt__', '__ne__', '__new__', '__reduce__',
44            '__reduce_ex__', '__repr__', '__setattr__',
45            '__sizeof__', '__str__', '__subclasshook__'
46        ]
47        assert reality == my_expectation
48        self.assertEqual(reality, my_expectation)
49
50
51# Exceptions seen
52# AssertionError
53# NameError
54# TypeError
55# AttributeError

open the project

  • I open a terminal

  • I change directory to the project

    terminal
    cd objects
    
  • I open test_objects.py from the tests folder

  • I use pytest-watcher to run the tests automatically

    terminal
    uv run pytest-watcher . --now
    

test_what_is_an_object

The tests other than test_is_none_an_object and test_dir_object assert that an object is an instance and a subclass of object

assert isinstance(an_object(), object)
self.assertIsInstance(an_object(), object)

assert isinstance(an_object, object)
self.assertIsInstance(an_object, object)

assert issubclass(an_object, object)
self.assertIsSubclass(an_object, object)

I can use a for loop in one test to remove the repetition.


RED: make it fail


I add a test with instance and subclass tests

objects/tests/test_objects.py
13class TestObjects(unittest.TestCase):
14
15    def test_what_is_an_object(self):
16        for an_object in (
17            WPass, WParentheses, WObject,
18            bool, int, float, str,
19            tuple, list, set, dict
20        ):
21            with self.subTest(an_object):
22                assert not isinstance(an_object(), object)
23                self.assertNotIsInstance(an_object(), object)
24                assert not issubclass(an_object, object)
25                self.assertNotIsSubclass(an_object, object)
26
27    def test_making_an_object_w_pass(self):

the terminal is my friend, and shows AssertionError

terminal
SUBFAILED[<class 'tests.test_objects.WPass'>] ...
    AssertionError: assert not True
SUBFAILED[<class 'tests.test_objects.WParentheses'>] ...
    AssertionError: assert not True
SUBFAILED[<class 'tests.test_objects.WObject'>] ...
    AssertionError: assert not True
SUBFAILED[<class 'bool'>] ...AssertionError: assert not True
SUBFAILED[<class 'int'>] ...AssertionError: assert not True
SUBFAILED[<class 'float'>] ...AssertionError: assert not True
SUBFAILED[<class 'str'>] ...AssertionError: assert not True
SUBFAILED[<class 'tuple'>] ...AssertionError: assert not True
SUBFAILED[<class 'list'>] ...AssertionError: assert not True
SUBFAILED[<class 'set'>] ...AssertionError: assert not True
SUBFAILED[<class 'dict'>] ...AssertionError: assert not True

GREEN: make it pass


  • I change assert not isinstance(an_object(), object)

    objects/tests/test_objects.py
    21            with self.subTest(an_object):
    22                assert isinstance(an_object(), object)
    23                self.assertNotIsInstance(an_object(), object)
    

    the terminal is my friend, and shows AssertionError

    terminal
    SUBFAILED[<class 'tests.test_objects.WPass'>] ...
        AssertionError: <tests.test_objects.WPass object at 0xffffa0bcd123>
                        is an instance of <class 'object'>
    SUBFAILED[<class 'tests.test_objects.WParentheses'>] ...
        AssertionError: <tests.test_objects.WParentheses object at 0xffffe4fab456>
                        is an instance of <class 'object'>
    SUBFAILED[<class 'tests.test_objects.WObject'>] ...
        AssertionError: <tests.test_objects.WObject object at 0xffffc7def801>
                        is an instance of <class 'object'>
    SUBFAILED[<class 'bool'>] ...
        AssertionError: False is an instance of <class 'object'>
    SUBFAILED[<class 'int'>] ...
        AssertionError: 0 is an instance of <class 'object'>
    SUBFAILED[<class 'float'>] ...
        AssertionError: 0.0 is an instance of <class 'object'>
    SUBFAILED[<class 'str'>] ...
        AssertionError: '' is an instance of <class 'object'>
    SUBFAILED[<class 'tuple'>] ...
        AssertionError: () is an instance of <class 'object'>
    SUBFAILED[<class 'list'>] ...
        AssertionError: [] is an instance of <class 'object'>
    SUBFAILED[<class 'set'>] ...
        AssertionError: set() is an instance of <class 'object'>
    SUBFAILED[<class 'dict'>] ...
        AssertionError: {} is an instance of <class 'object'>
    
  • I change self.assertNotIsInstance(an_object(), object)

    objects/tests/test_objects.py
    21            with self.subTest(an_object):
    22                assert isinstance(an_object(), object)
    23                self.assertIsInstance(an_object(), object)
    24                assert not issubclass(an_object, object)
    

    the terminal shows AssertionError

  • I change assert not issubclass(an_object, object)

    objects/tests/test_objects.py
    21            with self.subTest(an_object):
    22                assert isinstance(an_object(), object)
    23                self.assertIsInstance(an_object(), object)
    24                assert issubclass(an_object, object)
    25                self.assertNotIsSubclass(an_object, object)
    

    the terminal is my friend, and shows AssertionError

    terminal
    SUBFAILED[<class 'tests.test_objects.WPass'>] ...
        AssertionError: <class 'tests.test_objects.WPass'>
                        is a subclass of <class 'object'>
    SUBFAILED[<class 'tests.test_objects.WParentheses'>] ...
        AssertionError: <class 'tests.test_objects.WParentheses'>
                        is a subclass of <class 'object'>
    SUBFAILED[<class 'tests.test_objects.WObject'>] ...
        AssertionError: <class 'tests.test_objects.WObject'>
                        is a subclass of <class 'object'>
    SUBFAILED[<class 'bool'>] ...
        AssertionError: <class 'bool'> is a subclass of <class 'object'>
    SUBFAILED[<class 'int'>] ...
        AssertionError: <class 'int'> is a subclass of <class 'object'>
    SUBFAILED[<class 'float'>] ...
        AssertionError: <class 'float'> is a subclass of <class 'object'>
    SUBFAILED[<class 'str'>] ...
        AssertionError: <class 'str'> is a subclass of <class 'object'>
    SUBFAILED[<class 'tuple'>] ...
        AssertionError: <class 'tuple'> is a subclass of <class 'object'>
    SUBFAILED[<class 'list'>] ...
        AssertionError: <class 'list'> is a subclass of <class 'object'>
    SUBFAILED[<class 'set'>] ...
        AssertionError: <class 'set'> is a subclass of <class 'object'>
    SUBFAILED[<class 'dict'>] ...
        AssertionError: <class 'dict'> is a subclass of <class 'object'>
    
  • I change self.assertNotIsSubclass(an_object, object)

    objects/tests/test_objects.py
    21            with self.subTest(an_object):
    22                assert isinstance(an_object(), object)
    23                self.assertIsInstance(an_object(), object)
    24                assert issubclass(an_object, object)
    25                self.assertIsSubclass(an_object, object)
    26
    27    def test_making_an_object_w_pass(self):
    

    the test passes.


REFACTOR: make it better


  • I remove the other isinstance and issubclass tests. I keep test_is_none_an_object and test_dir_object

    objects/tests/test_objects.py
    21            with self.subTest(an_object):
    22                assert isinstance(an_object(), object)
    23                self.assertIsInstance(an_object(), object)
    24                assert issubclass(an_object, object)
    25                self.assertIsSubclass(an_object, object)
    26
    27    def test_is_none_an_object(self):
    28        assert isinstance(None, object)
    29        self.assertIsInstance(None, object)
    30
    31        # fails because None is not a class
    32        # assert issubclass(None, object)
    33        # self.assertIsSubclass(None, object)
    34
    35    def test_dir_object(self):
    
  • I add a git commit message

    terminal
    git commit -am \
    'extract test_what_is_an_object'
    

review

I used a for loop to remove repetition from the tests.


close the project

  • I close test_objects.py

  • I click in the terminal where the tests are running

  • I use q on the keyboard to leave the tests

  • I change directory to the parent of objects

    terminal
    cd ..
    

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 telephone 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.