martes, 22 de octubre de 2013

The Python unit testing framework

The PyUnit is a unit testing framework, which is a Python implementation of famous JUnit, which is the de facto standard unit testing framework for its different language.

Python implements this standard unit testing with the module unittest.

Firstly, a piece of theory on testing

 In order to design a comprehensive testing plan we want to take advantage of the following types of tests:

unit-testing
    Testing done on a single subroutine or module.
functional-testing
    Testing for a given functional group of subroutines or modules, for example, testing model dynamics alone without the model physics.
system-testing
    Testing done on the whole system.

In particular,  proper unit-tests will do the following:
  •     Applicable requirements are checked.
  •     Exercise every line of code.
  •     Check that the full range of possible input data works.
  •     Boundary analysis - logical statements that refer to threshold states are checked to ensure they are correct.
  •     Check for bad input data.
A test case in Python is created by subclassing unittest.TestCase.
 - a setUp() method is defined, the test runner will run that method prior to each test.
 - a tearDown() method is defined, the test runner will invoke that method after each test. I

Main assert functions:
  1. assertEqual(a, b)     a == b    
  2. assertNotEqual(a, b)     a != b    
  3. assertTrue(x)     bool(x) is True    
  4. assertFalse(x)     bool(x) is False
Tthere are another assert function, and in particular in the following example we are going to use to test assert raised (assertRaises)

A suite is a group of test cases.

Finally, we are going to show an example of an independet class (TestKelvinToFahrenheit) that performeces the unit tests

  •  File kelvinToFahrenheitFunctions.py - Function to be tested

1
2
3
def KelvinToFahrenheit(Temperature):
    assert (Temperature >= 0), "Colder than absolute zero!"
    return ((Temperature - 273) * 1.8) + 32

  • File kelvinToFahrenheit.py Main function that only prints different values

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
#!/usr/bin/env python
  
import kelvinToFahrenheitFunctions as k2f

if __name__ == '__main__':
    print k2f.KelvinToFahrenheit(273)
    print k2f.KelvinToFahrenheit(104)
    print k2f.KelvinToFahrenheit(454)
    print int(k2f.KelvinToFahrenheit(505.78))
    print k2f.KelvinToFahrenheit(-5)

  • File TestKelvinToFahrenheit.py - Independent class and file to testing function kelvinToFahrenheit

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#!/usr/bin/env python

import unittest
import math

import kelvinToFahrenheitFunctions as k2f

class TestKelvinToFahrenheit (unittest.TestCase):
    # Test positive value, for instance 104 and 454
    def test_positive_value (self):
        fahr_temp = k2f.KelvinToFahrenheit(104)
        self.assertEqual(fahr_temp, -272.2)
        fahr_temp = k2f.KelvinToFahrenheit(454)
        self.assertEqual(fahr_temp, 357.8)

    # Test boundary value 273 and 0
    def test_boundary_value (self):
        fahr_temp = k2f.KelvinToFahrenheit(273)
        self.assertEqual(fahr_temp, 32)
        fahr_temp = math.ceil(k2f.KelvinToFahrenheit(255.22))
        self.assertEqual(fahr_temp, 0)

    # Test assert raises, in this case colder than absolute zero
    # something impossible.
    def test_colder_abs_zero (self):
        self.assertRaises(AssertionError,
                            k2f.KelvinToFahrenheit,
                            - 1)

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

The output would be

$ ./TestKelvinToFahrenheit.py

...

----------------------------------------------------------------------

Ran 3 tests in 0.001s

OK

and with the --verbose option


$ ./TestKelvinToFahrenheit.py --verbose

test_boundary_value (__main__.TestKelvinToFahrenheit) ... ok

test_colder_abs_zero (__main__.TestKelvinToFahrenheit) ... ok

test_positive_value (__main__.TestKelvinToFahrenheit) ... ok

----------------------------------------------------------------------

Ran 3 tests in 0.001s

OK

OK


References:
[1] http://docs.python.org/3.3/library/unittest.html
[2] http://www.cesm.ucar.edu/working_groups/Software/dev_guide/dev_guide/node13.html
[3] http://blog.stevensanderson.com/2009/08/24/writing-great-unit-tests-best-and-worst-practises/
[4] http://stackoverflow.com/questions/129507/how-do-you-test-that-a-python-function-throws-an-exception


2 comentarios:

  1. Unit Software Testing = The unit testing features of Visual Studio 2012 were shown to be an effective way to improve software quality by introducing various tests.

    ResponderEliminar
  2. Thanks Sandeep for the information, but I don't use privative software.
    Best regards,
    Jose

    ResponderEliminar