lists



A list is an object that can hold other objects

  • they are represented with []

  • they can be made with the list constructor

  • they can be changed by performing an operation, this means they are mutable

requirements

  • I open a terminal to run makePythonTdd.sh with lists as the name of the project

    ./makePythonTdd.sh lists
    

    on Windows without Windows Subsystem Linux use makePythonTdd.ps1

    ./makePythonTdd.ps1 lists
    

    it makes the folders and files that are needed, installs packages, runs the first test, and the terminal shows AssertionError

    E       AssertionError: True is not false
    
    tests/test_lists.py:7: AssertionError
    
  • I hold ctrl (windows/linux) or option (mac) on the keyboard and use the mouse to click on tests/test_lists.py:7 to open it in the editor

  • then change True to False to make the test pass


test_make_a_list_w_list_constructor

red: make it fail

I change test_failure to test_make_a_list

import unittest


class TestLists(unittest.TestCase):

    def test_make_a_list_w_list_constructor(self):
        self.assertEqual(list(0, 1, 2, 3), None)

the terminal shows TypeError

TypeError: list expected at most 1 argument, got 4

green: make it pass

  • I add the error to the list of Exceptions encountered

    # Exceptions Encountered
    # AssertionError
    # TypeError
    
  • I change the values provided to the list constructor to a tuple by placing them in parentheses

    def test_make_a_list_w_list_constructor(self):
        self.assertEqual(list((0, 1, 2, 3)), None)
    

    and get AssertionError in the terminal

    AssertionError: [0, 1, 2, 3] != None
    

    when I change the right side to match the values on the left from the terminal

    def test_make_a_list_w_list_constructor(self):
        self.assertEqual(list((0, 1, 2, 3)), [0, 1, 2, 3])
    

    the test passes

test_make_a_list_w_square_brackets

I can make a list with the list constructor and the passing test shows I can make one with [].

red: make it fail

I add a test

def test_make_a_list_w_list_constructor(self):
    ...

def test_make_a_list_w_square_brackets(self):
    self.assertEqual([0, 1, 2, 3], list((0, 1, 2, 4)))

the terminal shows AssertionError for the last value

AssertionError: Lists differ: [0, 1, 2, 3] != [0, 1, 2, 4]

green: make it pass

I change the value to match the expectation

def test_make_a_list_w_square_brackets(self):
    self.assertEqual([0, 1, 2, 3], list((0, 1, 2, 3)))

the test passes. Making a list with square brackets uses less characters than with the constructor


test_make_a_list_from_an_iterable

red: make it fail

I add another test

def test_make_a_list_w_square_brackets(self):
    ...

def test_make_a_list_from_an_iterable(self):
    self.assertEqual(range(4), [0, 1, 2, 3])

the terminal shows AssertionError

AssertionError: range(0, 4) != [0, 1, 2, 3]

green: make it pass

range(x) makes a range object which is an iterable of numbers that go from a default of 0 to the given number minus 1, in this case it will be 0 to 3

I use it as input to the list constructor

self.assertEqual(list(iterable), [0, 1, 2, 3])

the test passes


test_attributes_and_methods_of_lists

I can use the dir function to look at the attributes and methods of list

red: make it fail

I add a failing test

def test_make_a_list_w_an_iterable(self):
    ...

def test_attributes_and_methods_of_lists(self):
    self.assertEqual(
        dir(list),
        []
    )

the terminal shows AssertionError

the terminal also shows a recommendation on how to see the differences between dir(list) and []

Diff is 748 characters long. Set self.maxDiff to None to see it

unittest.TestCase.maxDiff is an attribute of the unittest.TestCase class that sets the maximum number of characters to show when comparing 2 objects in the terminal, when it is set to None it shows all the differences

