26. Unit Testing with unittest
Why Unit Testing Matters
Unit tests check small, independent parts of your code (functions or classes) to ensure they work correctly. Writing tests helps catch bugs early, maintain code quality, and make future changes safer.
Getting Started with unittest
Python's `unittest` module is built-in and provides a framework to define and run tests easily.
import unittest
# Function to test
def add(a, b):
return a + b
# Test case class
class TestMath(unittest.TestCase):
def test_add(self):
self.assertEqual(add(2, 3), 5)
self.assertEqual(add(-1, 1), 0)
if __name__ == '__main__':
unittest.main()Here, `TestMath` is a test case class inheriting from `unittest.TestCase`. Each method starting with `test_` is a separate test.
Common Assertions
Assertions check if a condition holds true. Some common assertions include:
| Assertion | Description |
|---|---|
| assertEqual(a, b) | Check a == b |
| assertNotEqual(a, b) | Check a != b |
| assertTrue(x) | Check x is True |
| assertFalse(x) | Check x is False |
| assertRaises(Exception, func, *args) | Check that an exception is raised |
Setup and Teardown
Sometimes you need to prepare resources before tests and clean up after. Use `setUp()` and `tearDown()` methods.
class TestFiles(unittest.TestCase):
def setUp(self):
self.file = open('test.txt', 'w')
def test_write(self):
self.file.write('Hello')
self.file.seek(0)
self.assertEqual(self.file.read(), 'Hello')
def tearDown(self):
self.file.close()Best Practices
- Write tests for every function or class method.
- Keep tests independent of each other.
- Use descriptive test method names.
- Test both normal and edge cases.
- Run tests automatically when code changes (continuous integration).
Mini Project Step
Write a simple calculator module with functions for addition, subtraction, multiplication, and division. Create a `unittest` test suite to verify all operations, including division by zero handling.