Monday, November 30, 2020

Python unittest intro

The unittest test framework is python’s xUnit style framework.

It is a standard module that you already have if you’ve got python version 2.1 or greater.



Overview of unittest

The unittest module used to be called PyUnit, due to it’s legacy as a xUnit style framework.

It works much the same as the other styles of xUnit, and if you’re familiar with unit testing in other languages, this framework (or derived versions), may be the most comfortable for you.


The standard workflow is:

1. You define your own class derived from unittest.TestCase.

2. Then you fill it with functions that start with ‘test_’.

3. You run the tests by placing unittest.main() in your file, usually at the bottom.



One of the many benifits of unittest, that you’ll use when your tests get bigger than the toy examples I’m showing on this blog, is the use of ‘setUp’ and ‘tearDown’ functions to get your system ready for the tests.


test_um_unittest.py:


import unittest

from unnecessary_math import multiply


class TestUM(unittest.TestCase):


    def setUp(self):

        pass


    def test_numbers_3_4(self):

        self.assertEqual( multiply(3,4), 12)


    def test_strings_a_3(self):

        self.assertEqual( multiply('a',3), 'aaa')


if __name__ == '__main__':

    unittest.main()


In this example, I’ve used assertEqual(). The unittest framework has a whole bunch of assertBlah() style functions like assertEqual(). Once you have a reasonable reference for all of the assert functions bookmarked, working with unnittest is pretty powerful and easy.


Aside from the tests you write, most of what you need to do can be accomplished with the test fixture methods such as setUp, tearDown, setUpClass, tearDownClass, etc.


Running unittests

At the bottom of the test file, we have this code:



if __name__ == '__main__':

    unittest.main()


This allows us to run all of the test code just by running the file.

Running it with no options is the most terse, and running with a ‘-v’ is more verbose, showing which tests

ran.



> python test_um_unittest.py

..

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

Ran 2 tests in 0.000s


OK

> python test_um_unittest.py -v

test_numbers_3_4 (__main__.TestUM) ... ok

test_strings_a_3 (__main__.TestUM) ... ok


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

Ran 2 tests in 0.000s


OK



Test discovery

Let’s say that you’ve got a bunch of test files. It would be annoying to have to run each test file separately. That’s where test discovery comes in handy.


In our case, all of my test code (one file for now) is in ‘simple_example’.

To run all of the unittests in there, use python -m unittest discover simple_example, with or without the ‘-v’, like this:




> python -m unittest discover simple_example

..

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

Ran 2 tests in 0.000s


OK

> python -m unittest discover -v simple_example

test_numbers_3_4 (test_um_unittest.TestUM) ... ok

test_strings_a_3 (test_um_unittest.TestUM) ... ok


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

Ran 2 tests in 0.000s


OK




References:

https://pythontesting.net/framework/unittest/unittest-introduction/

No comments:

Post a Comment