green: make it pass

  • I add self.maxDiff to the test

    def test_attributes_and_methods_of_lists(self):
        self.maxDiff = None
        self.assertEqual(
            dir(list),
            []
        )
    

    the terminal shows a long list of items

  • I copy and paste the items from the terminal and remove the extra characters

    Note

    Your results can be different because of your version of Python

    def test_attributes_and_methods_of_lists(self):
        self.maxDiff = None
        self.assertEqual(
            dir(list),
            [
                '__add__',
                '__class__',
                '__class_getitem__',
                '__contains__',
                '__delattr__',
                '__delitem__',
                '__dir__',
                '__doc__',
                '__eq__',
                '__format__',
                '__ge__',
                '__getattribute__',
                '__getitem__',
                '__getstate__',
                '__gt__',
                '__hash__',
                '__iadd__',
                '__imul__',
                '__init__',
                '__init_subclass__',
                '__iter__',
                '__le__',
                '__len__',
                '__lt__',
                '__mul__',
                '__ne__',
                '__new__',
                '__reduce__',
                '__reduce_ex__',
                '__repr__',
                '__reversed__',
                '__rmul__',
                '__setattr__',
                '__setitem__',
                '__sizeof__',
                '__str__',
                '__subclasshook__',
                'append',
                'clear',
                'copy',
                'count',
                'extend',
                'index',
                'insert',
                'pop',
                'remove',
                'reverse',
                'sort'
            ]
        )
    

    the terminal shows passing tests. We can ignore anything with double underscores (__) for now

  • I copy and paste the methods to make a TODO list for tests to add

    'append',
    'clear',
    'copy',
    'count',
    'extend',
    'index',
    'insert',
    'pop',
    'remove',
    'reverse',
    'sort'
    
    # Exceptions Encountered
    # AssertionError
    # TypeError
    

test_append_adds_to_a_list

red: make it fail

I add a test for the append method

def test_attributes_and_methods_of_lists(self):
    ...

def test_append(self):
    a_list = [0, 1, 2, 3]
    self.assertIsNone(a_list.append())

the terminal shows TypeError

TypeError: list.append() takes exactly one argument (0 given)

the append method returns None when it is called

green: make it pass

I add input

self.assertIsNone(a_list.append(4))

the terminal shows green

refactor: make it better

I add another assert to find out what happens to the list

self.assertIsNone(a_list.append(4))
self.assertEqual(a_list, [0, 1, 2, 3])

the terminal shows AssertionError

AssertionError: Lists differ: [0, 1, 2, 3, 4] != [0, 1, 2, 3]

the values in a_list change after the append method is called. I change the values in the test to match the values in the terminal

self.assertEqual(a_list, [0, 1, 2, 3, 4])

the test passes, then I rename the test

def test_append_adds_to_a_list(self):
    a_list = [0, 1, 2, 3]
    self.assertIsNone(a_list.append(4))
    self.assertEqual(a_list, [0, 1, 2, 3, 4])

I remove append from the TODO list

'clear',
'copy',
'count',
'extend',
'index',
'insert',
'pop',
'remove',
'reverse',
'sort'

test_clear_empties_a_list

I add a test for the clear method

def test_append_adds_to_a_list(self):
    ...

def test_clear(self):
    a_list = [0, 1, 2, 3]
    self.assertIsNone(a_list.clear())

the terminal shows green. The clear method returns None when it is called

red: make it fail

I want to know what the method does to the list

self.assertIsNone(a_list.clear())
self.assertEqual(a_list, [0, 1, 2, 3])

the terminal shows AssertionError

AssertionError: Lists differ: [] != [0, 1, 2, 3]

green: make it pass

I change the values to match

self.assertEqual(a_list, [])

the test passes. I change the name of the test to be more descriptive

def test_clear_empties_a_list(self):
    a_list = [0, 1, 2, 3]
    self.assertIsNone(a_list.clear())
    self.assertEqual(a_list, [])

I remove clear from the TODO list

'copy',
'count',
'extend',
'index',
'insert',
'pop',
'remove',
'reverse',
'sort'

test_copy_a_list

red: make it fail

I add another test

def test_clear_empties_a_list(self):
    ...

def test_copy(self):
    a_list = [0, 1, 2, 3]
    self.assertIsNone(a_list.copy())

the terminal shows AssertionError

AssertionError: [0, 1, 2, 3] is not None

the copy method returns a copy of the list

green: make it pass

I add the value and change the assert method

def test_copy(self):
    a_list = [0, 1, 2, 3]
    self.assertEqual(a_list.copy(), [0, 1, 2, 3])

the test passes

refactor: make it better

I add another assertion to see what happened to the original list

