18.1. Introduction: Test Cases

When we write functions that return values, we intend to use them over and over again. However, we want to be certain that they return the correct result. To be more certain these functions work correctly we write test cases.

A test case expresses requirements for a program, in a way that can be checked automatically. Specifically, a test asserts something about the state of the program at a particular point in its execution.

We have previously suggested that it’s a good idea to first write down comments about what your code is supposed to do, before actually writing the code. It is an even better idea to write down some test cases before writing a program. For example, before writing a function, write a few test cases that check that it returns an object of the right type and that it returns the correct values when invoked on particular inputs.

You’ve actually been using test cases throughout this book in some of the activecode windows and almost all of the exercises. The code for them has been hidden, so as not to confuse you and also to avoid giving away the answers. Now it’s time to learn how to write code for test cases.

To write a unit test, we must know the correct result when calling the function with a specific input.

testEqual (from the test module) is a function that allows us to perform a unit test. It takes two parameters. The first is a call to the function we want to test (square in this example) with a particular input (10 in this example). The second parameter is the correct result that should be produced (100 in this example). test.testEqual compares what the function returns with the correct result and displays whether the unit test passes or fails.

Extend the program …

On line 8, write another unit test (that should pass) for the square function.

Note

The test module is not a standard Python module. Instead, there are other more powerful and more modern modules, such as one called unittest which will be taught in more advanced courses. However, the test module offers a simple introduction to testing that is appropriate at this stage in the interactive text.

Check your understanding

    test-1-1: When test.testEqual() is passed two values that are not the same, it generates an error and stops execution of the program.
  • True
  • A message is printed out, but the program does not stop executing
  • False
  • A message is printed out, but the program does not stop executing
  • It depends
  • A message is printed out, but the program does not stop executing
    test-1-2: Test cases are a waste of time, because the python interpreter will give an error message when the program runs incorrectly, and that’s all you need for debugging.
  • True
  • You might not notice the error, if the code just produces a wrong output rather generating an error. And it may be difficult to figure out the original cause of an error when you do get one.
  • False
  • Test cases let you test some pieces of code as you write them, rather than waiting for problems to show themselves later.

    test-1-3: Which of the following is the correct way to write a test to check that ‘under’ will be blanked as 'u_d__' when the user has guessed letters d and u so far?

    def blanked(word, revealed_letters):
        return word
    
    import test
    
    test.testEqual(blanked('hello', 'elj'), "_ell_")
    test.testEqual(blanked('hello', ''), '_____')
    test.testEqual(blanked('ground', 'rn'), '_r__n_')
    test.testEqual(blanked('almost', 'vrnalmqpost'), 'almost')
    
  • test.testEqual(blanked('under', 'du', 'u_d__'))
  • blanked only takes two inputs; this provides three inputs to the blanked function
  • test.testEqual(blanked('under', 'u_d__'), 'du')
  • The second argument to the blanked function should be the letters that have been guessed, not the blanked version of the word
  • test.testEqual(blanked('under', 'du'), 'u_d__')
  • This checks whether the value returned from the blanked function is 'u_d__'.
Next Section - 18.2. 👩‍💻 Writing Test Cases