Testing in Python

After having seen how to test in R.

Let’s see how to do the same in Python:

Writing a tests-oriented program

A good practice demand that we should try to write our test before we code the program we intended to.

At least, we can try to write the code in a way that is easier to test in the future. Trying to fight out natural tendency to write the tests after your code.

To do that try to follow these guidelines:

Guidelines

  • Use independent files:
    • One for the program, one for the test
  • Code stile for the program:
    • Atomicity:
      • A single python file for each task/objective.
      • Single functions for each step of your algorithm.
        This will help later in the test
    • A main function to be invoked. This will list all the functions (steps) of the program.
  • Tests, in and out:
    • Within the program file
      • Tests that define and check the inputs
      • Tests that define and check the outputs
    • Within the test file
      • A test with correct inputs
      • Wrong inputs
      • Exceptions

Independent Files:

  • A main.py, in this file is present the python code we are writing and we need to test.
  • A test_main.py, a file in which, we will write the tests.

main.py

In this simple program, it is present a main function (Main) that contains a series of calls to other methods.

The main, therefore, looks like a series of single steps that calls a single method, that deliver one single operation.


def __IsNameString(name):
    return isinstance(name, str)

def __add(num1, num2):
    return(num1 + num2)

def __output_print(result):
    if(result > 3):
        return('Results higher than 3')
    elif(result == 3):
        return('Results equal 3')
    else:
        raise ValueError('Result not equal to 3')


def Main(num1 = 2, num2 = 4):
    result_add = __add(num1, num2)

    output_result = __output_print(result_add)

    if __IsNameString(output_result):
        print(output_result)

test.py

Here in the test file we are going to use the package unittest that make the test process possible. This package provides a base class TestCase, that can be used to create the test.

Simply import unittest.TestCase in the class, how shown in the class TestClass. By doing so, we created what is called a testcase. In which, we can define the test methods, like test_add etch.

The most important component of the testing are the special calls like assertEqual() or assertTrue(). These calls are used to assert statement so the test runner can accumulate all test results and produce a report.

In here, I have used

  • assertEqual: This method asses if the result is equal to the one we expect.
  • assertTrue:This method asses if the result is a boolean. True in this case/
  • assertIsInstance:This method asses if the result is a class. A string in this case
  • assertRaises:This method asses if the function raises a warning or n error.
import unittest
from main import __IsNameString as isNameString
from main import __add as add
from main import __output_print as output_print

class TestClass(unittest.TestCase):

    def test_add(self):
        self.assertEqual(add(3, 4), 7)

    def test_isNameString(self):
        self.assertTrue(isNameString("test"))

    def test_output_print(self):
        self.assertIsInstance(output_print(2), str)
        self.assertIsInstance(output_print(2), str)
        with self.assertRaises(ValueError):
            output_print(3)


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

Command-Line Interface

The final block shows a simple way to run the tests. unittest.main() provides a command-line interface to the test script.

We can use the following command line

python -m unittest tests/test_[name_of_test].py

That produces an output that looks like this:


Ran 3 tests in 0.000s.

OK

Testing methods

There are many different calls that can be used for testing, here a provide a list of the one I used the most, more are present in the documentation.

MethodChecks that
assertEqual(a, b)a == b
assertNotEqual(a, b)a != b
assertTrue(x) bool(x) is True
assertFalse(x)bool(x) is False
assertIs(a, b)a is b
assertIsNot(a, b)a is not b
assertIsNone(x)x is None
assertIsNotNone(x)x is not None
assertIn(a, b)a in b
assertNotIn(a, b)a not in b
assertIsInstance(a, b)isinstance(a, b)
assertNotIsInstance(a, b)not isinstance(a, b)
assertRaises(exc, fun, *args, **kwds)fun(*args, **kwds) raises exc
assertWarns(warn, fun, *args, **kwds)fun(*args, **kwds) raises warn

Leave a Reply

Your email address will not be published. Required fields are marked *