self.assertEqual(a_list.copy(), [0, 1, 2, 3])
self.assertEqual(a_list, [0, 1, 2, 3])

the terminal still shows green, the original list is still the same. I change the name of the test

def test_copy_a_list(self):
    a_list = [0, 1, 2, 3]
    self.assertEqual(a_list.copy(), [0, 1, 2, 3])
    self.assertEqual(a_list, [0, 1, 2, 3])

the test is still green, I remove copy from the TODO list

'count',
'extend',
'index',
'insert',
'pop',
'remove',
'reverse',
'sort'

test_count_number_of_times_item_is_in_a_list

red: make it fail

I add a test for the next method

def test_count(self):
    a_list = [0, 1, 2, 3]
    self.assertIsNone(a_list.count())

the terminal shows TypeError

TypeError: list.count() takes exactly one argument (0 given)

red: make it fail

I pass a value to the call

def test_count(self):
    a_list = [0, 1, 2, 3]
    self.assertIsNone(a_list.count(0))

the terminal shows AssertionError

AssertionError: 1 is not None

green: make it pass

I add the value and change the assert method

def test_count(self):
    a_list = [0, 1, 2, 3]
    self.assertEqual(a_list.count(0), 1)

the test passes. It looks like the count method returns the number of times an item appears

refactor: make it better

  • I change the list then add another assert call to be sure

    def test_count(self):
        a_list = [0, 2, 1, 2, 3, 2]
        self.assertEqual(a_list.count(0), 1)
        self.assertEqual(a_list.count(2), 1)
    

    the terminal shows AssertionError

    AssertionError: 3 != 1
    

    I change the value to match

    self.assertEqual(a_list.count(2), 3)
    

    the test passes

  • I add another assertion to see what happens when I try to count an item that is not in the list

    self.assertEqual(a_list.count(0), 1)
    self.assertEqual(a_list.count(2), 3)
    self.assertEqual(a_list.count(9), 1)
    

    the terminal shows AssertionError

    AssertionError: 0 != 1
    

    The count method returns 0 when the item is not in the list. I change the value

    self.assertEqual(a_list.count(9), 0)
    

    the test passes

  • I rename the test

    def test_count_number_of_times_item_is_in_a_list(self):
        a_list = [0, 2, 1, 2, 3, 2]
        self.assertEqual(a_list.count(0), 1)
        self.assertEqual(a_list.count(2), 3)
        self.assertEqual(a_list.count(9), 0)
    
  • I remove count from the TODO list

    'extend',
    'index',
    'insert',
    'pop',
    'remove',
    'reverse',
    'sort'
    

test_extend_makes_a_list_longer

red: make it fail

time for another test

def test_count_number_of_times_item_is_in_a_list(self):
    ...

def test_extend(self):
    a_list = [0, 1, 2, 3]
    self.assertIsNone(a_list.extend())

the terminal shows TypeError

TypeError: list.extend() takes exactly one argument (0 given)

green: make it pass

I pass a value to the call

self.assertIsNone(a_list.extend(0))

the terminal shows TypeError

TypeError: 'int' object is not iterable

I change the value to an iterable

self.assertIsNone(a_list.extend((0, 1, 2, 3)))

the test passes. The extend method returns None when called

refactor: make it better

  • I add another assertion to see what changed in the list

    self.assertIsNone(a_list.extend((0, 1, 2, 3)))
    self.assertEqual(a_list, [0, 1, 2, 3])
    

    the terminal shows AssertionError

    AssertionError: Lists differ: [0, 1, 2, 3, 0, 1, 2, 3] != [0, 1, 2, 3]
    

    I change the values in the test to match

    self.assertEqual(a_list, [0, 1, 2, 3, 0, 1, 2, 3])
    

    the test passes

  • I change the values given to the extend method

    def test_extend(self):
        a_list = [0, 1, 2, 3]
        self.assertIsNone(a_list.extend((4, 5, 6, 7)))
        self.assertEqual(a_list, [0, 1, 2, 3, 0, 1, 2, 3])
    

    the terminal shows AssertionError

    AssertionError: Lists differ: [0, 1, 2, 3, 4, 5, 6, 7] != [0, 1, 2, 3, 0, 1, 2, 3]
    

    I change the values to match

    self.assertEqual(a_list, [0, 1, 2, 3, 4, 5, 6, 7])
    

    the test passes

  • I change the name of the test

    def test_extend_makes_a_list_longer(self):
        a_list = [0, 1, 2, 3]
        self.assertIsNone(a_list.extend((4, 5, 6, 7)))
        self.assertEqual(a_list, [0, 1, 2, 3, 4, 5, 6, 7])
    

    the test is still green

  • I remove extend from the TODO list

    'index',
    'insert',
    'pop',
    'remove',
    'reverse',
    'sort'
    

