A concise guide to writing unit tests, mocking, and measuring test coverage in Python using unittest library.
Unit testing ensures code reliability. This guide covers:
✅ Writing unit tests with unittest
✅ Mocking dependencies
✅ Measuring test coverage
📂 Project Structure
Organize test cases effectively:
project_root/
│── src/
│ ├── utils.py # Utility functions
│ ├── operations.py # Business logic
│── tests/
│ ├── test_operations.py # Test cases
✅ Writing Tests
📌 src/operations.py
def add(a, b):
return a + b
📌 tests/test_operations.py
import unittest
from src.operations import add
class TestMathOperations(unittest.TestCase):
def test_add(self):
self.assertEqual(add(5, -12), -7)
if __name__ == "__main__":
unittest.main()
Run tests:
python -m unittest discover -s tests
🔄 Setup & Teardown
import unittest
from io import StringIO
from src.utils import say_hello
from unittest.mock import patch
class TestGreetings(unittest.TestCase):
def setUp(self):
print("SETUP")
def tearDown(self):
print("TEARDOWN")
def test_say_hello(self):
with patch('sys.stdout', new=StringIO()) as fake_out:
say_hello()
self.assertEqual(fake_out.getvalue().strip(), "Hello World")
🔍 Mocking with unittest.mock
# src/data_fetcher.py
def get_status():
return "Live"
def fetch_data():
return {"status": get_status()}
# tests/test_data_fetcher.py
import unittest
from unittest.mock import patch
from src.data_fetcher import fetch_data
class TestDataFetcher(unittest.TestCase):
@patch("src.data_fetcher.get_status")
def test_fetch_data(self, mock_get_status):
mock_get_status.return_value = "Mocked Status"
self.assertDictEqual(fetch_data(), {"status": "Mocked Status"})
Run tests:
python -m unittest tests.test_data_fetcher
📈 Measuring Test Coverage
pip install coverage
coverage run -m unittest discover -s tests
coverage html # Generates an HTML report
View htmlcov/index.html
for insights.
🚀 Conclusion
unittest
helps write reliable tests. Use mocking to isolate dependencies and coverage to track completeness.
Start writing better tests today! 🧪✨