Unit Testing Basics: Automating Code Quality in Python
Learn how to use Python's unittest module to automate code verification. Master writing test cases and running suites to ensure long-term code reliability.

Previously in this course, we covered Advanced Error Handling to manage runtime failures. While error handling manages what happens when things go wrong, unit testing is how we proactively ensure our code behaves exactly as we expect under normal and edge conditions.
In professional backend development, you never assume your code works just because it ran once. You prove it through automated tests.
What is Unit Testing?
Unit testing is the practice of testing the smallest "units" of your code—usually individual functions or methods—in isolation. By verifying that a single function returns the correct output for a given input, you build a foundation of confidence. If you change your code later, running your test suite ensures you haven't accidentally broken existing functionality.
Getting Started with unittest
Python includes a powerful, built-in library called unittest. It follows an object-oriented approach where you define test classes that inherit from unittest.TestCase.
The Anatomy of a Test
A test case follows a simple pattern:
- Arrange: Set up the data or objects needed.
- Act: Call the function you are testing.
- Assert: Verify that the actual output matches your expected result.
Let’s apply this to our ongoing project. Suppose we have a utility function in math_utils.py that calculates the percentage of a total.
PYTHON# math_utils.py def calculate_percentage(part, total): if total == 0: return 0 return (part / total) * 100
Now, let's create a test file named test_math_utils.py.
PYTHONimport unittest from math_utils import calculate_percentage class TestMathUtils(unittest.TestCase): def test_calculate_percentage(self): # Arrange part = 50 total = 200 expected = 25.0 # Act result = calculate_percentage(part, total) # Assert self.assertEqual(result, expected) def test_zero_division(self): self.assertEqual(calculate_percentage(10, 0), 0) if __name__ == CE9178">'__main__': unittest.main()
Running Your Test Suite
To run your tests, simply execute the file from your terminal:
Bashpython test_math_utils.py
The unittest module will discover any method starting with the word test and run it. You will see a dot . for every successful test. If a test fails, unittest will provide a detailed report showing exactly what went wrong.
Why Quality Assurance Matters
If you're serious about building production-ready systems, you'll eventually want to dive into techniques like Equivalence Partitioning to optimize your testing efficiency. As your project scales, remember that Writing Failing Unit Tests First can act as a specification for your features, effectively documenting how your code should behave.
Practice Exercise
Create a new file called string_utils.py containing a function format_name(first, last) that returns a string in the format "Last, First". Then, create a test_string_utils.py file. Write at least two test cases: one for a standard name and one for a name with empty strings. Run the test suite and confirm both pass.
Common Pitfalls
- Forgetting the
test_prefix:unittestonly automatically discovers methods that start withtest_. If you name your methodcheck_math, it will be ignored silently. - Testing too much at once: A unit test should test one behavior. If your test is complex or involves multiple functions, it becomes harder to debug when it fails.
- Ignoring edge cases: Always test "boundary" conditions—like zero values, empty lists, or
None—not just the "happy path" where everything goes right.
FAQ
Q: Should I test every single line of code? A: Aim for high coverage, but focus on the logic that is prone to breaking. Improving Test Coverage: A Strategic Guide for Engineers can help you prioritize where your tests add the most value.
Q: What is the difference between unittest and pytest?
A: unittest is built into Python. pytest is a popular third-party library that is more concise and feature-rich. Start with unittest to understand the fundamentals; move to pytest once you are comfortable.
Q: Can I run tests in my CI/CD pipeline? A: Absolutely. Automated testing is the primary gatekeeper for quality in professional deployments.
Recap
We've moved from writing scripts that "just run" to verifying them with unittest. You now know how to structure test classes, use assertions to validate outcomes, and execute your test suite. This discipline is the first step toward professional software engineering.
Up next: We'll explore Test-Driven Development (TDD), where we write our tests before the code to ensure our requirements are met from the start.