test_index_returns_position_of_item_in_a_list

red: make it fail

I add a test for the index method

def test_extend_makes_a_list_longer(self):
    ...

def test_index(self):
    a_list = [0, 1, 2, 3]
    self.assertIsNone(a_list.index())

the terminal shows TypeError

TypeError: index expected at least 1 argument, got 0

green: make it pass

I add a value to the call

def test_index(self):
    a_list = [0, 1, 2, 3]
    self.assertIsNone(a_list.index(0))

the terminal shows AssertionError

AssertionError: 0 is not None

I add the expectation and change the assert method

def test_index(self):
    a_list = [0, 1, 2, 3]
    self.assertEqual(a_list.index(0), 0)

the test passes

refactor: make it better

  • I change the values in a_list

    def test_index(self):
        a_list = ['1st', '2nd', '3rd', '... last']
        self.assertEqual(a_list.index(0), 0)
    

    the terminal shows ValueError

    ValueError: 0 is not in list
    

    I add the error to the list of Exceptions encountered

    # Exceptions Encountered
    # AssertionError
    # TypeError
    # ValueError
    

    I add assertRaises to handle the Exception and remove assertEqual

    def test_index(self):
        a_list = ['1st', '2nd', '3rd', '... last']
    
        with self.assertRaises(ValueError):
            a_list.index(0)
    

    the test is green again

  • I add a new assertion for the index method

    def test_index(self):
        a_list = ['1st', '2nd', '3rd', '... last']
        self.assertEqual(a_list.index('1st'), 0)
    
        with self.assertRaises(ValueError):
            a_list.index(0)
    

    the test is still green

  • I add another assertion

    self.assertEqual(a_list.index('1st'), 0)
    self.assertEqual(a_list.index('3rd'), 0)
    

    the terminal shows AssertionError

    AssertionError: 2 != 0
    

    I change the value in the test

    self.assertEqual(a_list.index('3rd'), 2)
    

    the test passes

  • I add another call to assertEqual

    self.assertEqual(a_list.index('3rd'), 2)
    self.assertEqual(a_list.index('2nd'), 0)
    

    the terminal shows AssertionError

    AssertionError: 1 != 0
    

    I change the value to match

    self.assertEqual(a_list.index('2nd'), 1)
    

    the test is green again

  • I add another assertion

    self.assertEqual(a_list.index('2nd'), 1)
    self.assertEqual(a_list.index('... last'), 0)
    

    the terminal shows AssertionError

    AssertionError: 3 != 0
    

    I change the value in the test to match the one in the terminal

    self.assertEqual(a_list.index('... last'), 3)
    

    the test passes. Python uses zero-based indexing which means the first item has an index of 0 and the last item has an index of the length of the list minus 1

  • I rename the test

    def test_index_returns_position_of_item_in_a_list(self):
        a_list = ['1st', '2nd', '3rd', '... last']
        self.assertEqual(a_list.index('1st'), 0)
        self.assertEqual(a_list.index('3rd'), 2)
        self.assertEqual(a_list.index('2nd'), 1)
        self.assertEqual(a_list.index('... last'), 3)
    
        with self.assertRaises(ValueError):
            a_list.index(0)
    
  • I also remove index from the TODO list

    'insert',
    'pop',
    'remove',
    'reverse',
    'sort'
    

test_insert_places_item_at_given_index_in_a_list

red: make it fail

I add a test for the next method

def test_index_returns_position_of_item_in_a_list(self):
    ...

def test_insert(self):
    a_list = [0, 1, 2, 3]
    self.assertIsNone(a_list.insert())

the terminal shows TypeError

TypeError: insert expected 2 arguments, got 0

green: make it pass

I pass two values to the method

