Unit testing

Background

One thing we've learned through decades of software engineering is that developing correct software is difficult! The best way to ensure correctness is to test thoroughly while software is being developed. unit testing is a framework that automates testing by providing a standard format for tests and an easy way to execute them . In today's lab, you will design and implement your own unit tests cases.

Collaboration: You are encouraged to work with another student to complete this lab.

Computer bug image

The first computer bug (see Grace Hopper)

 

Objectives

  • Create a test program for use with Python Unit Testing module.
  • Write Python test functions that use assertEquals.
  • Run Python tests for a program or group of functions.

Key Terms

test program

A program that has the purpose of testing some other program, but is not part of the final application.

test function

A function that has the purpose of testing another function, but is not part of the final application.

assertion

A statement that should always be true. Assertions make claims about the expected behavior of programs.

 

Part 1: Using Unit Testing

The basic Unit Test pattern is simple:

  • For every program x there is a companion prorgram named test_x that is responsible for testing the class.
  • For every function m there is at least one companion function test_m that is responsible for testing the function.

Class Being Developed

 

"""
Lab 10-Basic Math - perform basic math on 2 operators.

Author: YOUR NAME
Version: Date
"""


def add(x, y):
    """Add - sum of x and y.

    Args:
        x(float): first number
        y(float): second number

    Returns:
        float: sum of x and y
    """
    sum = x + y
    return sum


def subtract(x, y):
    """Difference between x and y.

    Args:
        x(float): first number
        y(float): second number

    Returns:
        float: difference between x and y
    """
    diff = x - y
    return diff

Unit Tests 


import unittest
import basic_math

class TestBasicMath(unittest.TestCase):

def test_add(self):
expected = 15.5
actual = basic_math.add(7.2, 8.3)
self.assertEqual(expected, actual)

def test_subtract(self):
expected = 2.2
actual = basic_math.subtract(3.5, 1.3)
self.assertEqual(expected, actual)

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

Note in the above example:

  • import the unit testing module and the functions from the file you want to test
  • Each test is preceded by test_. This is referred to as an annotation. In this case, the test_ annotation tells Python Unit Testing module to treat the labeled function as a test function.
  • Each test function establishes an expected value and runs the corresponding function to get the actual value.
  • Finally, test functions use self.assertEqual (or other assert functions provided by the unit testing module) to verify correctness.
  • Normally, self.assertEqual takes two arguments: the first is the expected result, the second is the actual result.

Running Unit Test in Thonny

  • Create a new Python file in Thonny using the example code from basic_math.py above. Save the file.
  • Create a test file from the test code above called test_basic_math.py in the same directory.
  • Press the green play button in Thonny to run test_basic_math.py.
  • You should see something like this: 
    ----------------------------------------------------------------------
    Ran 2 tests in 0.000s

    OK
  • Now go back and "break" the code by changing the basic_math.add function: return sum + 1
  • Compile the new code, and then press the play button. What happens when an assertion fails?

Part 2: Writing Basic Test functions

  • Implement the following functions in your basic_math file:
    • multiply(x, y)
    • divide(x, y)
  • Now write the corresponding test functions in test_basic_math. Use the same pattern as in test_add and test_subtract: establish an expected result and an actual result, then compare the two with an assertion.
  • Run your new tests to validate the new functions. Then introduce errors into the new functions, just as you did before with the add function, and run the tests again to see if they are really working.

It's generally not enough to test a function just once. To be sure that the function is correct, we need to test multiple times with multiple values.

  • Add the following test cases to the test_add function. (Copy and paste the last three lines of test_add for each case below. For readability, separate each one with a blank line.)
    • case 1: x = 0.0, y = 0.0
    • case 2: x = -5.0, y = 3.5
  • Add two additional test cases to each of the other three test functions. Determine your own expected values for these functions.
  • Submit only basic_math.py through https://gradescope.com.  The test_basic_math.py will not be graded for the lab.

 

Acknowledgements: This lab was oringinally rewritten for Java by Nathan Sprague.

Back to Top