functions 3: use class attributes

In AssertionError 2: use class attributes I used class attributes to remove repetition from the assertion_error project. The classes chapter teaches the setUp method to ensure each test method starts with fresh values. In some cases the values I need are the same for every test. In this case, I do not need the setUp method because the class attributes are the same for every test and I do not need anything to run before each test. I want to do the same thing in the functions project.


preview

I have these tests by the end of the chapter


continue the project

  • I change directory to the functions folder

    cd functions
    

    the terminal shows I am in the functions folder

    .../pumping_python/functions
    
  • I use pytest-watcher to run the tests

    uv run pytest-watcher . --now
    

    the terminal is my friend, and shows

    rootdir: .../pumping_python/functions
    configfile: pyproject.toml
    collected 12 items
    
    tests/test_functions.py ............                  [100%]
    
    =================== 12 passed in X.YZs =====================
    
  • I hold ctrl on the keyboard, then click on tests/test_functions.py to open it


  • I add class attributes

    10class TestFunctions(unittest.TestCase):
    11
    12    first = 'first'
    13    last = 'last'
    14
    15    def test_why_use_a_function(self):
    
  • I use the class attributes to remove repetition of 'first' and 'last' from test_positional_arguments

    136    def test_positional_arguments(self):
    137        # first, last = 'first', 'last'
    138
    139        reality = src.functions.positional_arguments(
    140            # first, last,
    141            self.first, self.last,
    142        )
    143        # my_expectation = (first, last)
    144        my_expectation = (self.first, self.last)
    145        self.assertEqual(reality, my_expectation)
    146
    147        reality = src.functions.positional_arguments(
    148            # last, first,
    149            self.last, self.first,
    150        )
    151        # my_expectation = (last, first)
    152        my_expectation = (self.last, self.first)
    153        self.assertEqual(reality, my_expectation)
    

    the test is still green.

  • I use the class attributes to remove repetition of 'first' and 'last' from test_keyword_arguments

    170    def test_keyword_arguments(self):
    171        # first, last = 'first', 'last'
    172
    173        reality = src.functions.w_keyword_arguments(
    174            # first_input=first, last_input=last,
    175            first_input=self.first,
    176            last_input=self.last,
    177        )
    178        # my_expectation = (first, last)
    179        my_expectation = (self.first, self.last)
    180        self.assertEqual(reality, my_expectation)
    181
    182        reality = src.functions.w_keyword_arguments(
    183            # last_input=last, first_input=first,
    184            last_input=self.last,
    185            first_input=self.first,
    186        )
    187        # my_expectation = (first, last)
    188        my_expectation = (self.first, self.last)
    189        self.assertEqual(reality, my_expectation)
    190
    191        reality = src.functions.w_keyword_arguments(
    192            # last, first,
    193            self.last, self.first,
    194        )
    195        # my_expectation = (last, first)
    196        my_expectation = (self.last, self.first)
    197        self.assertEqual(reality, my_expectation)
    

    still green.

  • I use the class attributes to remove 'first' and 'last' from test_args_and_kwargs

    224    def test_args_and_kwargs(self):
    225        # first, last = 'first', 'last'
    226        reality = (
    227            src.functions.args_and_kwargs(
    228                # first, last_input=last,
    229                self.first, last_input=self.last,
    230            )
    231        )
    232        # my_expectation = (first, last)
    233        my_expectation = (self.first, self.last)
    234        self.assertEqual(reality, my_expectation)
    235
    236    def test_optional_arguments(self):
    

    green.

  • I remove the commented lines from test_args_and_kwargs

    224    def test_args_and_kwargs(self):
    225        reality = (
    226            src.functions.args_and_kwargs(
    227                self.first, last_input=self.last,
    228            )
    229        )
    230        my_expectation = (self.first, self.last)
    231        self.assertEqual(reality, my_expectation)
    232
    233    def test_optional_arguments(self):
    

  • I add a class attribute

    10class TestFunctions(unittest.TestCase):
    11
    12    first = 'first'
    13    last = 'last'
    14    a_tuple = (0, 1, 2, 'n')
    15
    16    def test_why_use_a_function(self):
    
  • I use the new class attribute to remove repetition of (0, 1, 2, 'n') from test_positional_arguments

    137    def test_positional_arguments(self):
    138        # first, last = 'first', 'last'
    139
    140        reality = src.functions.positional_arguments(
    141            # first, last,
    142            self.first, self.last,
    143        )
    144        # my_expectation = (first, last)
    145        my_expectation = (self.first, self.last)
    146        self.assertEqual(reality, my_expectation)
    147
    148        reality = src.functions.positional_arguments(
    149            # last, first,
    150            self.last, self.first,
    151        )
    152        # my_expectation = (last, first)
    153        my_expectation = (self.last, self.first)
    154        self.assertEqual(reality, my_expectation)
    155
    156        first_number, second_number = 0, 1
    157        reality = src.functions.positional_arguments(
    158            first_number, second_number,
    159        )
    160        my_expectation = (first_number, second_number)
    161        self.assertEqual(reality, my_expectation)
    162
    163        # a_tuple = (0, 1, 2, 'n')
    164        a_list = [0, 1, 2, 'n']
    165        reality = src.functions.positional_arguments(
    166            # a_tuple, a_list,
    167            self.a_tuple, a_list,
    168        )
    169        # my_expectation = (a_tuple, a_list)
    170        my_expectation = (self.a_tuple, a_list)
    171        self.assertEqual(reality, my_expectation)
    172
    173    def test_keyword_arguments(self):
    

    still green.

  • I use the new class attribute to remove repetition of (0, 1, 2, 'n') from test_keyword_arguments

    173    def test_keyword_arguments(self):
    174        # first, last = 'first', 'last'
    175
    176        reality = src.functions.w_keyword_arguments(
    177            # first_input=first, last_input=last,
    178            first_input=self.first,
    179            last_input=self.last,
    180        )
    181        # my_expectation = (first, last)
    182        my_expectation = (self.first, self.last)
    183        self.assertEqual(reality, my_expectation)
    184
    185        reality = src.functions.w_keyword_arguments(
    186            # last_input=last, first_input=first,
    187            last_input=self.last,
    188            first_input=self.first,
    189        )
    190        # my_expectation = (first, last)
    191        my_expectation = (self.first, self.last)
    192        self.assertEqual(reality, my_expectation)
    193
    194        reality = src.functions.w_keyword_arguments(
    195            # last, first,
    196            self.last, self.first,
    197        )
    198        # my_expectation = (last, first)
    199        my_expectation = (self.last, self.first)
    200        self.assertEqual(reality, my_expectation)
    201
    202        zero, one = 0, 1
    203        reality = src.functions.w_keyword_arguments(
    204            last_input=zero, first_input=one,
    205        )
    206        my_expectation = (one, zero)
    207        self.assertEqual(reality, my_expectation)
    208
    209        a_set = {0, 1, 2, 'n'}
    210        a_dictionary = {'key': 'value'}
    211        reality = src.functions.w_keyword_arguments(
    212            first_input=a_set,
    213            last_input=a_dictionary,
    214        )
    215        my_expectation = (a_set, a_dictionary)
    216        self.assertEqual(reality, my_expectation)
    217
    218        # a_tuple = (0, 1, 2, 'n')
    219        a_list = [0, 1, 2, 'n']
    220        reality = src.functions.positional_arguments(
    221            first_input=a_list,
    222            # last_input=a_tuple,
    223            last_input=self.a_tuple,
    224        )
    225        # my_expectation = (a_list, a_tuple)
    226        my_expectation = (a_list, self.a_tuple)
    227        self.assertEqual(reality, my_expectation)
    228
    229    def test_args_and_kwargs(self):
    

    the test is still green.


  • I add a class attribute

    10class TestFunctions(unittest.TestCase):
    11
    12    first = 'first'
    13    last = 'last'
    14    a_tuple = (0, 1, 2, 'n')
    15    a_list = [0, 1, 2, 'n']
    16
    17    def test_why_use_a_function(self):
    
  • I use the new class attribute to remove repetition of [0, 1, 2, 'n'] from test_positional_arguments

    138    def test_positional_arguments(self):
    139        # first, last = 'first', 'last'
    140
    141        reality = src.functions.positional_arguments(
    142            # first, last,
    143            self.first, self.last,
    144        )
    145        # my_expectation = (first, last)
    146        my_expectation = (self.first, self.last)
    147        self.assertEqual(reality, my_expectation)
    148
    149        reality = src.functions.positional_arguments(
    150            # last, first,
    151            self.last, self.first,
    152        )
    153        # my_expectation = (last, first)
    154        my_expectation = (self.last, self.first)
    155        self.assertEqual(reality, my_expectation)
    156
    157        first_number, second_number = 0, 1
    158        reality = src.functions.positional_arguments(
    159            first_number, second_number,
    160        )
    161        my_expectation = (first_number, second_number)
    162        self.assertEqual(reality, my_expectation)
    163
    164        # a_tuple = (0, 1, 2, 'n')
    165        # a_list = [0, 1, 2, 'n']
    166        reality = src.functions.positional_arguments(
    167            # a_tuple, a_list,
    168            # self.a_tuple, a_list,
    169            self.a_tuple, self.a_list,
    170        )
    171        # my_expectation = (a_tuple, a_list)
    172        # my_expectation = (self.a_tuple, a_list)
    173        my_expectation = (self.a_tuple, self.a_list)
    174        self.assertEqual(reality, my_expectation)
    175
    176    def test_keyword_arguments(self):
    

    still green.

  • I use the new class attribute to remove repetition of [0, 1, 2, 'n'] from test_keyword_arguments

    176    def test_keyword_arguments(self):
    177        # first, last = 'first', 'last'
    178
    179        reality = src.functions.w_keyword_arguments(
    180            # first_input=first, last_input=last,
    181            first_input=self.first,
    182            last_input=self.last,
    183        )
    184        # my_expectation = (first, last)
    185        my_expectation = (self.first, self.last)
    186        self.assertEqual(reality, my_expectation)
    187
    188        reality = src.functions.w_keyword_arguments(
    189            # last_input=last, first_input=first,
    190            last_input=self.last,
    191            first_input=self.first,
    192        )
    193        # my_expectation = (first, last)
    194        my_expectation = (self.first, self.last)
    195        self.assertEqual(reality, my_expectation)
    196
    197        reality = src.functions.w_keyword_arguments(
    198            # last, first,
    199            self.last, self.first,
    200        )
    201        # my_expectation = (last, first)
    202        my_expectation = (self.last, self.first)
    203        self.assertEqual(reality, my_expectation)
    204
    205        zero, one = 0, 1
    206        reality = src.functions.w_keyword_arguments(
    207            last_input=zero, first_input=one,
    208        )
    209        my_expectation = (one, zero)
    210        self.assertEqual(reality, my_expectation)
    211
    212        a_set = {0, 1, 2, 'n'}
    213        a_dictionary = {'key': 'value'}
    214        reality = src.functions.w_keyword_arguments(
    215            first_input=a_set,
    216            last_input=a_dictionary,
    217        )
    218        my_expectation = (a_set, a_dictionary)
    219        self.assertEqual(reality, my_expectation)
    220
    221        # a_tuple = (0, 1, 2, 'n')
    222        # a_list = [0, 1, 2, 'n']
    223        reality = src.functions.positional_arguments(
    224            # first_input=a_list,
    225            # last_input=a_tuple,
    226            first_input=self.a_list,
    227            last_input=self.a_tuple,
    228        )
    229        # my_expectation = (a_list, a_tuple)
    230        # my_expectation = (a_list, self.a_tuple)
    231        my_expectation = (self.a_list, self.a_tuple)
    232        self.assertEqual(reality, my_expectation)
    233
    234    def test_args_and_kwargs(self):
    

    green.


  • I add class attribute

    10class TestFunctions(unittest.TestCase):
    11
    12    first = 'first'
    13    last = 'last'
    14    a_tuple = (0, 1, 2, 'n')
    15    a_list = [0, 1, 2, 'n']
    16    first_number = 0
    17    second_number = 1
    18
    19    def test_why_use_a_function(self):
    
  • I use the new class attributes to remove repetition of 0 and 1 from test_positional_arguments

    140    def test_positional_arguments(self):
    141        # first, last = 'first', 'last'
    142
    143        reality = src.functions.positional_arguments(
    144            # first, last,
    145            self.first, self.last,
    146        )
    147        # my_expectation = (first, last)
    148        my_expectation = (self.first, self.last)
    149        self.assertEqual(reality, my_expectation)
    150
    151        reality = src.functions.positional_arguments(
    152            # last, first,
    153            self.last, self.first,
    154        )
    155        # my_expectation = (last, first)
    156        my_expectation = (self.last, self.first)
    157        self.assertEqual(reality, my_expectation)
    158
    159        # first_number, second_number = 0, 1
    160        reality = src.functions.positional_arguments(
    161            # first_number, second_number,
    162            self.first_number, self.second_number,
    163        )
    164        # my_expectation = (first_number, second_number)
    165        my_expectation = (
    166            self.first_number, self.second_number
    167        )
    168        self.assertEqual(reality, my_expectation)
    169
    170        # a_tuple = (0, 1, 2, 'n')
    171        # a_list = [0, 1, 2, 'n']
    172        reality = src.functions.positional_arguments(
    173            # a_tuple, a_list,
    174            # self.a_tuple, a_list,
    175            self.a_tuple, self.a_list,
    176        )
    177        # my_expectation = (a_tuple, a_list)
    178        # my_expectation = (self.a_tuple, a_list)
    179        my_expectation = (self.a_tuple, self.a_list)
    180        self.assertEqual(reality, my_expectation)
    181
    182    def test_keyword_arguments(self):
    

    still green.

  • I remove the commented lines from test_positional_arguments

    140    def test_positional_arguments(self):
    141        reality = src.functions.positional_arguments(
    142            self.first, self.last,
    143        )
    144        my_expectation = (self.first, self.last)
    145        self.assertEqual(reality, my_expectation)
    146
    147        reality = src.functions.positional_arguments(
    148            self.last, self.first,
    149        )
    150        my_expectation = (self.last, self.first)
    151        self.assertEqual(reality, my_expectation)
    152
    153        reality = src.functions.positional_arguments(
    154            self.first_number, self.second_number,
    155        )
    156        my_expectation = (
    157            self.first_number, self.second_number
    158        )
    159        self.assertEqual(reality, my_expectation)
    160
    161        reality = src.functions.positional_arguments(
    162            self.a_tuple, self.a_list,
    163        )
    164        my_expectation = (self.a_tuple, self.a_list)
    165        self.assertEqual(reality, my_expectation)
    166
    167    def test_keyword_arguments(self):
    
  • I use the new class attributes to remove repetition of 0 and 1 from test_keyword_arguments

    167    def test_keyword_arguments(self):
    168        # first, last = 'first', 'last'
    169
    170        reality = src.functions.w_keyword_arguments(
    171            # first_input=first, last_input=last,
    172            first_input=self.first,
    173            last_input=self.last,
    174        )
    175        # my_expectation = (first, last)
    176        my_expectation = (self.first, self.last)
    177        self.assertEqual(reality, my_expectation)
    178
    179        reality = src.functions.w_keyword_arguments(
    180            # last_input=last, first_input=first,
    181            last_input=self.last,
    182            first_input=self.first,
    183        )
    184        # my_expectation = (first, last)
    185        my_expectation = (self.first, self.last)
    186        self.assertEqual(reality, my_expectation)
    187
    188        reality = src.functions.w_keyword_arguments(
    189            # last, first,
    190            self.last, self.first,
    191        )
    192        # my_expectation = (last, first)
    193        my_expectation = (self.last, self.first)
    194        self.assertEqual(reality, my_expectation)
    195
    196        # zero, one = 0, 1
    197        reality = src.functions.w_keyword_arguments(
    198            # last_input=zero, first_input=one,
    199            last_input=self.first_number,
    200            first_input=self.second_number,
    201        )
    202        # my_expectation = (one, zero)
    203        my_expectation = (
    204            self.second_number, self.first_number
    205        )
    206        self.assertEqual(reality, my_expectation)
    207
    208        a_set = {0, 1, 2, 'n'}
    209        a_dictionary = {'key': 'value'}
    210        reality = src.functions.w_keyword_arguments(
    211            first_input=a_set,
    212            last_input=a_dictionary,
    213        )
    214        my_expectation = (a_set, a_dictionary)
    215        self.assertEqual(reality, my_expectation)
    216
    217        # a_tuple = (0, 1, 2, 'n')
    218        # a_list = [0, 1, 2, 'n']
    219        reality = src.functions.positional_arguments(
    220            # first_input=a_list,
    221            # last_input=a_tuple,
    222            first_input=self.a_list,
    223            last_input=self.a_tuple,
    224        )
    225        # my_expectation = (a_list, a_tuple)
    226        # my_expectation = (a_list, self.a_tuple)
    227        my_expectation = (self.a_list, self.a_tuple)
    228        self.assertEqual(reality, my_expectation)
    229
    230    def test_args_and_kwargs(self):
    
  • I remove the commented lines from test_keyword_arguments

    167    def test_keyword_arguments(self):
    168        reality = src.functions.w_keyword_arguments(
    169            first_input=self.first,
    170            last_input=self.last,
    171        )
    172        my_expectation = (self.first, self.last)
    173        self.assertEqual(reality, my_expectation)
    174
    175        reality = src.functions.w_keyword_arguments(
    176            last_input=self.last,
    177            first_input=self.first,
    178        )
    179        my_expectation = (self.first, self.last)
    180        self.assertEqual(reality, my_expectation)
    181
    182        reality = src.functions.w_keyword_arguments(
    183            self.last, self.first,
    184        )
    185        my_expectation = (self.last, self.first)
    186        self.assertEqual(reality, my_expectation)
    187
    188        reality = src.functions.w_keyword_arguments(
    189            last_input=self.first_number,
    190            first_input=self.second_number,
    191        )
    192        my_expectation = (
    193            self.second_number, self.first_number
    194        )
    195        self.assertEqual(reality, my_expectation)
    196
    197        a_set = {0, 1, 2, 'n'}
    198        a_dictionary = {'key': 'value'}
    199        reality = src.functions.w_keyword_arguments(
    200            first_input=a_set,
    201            last_input=a_dictionary,
    202        )
    203        my_expectation = (a_set, a_dictionary)
    204        self.assertEqual(reality, my_expectation)
    205
    206        reality = src.functions.positional_arguments(
    207            first_input=self.a_list,
    208            last_input=self.a_tuple,
    209        )
    210        my_expectation = (self.a_list, self.a_tuple)
    211        self.assertEqual(reality, my_expectation)
    212
    213    def test_args_and_kwargs(self):
    
  • I add a git commit message

    git commit -am 'extract class attributes'
    

I can use class attributes to remove repetition


close the project

  • I close test_functions.py and functions.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.tests. The terminal goes back to the command line.

  • I change directory to the parent of functions

    cd ..
    

    the terminal shows

    .../pumping_python
    

    I am back in the pumping_python directory.


review

In AssertionError 2: use class attributes I used class attributes to remove repetition. The classes chapter shows the setUp method to make new values before every test, for example when I want random values for each test.

In some cases the values I need are the same for every test, which means I do not need the setUp method because the class attributes are the same for every test and I do not need anything to run before each test.

I can place the constants directly under the TestFunctions class:

first = 'first'
last = 'last'
a_tuple = (0, 1, 2, 'n')
a_list = [0, 1, 2, 'n']
first_number = 0
second_number = 1

then test_positional_arguments, test_keyword_arguments and test_args_and_kwargs use self.first and so on, instead repeated values.

I can use class attributes for things that repeat (when they are constants), which allows methods of the same class to use them without the setUp method.


code from the chapter

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


what is next?

Here is another reminder, you know

Would you like to test AttributeError?


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.