def test_insert(self):
    a_list = [0, 1, 2, 3]
    self.assertIsNone(a_list.insert(0, 1))

the test is green. The insert method returns None

refactor: make it better

  • I add an assertion to find out what changed in the list

    self.assertIsNone(a_list.insert(0, 1))
    self.assertEqual(a_list, [0, 1, 2, 3])
    

    the terminal shows AssertionError

    AssertionError: Lists differ: [1, 0, 1, 2, 3] != [0, 1, 2, 3]
    

    I add the new value to the list

    self.assertEqual(a_list, [1, 0, 1, 2, 3])
    

    the test passes. The insert method places the second input given at the index given as the first input

  • I rename the test

    def test_insert_places_item_at_given_index_in_a_list(self):
        a_list = [0, 1, 2, 3]
        self.assertIsNone(a_list.insert(0, 1))
        self.assertEqual(a_list, [1, 0, 1, 2, 3])
    
  • I remove insert from the TODO list

    'pop',
    'remove',
    'reverse',
    'sort'
    

test_pop_removes_and_returns_last_item_in_a_list

red: make it fail

I add a new test

def test_insert_places_item_at_given_index_in_a_list(self):
    ...

def test_pop(self):
    a_list = [0, 1, 2, 3]
    self.assertIsNone(a_list.pop())

the terminal shows AssertionError

AssertionError: 3 is not None

The pop method returns the last item in the list

green: make it pass

I change the assert method then add the value from the terminal

def test_pop(self):
    a_list = [0, 1, 2, 3]
    self.assertEqual(a_list.pop(), 3)

the test passes

refactor: make it better

  • I add an assertion to see what the method does to the list

    self.assertEqual(a_list.pop(), 3)
    self.assertEqual(a_list, [0, 1, 2, 3])
    

    the terminal shows AssertionError

    AssertionError: Lists differ: [0, 1, 2] != [0, 1, 2, 3]
    

    The pop method removes and returns the last item in the list. I change the values in the test to match

    self.assertEqual(a_list, [0, 1, 2])
    

    the test passes

  • I rename the test

    def test_pop_removes_and_returns_last_item_in_a_list(self):
        a_list = [0, 1, 2, 3]
        self.assertEqual(a_list.pop(), 3)
        self.assertEqual(a_list, [0, 1, 2])
    
  • I remove pop from the TODO list

    'remove',
    'reverse',
    'sort'
    

test_remove_first_instance_of_item_from_a_list

red: make it fail

time for the next method

def test_remove(self):
    a_list = [0, 1, 2, 3]
    self.assertIsNone(a_list.remove(2))

the terminal shows green, the remove method returns None. I want to know if the list has changed

self.assertIsNone(a_list.remove(2))
self.assertEqual(a_list, [0, 1, 2, 3])

the terminal shows AssertionError

AssertionError: Lists differ: [0, 1, 3] != [0, 1, 2, 3]

the method removes the item given from the list

green: make it pass

I change the expectation in the assert statement

self.assertEqual(a_list, [0, 1, 3])

the test passes

refactor: make it better

  • I change the values in a_list to see what would happen if an item shows up more than once in the list

    def test_remove(self):
        a_list = [0, 2, 1, 2, 3, 2]
        self.assertIsNone(a_list.remove(2))
        self.assertEqual(a_list, [0, 1, 3])
    

    the terminal shows AssertionError

    AssertionError: Lists differ: [0, 1, 2, 3, 2] != [0, 1, 3]
    

    the method removes the first occurrence of a given item from the list. I change the test to match

    self.assertEqual(a_list, [0, 1, 2, 3, 2])
    

    the test passes

  • I want to know what happens if the item does not exist in the list

    self.assertEqual(a_list, [0, 1, 2, 3, 2])
    self.assertIsNone(a_list.remove(4))
    

    the terminal shows ValueError

    ValueError: list.remove(x): x not in list
    

    I add assertRaises and remove the call to assertIsNone

    with self.assertRaises(ValueError):
        a_list.remove(4)
    

    the test passes

  • I rename the test

    def test_remove_first_instance_of_item_from_a_list(self):
        a_list = [0, 2, 1, 2, 3, 2]
        self.assertIsNone(a_list.remove(2))
        self.assertEqual(a_list, [0, 1, 2, 3, 2])
    
        with self.assertRaises(ValueError):
            a_list.remove(4)
    
  • I take out remove from the TODO list

    'reverse',
    'sort'
    

