Tuesday, November 26, 2013

Unit test for Python

As a sort of hello world for Python (2.7.5+), I write here a function that calculate the distance between two points in a Cartesian plane. However, the most interesting part of the post is seeing how easy (and fun) is to integrate the code with unittest, the official Python module that implements unit testing framework, also known as PyUnit. I firstly write a minimal version for my function, that actually works fine in the case the segment that I want to measure has collapsed to a single point:
def distance(ax, ay, bx, by):
    return 0.0
If you haven't seen any Python code before, you would probably appreciate its syntheticity. No need of specifying variable (and function) type, no need of much more than the strict necessity. Notice the colon after the function prototype, that says its body is about to start, and notice the mandatory indentation (four blanks is its traditional span) for the code owned by the block. Writing test cases for this function, requires us to import the module unittest and define a class that derives from its TestCase class. Besides, I need also to import the math module, so that I could use its sqrt() function. Finally we just need to add a new method for each test case we want to create:
import unittest
import math


class Tests(unittest.TestCase):
    def test_zero(self):
        dist = distance(0, 0, 0, 0)
        self.assertEqual(0, dist)

    def test_sqr2(self):
        dist = distance(0, 0, 1, 1)
        self.assertEqual(math.sqrt(2), dist)

    def test_sqr8(self):
        dist = distance(0, 0, 2, 2)
        self.assertEqual(math.sqrt(8), dist)
Each test case calls my distance() function, and then asserts that its result has the expected value. Running the test, you should get a success, test_zero, and two failures. Now it is easy to refactor the function to get a better result:
import math


def distance(ax, ay, bx, by):
    return math.sqrt((bx - ax) ** 2 + (by - ay) ** 2)
As you can see, double-star is the Python operator square. The usual precedence rules apply for mathematical operators. Given this distance() implementation, you should get a full success for the above tests.

No comments:

Post a Comment