Every piece of software is expected to be properly tested when the development process is completed to detect and fix bugs. There are countless ways to do that. Manual testing is the easiest way to check if a piece of software works the way it was supposed to. Even though it is an easy way to test it, it is definitely not the most efficient one. It is impractical, prone to errors, and due to a human error not accurate at all times. With manual testing, every piece of software needs to be tested over and over again by the developer, which can be very tedious and time-consuming. To avoid redundancy, unit testing can be used to automate the process for us and make the manual tests more efficient.
Through unit testing, we are able to test if the code we have written works as we intended. The primary focus is to test whether an individual unit (smallest piece of code which can be tested) such as a method or function is working well in isolation. A unit’s actual behavior is being compared with the expected behavior and based on the outcome the test is set to either pass or fail. It is on us to decide if we want the test for a specific outcome to pass or fail. Each test needs to be written only once and can be run countless times to check if the piece of software is working well and to determine how well it reacts to valid or invalid input. With this approach, we are able to efficiently detect and fix bugs earlier which will eventually lead to reduced costs.
How to write a Test Case in Python
Python has a built-in unit testing framework called unittest that has tools for writing and running tests. In order for the test runner to tell apart which methods represent an individual test from regular methods, test methods must be defined with the names starting with the letters ‘test’.
The following examples show a diagram or structure of a new test case class called Example which inherits from unittest.TestCase and code implemented in Python that follows the same structure.
The diagram shows how Example behaves when executed. The setUpClass and tearDownClass methods are defined as class methods in order to be invoked only once for the whole class. Both hold instructions to be executed, setUpClass will run the instructions before all tests are executed and tearDownClass will run it after.
The next method to be invoked after the setUpClass is the setUp method. This method runs before each test method, in this case, testA and testB. The tearDown method runs after each test method. Same as with the previous class methods they both also hold instructions to be executed before and after each test.
Both test methods, testA, and testB get executed in order. They have different test cases that are using assertions to validate the unit’s actual behavior against the expected behavior. The testA method calls the assertEqual method to check for an expected result or outcome. The testB method calls the assertTrue and assertFalse methods to verify a condition.
At the end, when all test methods are successfully executed, the tearDown method will run once more before the tearDownClass that will execute some final instructions.
Run the code with an interactive Python interpreter
The following example shows the output of the Example class when it is run in VS Code. The first output shows OK which means all tests have successfully passed. The dots signify a test has passed successfully. We can also see the order in which the methods were called thanks to the print methods we previously used in all methods.
|
To show how it would look if the test had failed instead of passing, we made some small modifications to our test method testA to introduce a failure. The output shows FAILED which means some of the tests have failed. At the top of the output we can see which test has failed, and it is testA. From the output, we can also see that two tests were run with one failure.
|
To sum up, unit testing is a useful tool when correctly implemented to quickly catch and fix bugs during development. Certain methods should always be implemented for the automation to work. All tests can then be run whenever we want to. By running the tests frequently we will be able to catch errors or bugs and improve the overall quality of our code. With that, unit testing is giving us some reassurance that the code we are working on will behave as we want it to, and it is safe to say that for that alone, it is worth the effort to learn it.
© – Gravity Vector