test_reverse_a_list

red: make it fail

I add the next test

def test_reverse(self):
    a_list = [0, 1, 2, 3]
    self.assertIsNone(a_list.reverse())

the terminal shows green. This method returns None. I add an assertion to see what has changed in the list

self.assertIsNone(a_list.reverse())
self.assertEqual(a_list, [0, 1, 2, 3])

the terminal show AssertionError

AssertionError: Lists differ: [3, 2, 1, 0] != [0, 1, 2, 3]

the method reverses the order of the list

green: make it pass

I change the expectation

self.assertEqual(a_list, [3, 2, 1, 0])

the test passes

refactor: make it better

  • I rename the test

    def test_reverse_a_list(self):
        a_list = [0, 1, 2, 3]
        self.assertIsNone(a_list.reverse())
        self.assertEqual(a_list, [3, 2, 1, 0])
    
  • I remove the method from the TODO list

    'sort'
    

test_sort_a_list

red: make it fail

I add a test

def test_sort(self):
    a_list = [0, 1, 2, 3]
    self.assertIsNone(a_list.sort())

the terminal still shows green. sort returns None when called, what does it do to the list?

def test_sort(self):
    a_list = [0, 1, 2, 3]
    self.assertIsNone(a_list.sort())
    self.assertEqual(a_list, [0, 1, 2, 3])

the list is still the same. I change the values in a_list to see if it makes a difference

def test_sort(self):
    a_list = [0, 2, 1, 2, 3, 2]

I get AssertionError

AssertionError: Lists differ: [0, 1, 2, 2, 2, 3] != [0, 1, 2, 3]

the sort method arranges the list in ascending order by default

green: make it pass

I change the values to match

self.assertEqual(a_list, [0, 1, 2, 2, 2, 3])

the test passes

refactor: make it better

  • I change the name of the test

    def test_sort_a_list(self):
        a_list = [0, 2, 1, 2, 3, 2]
        self.assertIsNone(a_list.sort())
        self.assertEqual(a_list, [0, 1, 2, 2, 2, 3])
    

    still green

  • I remove sort from the TODO list


test_view_items_in_a_list

I can provide the index of an item I want to see in [] to a list

red: make it fail

I add a failing test

def test_view_items_in_a_list(self):
    a_list = ['1st', '2nd', '3rd', '... last']
    self.assertEqual(a_list[0], '')

the terminal shows AssertionError

AssertionError: '1st' != ''

Python starts indexing at 0 as shown in test_index_returns_position_of_item_in_a_list

green: make it pass

I change the value in the test

self.assertEqual(a_list[0], '1st')

the test passes

refactor: make it better

  • I add another line, this time with a negative number

    def test_view_items_in_a_list(self):
        a_list = ['1st', '2nd', '3rd', '... last']
        self.assertEqual(a_list[0], '1st')
        self.assertEqual(a_list[-4], '')
    

    the terminal shows AssertionError

    AssertionError: '1st' != ''
    

    I change the value to match

    self.assertEqual(a_list[-4], '1st')
    

    the test passes

  • I add another assert statement

    self.assertEqual(a_list[-4], '1st')
    self.assertEqual(a_list[2], '')
    

    the terminal shows AssertionError

    AssertionError: '3rd' != ''
    

    I change the expectation to match

    self.assertEqual(a_list[2], '3rd')
    

    the terminal shows green again

  • I add another line with a negative number

    self.assertEqual(a_list[2], '3rd')
    self.assertEqual(a_list[-2], '')
    

    and get AssertionError

    AssertionError: '3rd' != ''
    

    I change the expectation

    self.assertEqual(a_list[-2], '3rd')
    

    the test passes

  • I add another line

    self.assertEqual(a_list[-2], '3rd')
    self.assertEqual(a_list[1], '')
    

    the terminal shows AssertionError

    AssertionError: '2nd' != ''
    

    I make the test pass

    self.assertEqual(a_list[1], '2nd')
    
  • I add another one

    self.assertEqual(a_list[1], '2nd')
    self.assertEqual(a_list[-3], '')
    

    the terminal shows AssertionError

    AssertionError: '2nd' != ''
    

    I change the value

    self.assertEqual(a_list[-3], '2nd')
    

    the test passes

  • I add another assertion

    self.assertEqual(a_list[-3], '2nd')
    self.assertEqual(a_list[3], '')
    

    and get AssertionError

    AssertionError: '... last' != ''
    

    I change the value

    self.assertEqual(a_list[3], '... last')
    

    the test passes

  • I add another assertion

    self.assertEqual(a_list[3], '... last')
    self.assertEqual(a_list[-1], '')
    

    the terminal shows AssertionError

    AssertionError: '... last' != ''
    

    I make the values match

    self.assertEqual(a_list[-1], '... last')
    

    all tests are still passing


