Difference between Unittest and Doctest
In this tutorial, we will discuss the difference between the doctest and unittest and see some cases. Testing is an important phase of software development, and it helps to identify an error, agile code, and code reusability. A codebase is tested with several test cases to prevent breaking and minimize exposure to vulnerability. Python provides the two main testing frameworks, doctest, and unittest. Let's get familiar with both frameworks.
Introduction to Doctest
Doctest is an in-built framework which means it comes with the Python installation, or we don't need to install it separately. The doctest module is used to identify and execute code snippets that mimic interactive Python sessions, and it tests to ensure that the results match the expected output as described. The doctest is most commonly used to test the documentation. It checks the statement sequence in a docstring, re-executes the extracted command, and compares it with the command line input in the docstring. By default, while using the doctest module, the output is not displayed when a test case passes. However, this behavior can be altered using options in the doctest runner. Moreover, the compatibility of doctest with the Python unittest framework allows us to execute doctests as regular unittest test cases. If you want to learn more about the doctest module, you can check our Python Doctest Module tutorial.
Introduction to Unittest
The test runners in unittest provide additional options when executing test cases, including the ability to generate statistics reports on the results, including the number of test cases that have passed and failed. In the unittest, the methods created in the class manage the tests. It supports the setup, automation, and shutdown code when testing. It comes with various in-built, rich features, including generators and group fixture managers that are not included in the doctest.
Since that unittest follows an object-oriented approach, it is better suited for testing class-based methods in a non-production environment. On the other hand, continuous delivery tools such as Jenkins or Travis CI are more appropriate for production environments. In the following sections, we will demonstrate a real-world example of code that deals with employee information and their efs on salary and test it using both doctest and unittest. After conducting the tests, we will evaluate the results and suggest ways to enhance the testing process further.
Coding Example - Using Unittest
Let's implement the Employee class and create some methods to tests using the unittest. Let's see the following code.
In the above code, we import the unittest from the Python package and import the Employee class. In the TestEmployee class, we use the "TestCase" from unittest as it allows us to verify specific outputs for each set of inputs. We then design three separate tests using methods that start with the "test" prefix. The "test" prefix signals the test runner to identify which methods to run as tests.
In the above code, we import the unittest from the Python package and import the Employee class. In the TestEmployee class, we use the "TestCase" from unittest as it provides us with the ability to verify specific outputs for each set of inputs. We then design three separate tests using methods that start with the "test" prefix. The "test" prefix signals the test runner to identify which methods to run as tests.
The setUp() method is executed before any other test method, and it is where we create instances of the customer. We use the assertEqual() method from the assert() method to compare expected results with actual results in each of the test methods. When we run the above test, we get the following result.
... ---------------------------------------------------------------------- Ran 3 tests in 0.001s OK
If we make alter the expected output, we will see the following result.
C:\Users\User\Desktop\my_project\unittest>python test_employee.py F.. ====================================================================== FAIL: test_apply_epf (__main__.TestEmployee) ---------------------------------------------------------------------- Traceback (most recent call last): File "test_employee.py", line 22, in test_apply_epf self.assertEqual(self.employee_1.salary, 47500) AssertionError: 475000 != 47500 ---------------------------------------------------------------------- Ran 3 tests in 0.001s FAILED (failures=1)
This type of testing allows for quick identification of bugs and helps pinpoint where in the code the error occurs. By utilizing unittest and crafting tests that encompass all possible scenarios, we can enhance our program's clarity, functionality, and logical flow.
Compared to unittest, using doctest is simpler and requires fewer steps. Despite its ease of use, it is important to exercise caution when utilizing a doctest, as it has certain limitations.
Let's now demonstrate the previous example using doctest.
Now, we will perform the following operations in the terminal.
We run the python doctest_employee -v command in the terminal and it returns the following output.
Trying: employee_1 = Employee("John", "Brad", 5000) Expecting nothing ok Trying: employee_2 = Employee("Tina", "Smith", 3000) Expecting nothing ok Trying: employee_1.employee_mail() Expecting: '[email protected]' ok Trying: employee_2.employee_mail() Expecting: '[email protected]' ok Trying: employee_1.employee_fullname() Expecting: 'John Brad' ok Trying: employee_2.employee_fullname() Expecting: 'Tina Smith' ok Trying: employee_1.apply_epf() Expecting: 4750 ok Trying: employee_2.apply_epf() Expecting: 2850 ok 5 items had no tests: __main__ __main__.employee.__init__ __main__.employee.apply_epf __main__.employee.employee_fullname __main__.employee.employee_mail 1 items passed all tests: 8 tests in __main__.employee 8 tests in 6 items. 8 passed and 0 failed. Test passed.
As we can see in the above output, all tests are passed. The doctest makes it easy and more suitable for writing executable documentation for a package while the unittest is better suited for testing documentation.
This tutorial included the difference between doctest and unittest. The unittest framework provides an object-oriented method for testing code, including features such as automation, setup, and tear down of test code. On the other hand, doctest is more appropriate for documentation as it can be embedded within the code's docstrings.
Next TopicImage Filter with Python | OpenCV