Python unit testing for a Stack data structure I am completely new to unit testing. I read this chapter in Dive Into Python 3, and decided to give it a try on a basic data structure: a stack.

Here is the stack code (taken from "Problem Solving with Algorithms and Data Structures using Python"):

class Stack:
     def __init__(self):
         self.items = []

     def isEmpty(self):
         return self.items == []

     def push(self, item):
         self.items.append(item)

     def pop(self):
         return self.items.pop()

     def peek(self):
         return self.items[len(self.items)-1]

     def size(self):
         return len(self.items)


Here is my testing code:

import unittest

class StackTester(unittest.TestCase):

    def test_stack_init(self):
        s = Stack()
        self.assertEqual(0, s.size())

    def test_push1_size(self):
        item = 5
        s = Stack()
        s.push(item)
        self.assertEqual(1, s.size())

    def test_push1_items(self):
        s = Stack()
        s.push(5)
        self.assertEqual([5], s.items)

    def test_push2_size(self):
        s = Stack()
        s.push(5)
        s.push(6)
        self.assertEqual(2, s.size())

    def test_push2_items(self):
        s = Stack()
        s.push(5)
        s.push(6)
        self.assertEqual([5,6], s.items)

    def test_push2_pop1_size(self):
        s = Stack()
        s.push(5)
        s.push(6)
        s.pop()
        self.assertEqual(1, s.size())

    def test_push2_pop1_value(self):
        s = Stack()
        s.push(8)
        s.push(9)
        self.assertEqual(9, s.pop())

    def test_push2_pop2_size(self):
        s = Stack()
        s.push("Glob")
        s.push("Blob")
        s.pop()
        s.pop()
        self.assertEqual(0, s.size())

    def test_push2_pop2_value(self):
        s = Stack()
        s.push("Glob")
        s.push("Blob")
        s.pop()
        self.assertEqual("Glob", s.pop())

    def test_isEmpty_init(self):
        s = Stack()
        self.assertEqual(True, s.isEmpty())

    def test_isEmpty_push1(self):
        s = Stack()
        s.push(5)
        self.assertEqual(False, s.isEmpty())

    def test_isEmpty_push1_pop1(self):
        s = Stack()
        s.push(1)
        s.pop()
        self.assertEqual(True, s.isEmpty())

    def test_peek_push1(self):
        s = Stack()
        s.push(88)
        self.assertEqual(88, s.peek())

    def test_peek_push3_pop1(self):
        s = Stack()
        s.push(7)
        s.push(889)
        s.push(3)
        s.pop()
        self.assertEqual(889, s.peek())

    def test_pop_empty(self):
        s = Stack()
        self.assertRaises(IndexError, s.pop)

    def test_peek_empty(self):
        s = Stack()
        self.assertRaises(IndexError, s.peek)

if __name__ == '__main__':
    unittest.main()


Am I leaving anything out? Is 16 tests for a stack overkill? What are the best practices for something like this?
There are certainly some good tests here. In a related question for Java, the answer by Phil Wright states:


  Here are some tests I'd perform at the very least. There may be more
  you'd want:
  
  
  Create an empty Stack. Test that its size is 0.
  Push an element onto the stack. Test that its size is now 1.
  Push another element onto the stack. Test that its size is now 2.
  Pop an element from the stack. Test that it matches the 2nd pushed value. Check that the size of the stack is now 1.
  Pop an element from the stack. Test that it matches the 1st pushed value. Check that the size of the stack is 0.
  Attempt to pop an element from the stack. You should receive an ArrayIndexOutOfBounds exception.
  


At a quick glance, you do most (if not all of these tests). So in some sense the coverage is good. 

The amount of testing may be overkill. You have to realize you can't test every possible thing. With that in mind your tests should:


Find current issues with your code.
Nip likely future issues.
Prevent errors you've had in the past from coming back.


The past, present, and future. So for example, your function test_peek_push3_pop1 may have a good reason for being there. Maybe you had designed a stack before and had issues with pushing 3, popping 1, and then peeking. I've never personally had such an issue. It seems like a weird test case I wouldn't consider it, but maybe you have. If you have a compelling reason to have that test you should explain your reasoning in a comment so I can understand the purpose of the test. Ultimately:


  Think and comment WHY you have a test.