19. Testing in Python

Testing ensures that Python programs work correctly and reliably.

Benefits of testing:

  • Finds bugs early
  • Improves code quality
  • Makes maintenance easier
  • Prevents unexpected errors

Types of Testing

TypePurpose
Unit TestingTest individual functions/modules
Integration TestingTest combined components
Functional TestingTest application behavior
System TestingTest entire application

Unit Testing

Unit testing checks small units of code such as:

  • Functions
  • Methods
  • Classes

Python provides:

unittest

module for unit testing.


Example Function

def add(a, b):
return a + b

Writing Unit Test

import unittest

def add(a, b):
return a + b

class TestMath(unittest.TestCase):

def test_add(self):
self.assertEqual(add(2, 3), 5)

if __name__ == "__main__":
unittest.main()

Running Tests

Save file as:

test_math.py

Run:

python test_math.py

Common Assertion Methods

MethodPurpose
assertEqual(a, b)Check equality
assertNotEqual(a, b)Check inequality
assertTrue(x)Check true
assertFalse(x)Check false
assertIsNone(x)Check None
assertIn(a, b)Check membership

Example: Multiple Tests

import unittest

class TestString(unittest.TestCase):

def test_upper(self):
self.assertEqual(
"python".upper(),
"PYTHON"
)

def test_isdigit(self):
self.assertFalse("abc".isdigit())

if __name__ == "__main__":
unittest.main()

Setup and Teardown Methods

Used for preparing and cleaning test environment.


Example

import unittest

class TestExample(unittest.TestCase):

def setUp(self):
print("Setup executed")

def tearDown(self):
print("Teardown executed")

def test_sample(self):
self.assertEqual(1 + 1, 2)

if __name__ == "__main__":
unittest.main()

pytest

pytest is a powerful third-party testing framework.

Advantages:

  • Simpler syntax
  • Better output
  • Easy fixtures

Install pytest

pip install pytest

Simple pytest Example

def add(a, b):
return a + b

def test_add():
assert add(2, 3) == 5

Run pytest

pytest

Multiple pytest Tests

def multiply(a, b):
return a * b

def test_multiply():
assert multiply(2, 4) == 8

def test_negative():
assert multiply(-1, 5) == -5

pytest Fixtures

Fixtures provide reusable test setup.

import pytest

@pytest.fixture
def sample_data():
return [1, 2, 3]

def test_length(sample_data):
assert len(sample_data) == 3

Mocking in Python

Mocking replaces real objects with fake objects during testing.

Useful when testing:

  • APIs
  • Databases
  • External services

Python provides:

unittest.mock

Example Function

import requests

def get_data():
response = requests.get(
"https://api.example.com"
)

return response.status_code

Mocking API Request

from unittest.mock import patch
import unittest

class TestAPI(unittest.TestCase):

@patch("requests.get")
def test_get_data(self, mock_get):

mock_get.return_value.status_code = 200

import requests

response = requests.get(
"https://api.example.com"
)

self.assertEqual(
response.status_code,
200
)

if __name__ == "__main__":
unittest.main()

Mock Object Example

from unittest.mock import Mock

database = Mock()

database.get_user.return_value = {
"name": "Aditya"
}

print(database.get_user())

Debugging Techniques

Debugging helps identify and fix errors.


Using print()

Simplest debugging method.

x = 10

print("Value of x:", x)

Using pdb Debugger

Python provides built-in debugger:

pdb

Example

import pdb

x = 10
y = 0

pdb.set_trace()

print(x / y)

Common pdb Commands

CommandPurpose
nNext line
cContinue
qQuit
p variablePrint variable

Exception Traceback

Python displays traceback for errors.

def divide(a, b):
return a / b

print(divide(10, 0))

Output:

ZeroDivisionError

Logging for Debugging

Use logging instead of many print statements.


Example

import logging

logging.basicConfig(level=logging.INFO)

logging.info("Program started")

logging.warning("Warning message")

logging.error("Error occurred")

Debugging with VS Code

VS Code provides:

  • Breakpoints
  • Variable inspection
  • Step execution

Steps:

  1. Open Python file
  2. Click beside line number
  3. Press F5
  4. Start debugging

Test Coverage

Coverage measures how much code is tested.

Install coverage:

pip install coverage

Run coverage:

coverage run test_math.py
coverage report

Practical Example

Calculator Testing

import unittest

def divide(a, b):
return a / b

class TestCalculator(unittest.TestCase):

def test_divide(self):
self.assertEqual(
divide(10, 2),
5
)

def test_zero_division(self):

with self.assertRaises(
ZeroDivisionError
):

divide(10, 0)

if __name__ == "__main__":
unittest.main()

Best Practices

✅ Write small test cases
✅ Test edge cases
✅ Use mocking for external services
✅ Use logging for debugging
✅ Automate tests regularly


Summary

In this chapter you learned:

✅ Unit testing
unittest module
pytest basics
✅ Mocking
✅ Debugging techniques