Back to Blog
Lesson 41 of the Python: Programming from Zero with Python course
PythonAugust 28, 20264 min read

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.

pythonunit testingunittestprogrammingsoftware engineeringquality assurance
Close-up view of a developer typing code on a keyboard with a computer screen showing scripts.

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:

  1. Arrange: Set up the data or objects needed.
  2. Act: Call the function you are testing.
  3. 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.

PYTHON
import 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:

Bash
python 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: unittest only automatically discovers methods that start with test_. If you name your method check_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.

Similar Posts