test_view_parts_of_a_list

red: make it fail

I add another test

def test_view_items_in_a_list(self):
    ...

def test_view_parts_of_a_list(self):
    a_list = ['1st', '2nd', '3rd', '... last']
    self.assertEqual(a_list[0:2], [])

the terminal shows AssertionError

AssertionError: Lists differ: ['1st', '2nd'] != []

viewing parts of a list is like indexing, it takes two values in square brackets [], seperated by a :, the first value is the starting index you want and the second value is the ending index plus 1

green: make it pass

I change the values to match

self.assertEqual(a_list[0:2], ['1st', '2nd'])

the test passes

refactor: make it better

  • I add another assertion

    self.assertEqual(a_list[0:2], ['1st', '2nd'])
    self.assertEqual(a_list[0:3], ['1st', '2nd'])
    

    the terminal shows AssertionError

    AssertionError: Lists differ: ['1st', '2nd', '3rd'] != ['1st', '2nd']
    

    I add the missing value

    self.assertEqual(a_list[0:3], ['1st', '2nd', '3rd'])
    

    the test passes

  • I add another line

    self.assertEqual(a_list[0:3], ['1st', '2nd', '3rd'])
    self.assertEqual(a_list[1:4], ['2nd', '3rd'])
    

    the terminal shows AssertionError

    AssertionError: Lists differ: ['2nd', '3rd', '... last'] != ['2nd', '3rd']
    

    I change the expectation

    self.assertEqual(a_list[1:4], ['2nd', '3rd', '... last'])
    

    the test is green again

  • One more assert statement for good measure

    self.assertEqual(a_list[1:4], ['2nd', '3rd', '... last'])
        self.assertEqual(a_list[1:3], ['2nd', '3rd', '... last'])
    

    I get AssertionError

    AssertionError: Lists differ: ['2nd', '3rd'] != ['2nd', '3rd', '... last']
    

    I change the expectation

    self.assertEqual(a_list[1:3], ['2nd', '3rd'])
    

    the test is green again


test_index_error

IndexError is raised when I try to get an item from a list but use a number that is greater than range of indexes for it

red: make it fail

I add a failing test to show this

def test_index_error(self):
    a_list = ['a', 'b', 'c', 'd']
    a_list[4]

the terminal shows IndexError

IndexError: list index out of range

green: make it pass

  • I add IndexError to the list of Exceptions encountered

    # Exceptions Encountered
    # AssertionError
    # TypeError
    # ValueError
    # IndexError
    
  • I add assertRaises to handle the error

    def test_index_error(self):
        a_list = ['a', 'b', 'c', 'd']
    
        with self.assertRaises(IndexError):
            a_list[5]
    

    the test passes

refactor: make it better

I add one more line to test indexing with a negative number that is outside the range of numbers that can be used to index the list

def test_index_error(self):
    a_list = ['a', 'b', 'c', 'd']

    with self.assertRaises(IndexError):
        a_list[5]
    a_list[-5]

the terminal shows IndexError

IndexError: list index out of range

I add another assertRaises

def test_index_error(self):
    a_list = ['a', 'b', 'c', 'd']
    with self.assertRaises(IndexError):
        a_list[5]
    with self.assertRaises(IndexError):
        a_list[-5]

the test passes


review

I ran tests for lists

  • they are represented with []

  • they can be made with the list constructor

  • they can hold any object

  • they can be changed by performing an operation, this means they are mutable

Would you like to test list comprehensions?


data structures: Lists: tests