How to Test Python Code: A Beginner’s Guide with Examples

You’ve written some Python code and it seems to work. But how do you really know it works correctly? What happens when someone uses it differently than you expected? Testing Python code isn’t just for professionals at big tech companies — it’s an essential skill every Python programmer needs to learn. Good testing catches bugs before they cause problems, makes your code more reliable, and actually saves you time in the long run. Whether you’re building a simple script or a complex application, knowing how to test Python code properly will make you a better developer. In this guide, we’ll walk through practical testing methods with real code examples that you can use today.

Why Testing Python Code Matters?

Before we jump into the how, let’s talk about the why. Testing isn’t extra work; it’s insurance for your code.

Benefits of testing Python code:

  • Catch bugs before users find them
  • Feel confident when making changes to existing code
  • Document how your code should work
  • Make your code easier to maintain
  • Save debugging time in the future

Think of testing like proofreading an important email before sending it. A few minutes checking now prevents embarrassment later.

Manual Testing: The Simplest Way to Start

When you’re learning how to test Python code, manual testing is where everyone begins. It’s simple: run your code with different inputs and check if the output is correct.

Example of manual testing:

def add_numbers(a, b):

return a + b

# Manual testing

print(add_numbers(2, 3))  # Should print 5

print(add_numbers(-1, 1))  # Should print 0

print(add_numbers(0, 0))  # Should print 0

Manual testing works for small projects, but it has problems:

  • You have to remember to test everything each time you change code
  • It’s slow and boring
  • Easy to forget edge cases
  • No record of what you’ve tested

That’s why we need better methods for testing Python code.

Using Print Statements for Quick Testing

Print statements are the most basic debugging tool, and they’re useful for quick testing while you’re writing code.

Example:

def calculate_discount(price, discount_percent):

print(f”Price: {price}, Discount: {discount_percent}%”)  # Debug line

discount_amount = price * (discount_percent / 100)

print(f”Discount amount: {discount_amount}”)  # Debug line

final_price = price – discount_amount

return final_price

result = calculate_discount(100, 20)

print(f”Final price: {result}”)

Print statements help you see what’s happening inside your code. But they’re messy — you have to remove them later, and they clutter your output.

Assert Statements: Simple Built-in Testing

Python has a built-in way to test code: assert statements. These check if something is true, and raise an error if it’s not.

 

Basic assert example:

def multiply(x, y):

return x * y

# Test using assert

assert multiply(3, 4) == 12, “3 times 4 should equal 12”

assert multiply(0, 100) == 0, “Anything times 0 should be 0”

assert multiply(-2, 3) == -6, “Should handle negative numbers”

print(“All tests passed!”)

If any assert fails, Python stops and shows an error. This is better than print statements because:

  • Tests fail loudly when something’s wrong
  • Your code doesn’t run if tests fail
  • You can see exactly which test broke

Introduction to unittest: Python’s Built-in Testing Framework

For serious testing Python code, you need a proper testing framework. Python comes with unittest built-in — no installation needed.

Simple unittest example:

import unittest

def is_even(number):

return number % 2 == 0

class TestEvenNumbers(unittest.TestCase):

def test_positive_even_number(self):

self.assertTrue(is_even(4))

def test_positive_odd_number(self):

self.assertFalse(is_even(5))

 

def test_zero(self):

self.assertTrue(is_even(0))

def test_negative_even(self):

self.assertTrue(is_even(-2))

if __name__ == ‘__main__’:

unittest.main()

When you run this, unittest runs all your tests and shows you which passed and which failed. It’s organized and professional.

Testing with pytest: The Popular Alternative

While unittest is built-in, many developers prefer pytest because it’s simpler and more powerful. You’ll need to install it first:

pip install pytest

Same tests using pytest:

def is_even(number):

return number % 2 == 0

 

def test_positive_even_number():

assert is_even(4) == True

 

def test_positive_odd_number():

assert is_even(5) == False

 

def test_zero():

assert is_even(0) == True

 

def test_negative_even():

assert is_even(-2) == True

Notice how pytest is simpler? No classes needed, just functions that start with test_. Run it with:

pytest test_file.py

Testing Different Types of Functions

Different functions need different testing approaches. Here’s how to test common scenarios:

Testing Functions with Return Values

def greet(name):

return f”Hello, {name}!”

def test_greet():

assert greet(“Alice”) == “Hello, Alice!”

assert greet(“”) == “Hello, !”

assert greet(“123”) == “Hello, 123!”

Testing Functions That Modify Data

def add_item_to_list(items_list, item):

items_list.append(item)

return items_list

 

def test_add_item():

test_list = [1, 2, 3]

result = add_item_to_list(test_list, 4)

assert 4 in result

assert len(result) == 4

Testing Functions That Raise Errors

 

def divide(a, b):

if b == 0:

raise ValueError(“Cannot divide by zero”)

return a / b

 

def test_divide_by_zero():

import pytest

with pytest.raises(ValueError):

divide(10, 0)

How to Structure Your Test Files?

Keep your tests organized so they’re easy to find and run.

Good project structure:

my_project/

main.py

calculator.py

tests/

test_calculator.py

test_main.py

Naming conventions for testing Python code:

  • Test files should start with test_
  • Test functions should start with test_
  • Use descriptive names: test_addition_with_positive_numbers

This makes it easy to run all tests at once and find specific tests later.

Testing Edge Cases and Boundary Conditions

Good testing doesn’t just check if your code works with normal inputs. Test the weird stuff too.

Common edge cases to test:

  • Empty inputs (empty strings, empty lists)
  • Zero values
  • Negative numbers
  • Very large numbers
  • Null or None values
  • Duplicate values

Example with edge cases:

def get_first_item(items):

return items[0]

 

def test_get_first_item():

# Normal case

assert get_first_item([1, 2, 3]) == 1

 

# Edge case: single item

assert get_first_item([5]) == 5

 

# Edge case: empty list should raise error

import pytest

with pytest.raises(IndexError):

get_first_item([])

Running Your Tests Automatically

The real power of testing Python code comes from running tests automatically every time you change something.

Run all tests in a directory:

# Using pytest

pytest tests/

 

# Using unittest

python -m unittest discover tests/

You can even set up your code editor to run tests automatically when you save a file. This catches problems instantly.

Common Testing Mistakes to Avoid

When learning how to test Python code, everyone makes these mistakes:

Testing mistakes:

  • Testing too little (only happy path, no edge cases)
  • Testing too much (testing Python built-ins that already work)
  • Tests that depend on each other
  • Tests that change based on time or random values
  • Not testing error conditions

Good testing practices:

  • Each test should be independent
  • Tests should run the same way every time
  • Test one thing per test function
  • Use clear, descriptive test names
  • Keep tests simple and readable

How Much Testing Is Enough?

You don’t need to test every single line, but you should test:

  • All your important functions
  • Any complex logic or calculations
  • Error handling and edge cases
  • Code that’s caused bugs before

A good goal is 70-80% code coverage, meaning your tests run 70-80% of your code lines. You can check coverage with:

pip install pytest-cov

pytest –cov=my_project tests/

Conclusion

Testing Python code doesn’t have to be complicated. Start simple with assert statements, then move to unittest or pytest as your projects grow. Write tests for your important functions, include edge cases, and run tests regularly. Good testing catches bugs early, makes your code more reliable, and gives you confidence to make changes without breaking things. The time you spend testing today saves hours of debugging tomorrow. Start small, test often, and watch your code quality improve.

 

Leave a Comment

Your email address will not be published.

Scroll to Top