Read And Learn
Python
Chapter 8: Testing, Debugging & Code Quality
An In-Depth Comprehensive Guide for Beginners
1. The Importance of Testing
As your Python programs grow in complexity, the probability of introducing bugs
increases exponentially. Testing is the practice of writing code to verify that your
actual application code behaves as expected. Software testing is generally broken
down into several levels, with the most fundamental being Unit Testing.
Unit testing involves testing individual components of software, usually functions or
methods, in isolation. By writing unit tests, you can refactor your code with
confidence, knowing that if you break something, your tests will immediately notify
you.
2. Unit Testing with unittest
Python comes with a built-in testing framework called unittest . It requires you to
put your tests into classes as methods. To use it, you subclass
[Link] and write methods starting with the word test .
import unittest
# The function we want to test
def divide(a, b):
if b == 0:
raise ValueError("Cannot divide by zero")
return a / b
# The test case class
class TestMathFunctions([Link]):
def test_divide_normal(self):
# Assertions verify the expected outcome
[Link](divide(10, 2), 5)
[Link](divide(-10, 2), -5)
def test_divide_by_zero(self):
# Context managers can test for exceptions
with [Link](ValueError):
divide(10, 0)
if __name__ == '__main__':
[Link]()
Test Setup and Teardown
If your tests require a specific environment (like an open database connection
or a temporary file), you can use the setUp() and tearDown() methods.
setUp() runs immediately before every test method, and tearDown()
runs immediately after.
3. Professional Logging
Beginners often use the print() function to debug and track the flow of their
application. However, professional Python applications use the built-in logging
module. Logging allows you to categorize messages by severity (DEBUG, INFO,
WARNING, ERROR, CRITICAL) and direct them to different destinations (like a
console or a file).
import logging
# Configure the logging system
[Link](
level=[Link],
format='%(asctime)s - %(levelname)s - %(message)s',
filename='[Link]', # Saves to a file instead of the terminal
filemode='a'
)
[Link]("This is a debug message (ignored due to level).")
[Link]("System initialized successfully.")
[Link]("Memory usage is getting high.")
[Link]("Failed to connect to the database.")
[Link]("System crash imminent!")
4. Debugging with pdb
When you encounter a complex bug that logs and tests can't easily explain, you
need a debugger. Python includes a built-in interactive debugger called pdb
(Python Debugger). It allows you to pause the execution of your program, inspect
variables, and step through the code line by line.
def calculate_tax(total):
tax_rate = 0.05
# Insert a breakpoint. The script pauses here during execution.
import pdb; pdb.set_trace()
# In Python 3.7+, you can simply use the built-in: breakpoint()
final_amount = total + (total * tax_rate)
return final_amount
calculate_tax(100)
5. Type Hinting (PEP 484)
Python is dynamically typed, but modern Python supports Type Hints. Type hints do
not affect how the code runs, but they allow IDEs (like VSCode or PyCharm) and
static analysis tools (like mypy ) to catch type-related errors before you even run
the code.
from typing import List, Dict
# Specifying that 'name' must be a str, and the function returns a
str
def greet(name: str) -> str:
return f"Hello, {name}"
# Specifying complex data structures
def process_scores(scores: List[int]) -> Dict[str, float]:
average = sum(scores) / len(scores)
return {"average_score": average}
6. Practice Exercises
Writing robust, professional Python code requires mastering testing, logging, and
type hints. The following 45 exercises will guide you through practical scenarios.
Exercise 1: Unit Test Assertion
Problem Statement: Develop a Python script that implements unit test
assertion effectively.
Python Code Solution:
# Exercise 1: Unit Test Assertion
import unittest
def multiply(a, b): return a * b
class TestMath([Link]):
def test_mult(self):
[Link](multiply(1, 2), 2)
# [Link]()
Detailed Explanation: This exercise tests your mastery of unit test
assertion. We define a test case inheriting from [Link]. We use
[Link] to assert that our multiplication function correctly processes
the inputs and returns the exact expected mathematical output.
Exercise 2: Exception Testing
Problem Statement: Develop a Python script that implements exception
testing effectively.
Python Code Solution:
# Exercise 2: Exception Testing
import unittest
def get_item(lst, index):
return lst[index]
class TestList([Link]):
def test_bounds(self):
with [Link](IndexError):
get_item([1, 2], 7)
# [Link]()
Detailed Explanation: This exercise tests your mastery of exception testing.
Using the [Link] context manager, we instruct the test runner to
expect an IndexError. If the function successfully throws the error, the test
passes; otherwise, it fails.
Exercise 3: Logging Configuration
Problem Statement: Develop a Python script that implements logging
configuration effectively.
Python Code Solution:
# Exercise 3: Logging Configuration
import logging
[Link](level=[Link])
val = 30
[Link](f'Debugging variable state: val={val}')
[Link]('Operation finished safely.')
Detailed Explanation: This exercise tests your mastery of logging
configuration. Instead of using print(), we configure the built-in logging
module to display DEBUG level messages and above. This is the
professional standard for tracking application flow and internal states.
Exercise 4: Type Hinting
Problem Statement: Develop a Python script that implements type hinting
effectively.
Python Code Solution:
# Exercise 4: Type Hinting
from typing import List
def filter_evens(nums: List[int]) -> List[int]:
return [n for n in nums if n % 2 == 0]
res: List[int] = filter_evens([4, 5, 6])
print(res)
Detailed Explanation: This exercise tests your mastery of type hinting. We
apply PEP 484 type hints to the function arguments and return type. This
explicitly defines the expected data structures (Lists of integers), allowing
static analysis tools to catch type mismatch errors before execution.
Exercise 5: Test Setup Method
Problem Statement: Develop a Python script that implements test setup
method effectively.
Python Code Solution:
# Exercise 5: Test Setup Method
import unittest
class TestEnv([Link]):
def setUp(self):
self.test_data = [x for x in range(5)]
def test_data_length(self):
[Link](len(self.test_data), 5)
# [Link]()
Detailed Explanation: This exercise tests your mastery of test setup
method. The setUp() method is automatically called before every single test
method in the class. It is used to prepare the environment, such as opening
database connections or instantiating complex test data objects.
Exercise 6: Debugging Simulation
Problem Statement: Develop a Python script that implements debugging
simulation effectively.
Python Code Solution:
# Exercise 6: Debugging Simulation
def process_data(val):
modifier = 5
# breakpoint()
return val * modifier + 6
res = process_data(10)
print('Simulated debug output:', res)
Detailed Explanation: This exercise tests your mastery of debugging
simulation. In a live debugging scenario, inserting the built-in breakpoint()
function (or import pdb; pdb.set_trace()) pauses the script. This drops the
developer into an interactive console to manually inspect the values of
'modifier' and 'val'.
Exercise 7: Unit Test Assertion
Problem Statement: Develop a Python script that implements unit test
assertion effectively.
Python Code Solution:
# Exercise 7: Unit Test Assertion
import unittest
def multiply(a, b): return a * b
class TestMath([Link]):
def test_mult(self):
[Link](multiply(7, 2), 14)
# [Link]()
Detailed Explanation: This exercise tests your mastery of unit test
assertion. We define a test case inheriting from [Link]. We use
[Link] to assert that our multiplication function correctly processes
the inputs and returns the exact expected mathematical output.
Exercise 8: Exception Testing
Problem Statement: Develop a Python script that implements exception
testing effectively.
Python Code Solution:
# Exercise 8: Exception Testing
import unittest
def get_item(lst, index):
return lst[index]
class TestList([Link]):
def test_bounds(self):
with [Link](IndexError):
get_item([1, 2], 13)
# [Link]()
Detailed Explanation: This exercise tests your mastery of exception testing.
Using the [Link] context manager, we instruct the test runner to
expect an IndexError. If the function successfully throws the error, the test
passes; otherwise, it fails.
Exercise 9: Logging Configuration
Problem Statement: Develop a Python script that implements logging
configuration effectively.
Python Code Solution:
# Exercise 9: Logging Configuration
import logging
[Link](level=[Link])
val = 90
[Link](f'Debugging variable state: val={val}')
[Link]('Operation finished safely.')
Detailed Explanation: This exercise tests your mastery of logging
configuration. Instead of using print(), we configure the built-in logging
module to display DEBUG level messages and above. This is the
professional standard for tracking application flow and internal states.
Exercise 10: Type Hinting
Problem Statement: Develop a Python script that implements type hinting
effectively.
Python Code Solution:
# Exercise 10: Type Hinting
from typing import List
def filter_evens(nums: List[int]) -> List[int]:
return [n for n in nums if n % 2 == 0]
res: List[int] = filter_evens([10, 11, 12])
print(res)
Detailed Explanation: This exercise tests your mastery of type hinting. We
apply PEP 484 type hints to the function arguments and return type. This
explicitly defines the expected data structures (Lists of integers), allowing
static analysis tools to catch type mismatch errors before execution.
Exercise 11: Test Setup Method
Problem Statement: Develop a Python script that implements test setup
method effectively.
Python Code Solution:
# Exercise 11: Test Setup Method
import unittest
class TestEnv([Link]):
def setUp(self):
self.test_data = [x for x in range(11)]
def test_data_length(self):
[Link](len(self.test_data), 11)
# [Link]()
Detailed Explanation: This exercise tests your mastery of test setup
method. The setUp() method is automatically called before every single test
method in the class. It is used to prepare the environment, such as opening
database connections or instantiating complex test data objects.
Exercise 12: Debugging Simulation
Problem Statement: Develop a Python script that implements debugging
simulation effectively.
Python Code Solution:
# Exercise 12: Debugging Simulation
def process_data(val):
modifier = 5
# breakpoint()
return val * modifier + 12
res = process_data(10)
print('Simulated debug output:', res)
Detailed Explanation: This exercise tests your mastery of debugging
simulation. In a live debugging scenario, inserting the built-in breakpoint()
function (or import pdb; pdb.set_trace()) pauses the script. This drops the
developer into an interactive console to manually inspect the values of
'modifier' and 'val'.
Exercise 13: Unit Test Assertion
Problem Statement: Develop a Python script that implements unit test
assertion effectively.
Python Code Solution:
# Exercise 13: Unit Test Assertion
import unittest
def multiply(a, b): return a * b
class TestMath([Link]):
def test_mult(self):
[Link](multiply(13, 2), 26)
# [Link]()
Detailed Explanation: This exercise tests your mastery of unit test
assertion. We define a test case inheriting from [Link]. We use
[Link] to assert that our multiplication function correctly processes
the inputs and returns the exact expected mathematical output.
Exercise 14: Exception Testing
Problem Statement: Develop a Python script that implements exception
testing effectively.
Python Code Solution:
# Exercise 14: Exception Testing
import unittest
def get_item(lst, index):
return lst[index]
class TestList([Link]):
def test_bounds(self):
with [Link](IndexError):
get_item([1, 2], 19)
# [Link]()
Detailed Explanation: This exercise tests your mastery of exception testing.
Using the [Link] context manager, we instruct the test runner to
expect an IndexError. If the function successfully throws the error, the test
passes; otherwise, it fails.
Exercise 15: Logging Configuration
Problem Statement: Develop a Python script that implements logging
configuration effectively.
Python Code Solution:
# Exercise 15: Logging Configuration
import logging
[Link](level=[Link])
val = 150
[Link](f'Debugging variable state: val={val}')
[Link]('Operation finished safely.')
Detailed Explanation: This exercise tests your mastery of logging
configuration. Instead of using print(), we configure the built-in logging
module to display DEBUG level messages and above. This is the
professional standard for tracking application flow and internal states.
Exercise 16: Type Hinting
Problem Statement: Develop a Python script that implements type hinting
effectively.
Python Code Solution:
# Exercise 16: Type Hinting
from typing import List
def filter_evens(nums: List[int]) -> List[int]:
return [n for n in nums if n % 2 == 0]
res: List[int] = filter_evens([16, 17, 18])
print(res)
Detailed Explanation: This exercise tests your mastery of type hinting. We
apply PEP 484 type hints to the function arguments and return type. This
explicitly defines the expected data structures (Lists of integers), allowing
static analysis tools to catch type mismatch errors before execution.
Exercise 17: Test Setup Method
Problem Statement: Develop a Python script that implements test setup
method effectively.
Python Code Solution:
# Exercise 17: Test Setup Method
import unittest
class TestEnv([Link]):
def setUp(self):
self.test_data = [x for x in range(17)]
def test_data_length(self):
[Link](len(self.test_data), 17)
# [Link]()
Detailed Explanation: This exercise tests your mastery of test setup
method. The setUp() method is automatically called before every single test
method in the class. It is used to prepare the environment, such as opening
database connections or instantiating complex test data objects.
Exercise 18: Debugging Simulation
Problem Statement: Develop a Python script that implements debugging
simulation effectively.
Python Code Solution:
# Exercise 18: Debugging Simulation
def process_data(val):
modifier = 5
# breakpoint()
return val * modifier + 18
res = process_data(10)
print('Simulated debug output:', res)
Detailed Explanation: This exercise tests your mastery of debugging
simulation. In a live debugging scenario, inserting the built-in breakpoint()
function (or import pdb; pdb.set_trace()) pauses the script. This drops the
developer into an interactive console to manually inspect the values of
'modifier' and 'val'.
Exercise 19: Unit Test Assertion
Problem Statement: Develop a Python script that implements unit test
assertion effectively.
Python Code Solution:
# Exercise 19: Unit Test Assertion
import unittest
def multiply(a, b): return a * b
class TestMath([Link]):
def test_mult(self):
[Link](multiply(19, 2), 38)
# [Link]()
Detailed Explanation: This exercise tests your mastery of unit test
assertion. We define a test case inheriting from [Link]. We use
[Link] to assert that our multiplication function correctly processes
the inputs and returns the exact expected mathematical output.
Exercise 20: Exception Testing
Problem Statement: Develop a Python script that implements exception
testing effectively.
Python Code Solution:
# Exercise 20: Exception Testing
import unittest
def get_item(lst, index):
return lst[index]
class TestList([Link]):
def test_bounds(self):
with [Link](IndexError):
get_item([1, 2], 25)
# [Link]()
Detailed Explanation: This exercise tests your mastery of exception testing.
Using the [Link] context manager, we instruct the test runner to
expect an IndexError. If the function successfully throws the error, the test
passes; otherwise, it fails.
Exercise 21: Logging Configuration
Problem Statement: Develop a Python script that implements logging
configuration effectively.
Python Code Solution:
# Exercise 21: Logging Configuration
import logging
[Link](level=[Link])
val = 210
[Link](f'Debugging variable state: val={val}')
[Link]('Operation finished safely.')
Detailed Explanation: This exercise tests your mastery of logging
configuration. Instead of using print(), we configure the built-in logging
module to display DEBUG level messages and above. This is the
professional standard for tracking application flow and internal states.
Exercise 22: Type Hinting
Problem Statement: Develop a Python script that implements type hinting
effectively.
Python Code Solution:
# Exercise 22: Type Hinting
from typing import List
def filter_evens(nums: List[int]) -> List[int]:
return [n for n in nums if n % 2 == 0]
res: List[int] = filter_evens([22, 23, 24])
print(res)
Detailed Explanation: This exercise tests your mastery of type hinting. We
apply PEP 484 type hints to the function arguments and return type. This
explicitly defines the expected data structures (Lists of integers), allowing
static analysis tools to catch type mismatch errors before execution.
Exercise 23: Test Setup Method
Problem Statement: Develop a Python script that implements test setup
method effectively.
Python Code Solution:
# Exercise 23: Test Setup Method
import unittest
class TestEnv([Link]):
def setUp(self):
self.test_data = [x for x in range(23)]
def test_data_length(self):
[Link](len(self.test_data), 23)
# [Link]()
Detailed Explanation: This exercise tests your mastery of test setup
method. The setUp() method is automatically called before every single test
method in the class. It is used to prepare the environment, such as opening
database connections or instantiating complex test data objects.
Exercise 24: Debugging Simulation
Problem Statement: Develop a Python script that implements debugging
simulation effectively.
Python Code Solution:
# Exercise 24: Debugging Simulation
def process_data(val):
modifier = 5
# breakpoint()
return val * modifier + 24
res = process_data(10)
print('Simulated debug output:', res)
Detailed Explanation: This exercise tests your mastery of debugging
simulation. In a live debugging scenario, inserting the built-in breakpoint()
function (or import pdb; pdb.set_trace()) pauses the script. This drops the
developer into an interactive console to manually inspect the values of
'modifier' and 'val'.
Exercise 25: Unit Test Assertion
Problem Statement: Develop a Python script that implements unit test
assertion effectively.
Python Code Solution:
# Exercise 25: Unit Test Assertion
import unittest
def multiply(a, b): return a * b
class TestMath([Link]):
def test_mult(self):
[Link](multiply(25, 2), 50)
# [Link]()
Detailed Explanation: This exercise tests your mastery of unit test
assertion. We define a test case inheriting from [Link]. We use
[Link] to assert that our multiplication function correctly processes
the inputs and returns the exact expected mathematical output.
Exercise 26: Exception Testing
Problem Statement: Develop a Python script that implements exception
testing effectively.
Python Code Solution:
# Exercise 26: Exception Testing
import unittest
def get_item(lst, index):
return lst[index]
class TestList([Link]):
def test_bounds(self):
with [Link](IndexError):
get_item([1, 2], 31)
# [Link]()
Detailed Explanation: This exercise tests your mastery of exception testing.
Using the [Link] context manager, we instruct the test runner to
expect an IndexError. If the function successfully throws the error, the test
passes; otherwise, it fails.
Exercise 27: Logging Configuration
Problem Statement: Develop a Python script that implements logging
configuration effectively.
Python Code Solution:
# Exercise 27: Logging Configuration
import logging
[Link](level=[Link])
val = 270
[Link](f'Debugging variable state: val={val}')
[Link]('Operation finished safely.')
Detailed Explanation: This exercise tests your mastery of logging
configuration. Instead of using print(), we configure the built-in logging
module to display DEBUG level messages and above. This is the
professional standard for tracking application flow and internal states.
Exercise 28: Type Hinting
Problem Statement: Develop a Python script that implements type hinting
effectively.
Python Code Solution:
# Exercise 28: Type Hinting
from typing import List
def filter_evens(nums: List[int]) -> List[int]:
return [n for n in nums if n % 2 == 0]
res: List[int] = filter_evens([28, 29, 30])
print(res)
Detailed Explanation: This exercise tests your mastery of type hinting. We
apply PEP 484 type hints to the function arguments and return type. This
explicitly defines the expected data structures (Lists of integers), allowing
static analysis tools to catch type mismatch errors before execution.
Exercise 29: Test Setup Method
Problem Statement: Develop a Python script that implements test setup
method effectively.
Python Code Solution:
# Exercise 29: Test Setup Method
import unittest
class TestEnv([Link]):
def setUp(self):
self.test_data = [x for x in range(29)]
def test_data_length(self):
[Link](len(self.test_data), 29)
# [Link]()
Detailed Explanation: This exercise tests your mastery of test setup
method. The setUp() method is automatically called before every single test
method in the class. It is used to prepare the environment, such as opening
database connections or instantiating complex test data objects.
Exercise 30: Debugging Simulation
Problem Statement: Develop a Python script that implements debugging
simulation effectively.
Python Code Solution:
# Exercise 30: Debugging Simulation
def process_data(val):
modifier = 5
# breakpoint()
return val * modifier + 30
res = process_data(10)
print('Simulated debug output:', res)
Detailed Explanation: This exercise tests your mastery of debugging
simulation. In a live debugging scenario, inserting the built-in breakpoint()
function (or import pdb; pdb.set_trace()) pauses the script. This drops the
developer into an interactive console to manually inspect the values of
'modifier' and 'val'.
Exercise 31: Unit Test Assertion
Problem Statement: Develop a Python script that implements unit test
assertion effectively.
Python Code Solution:
# Exercise 31: Unit Test Assertion
import unittest
def multiply(a, b): return a * b
class TestMath([Link]):
def test_mult(self):
[Link](multiply(31, 2), 62)
# [Link]()
Detailed Explanation: This exercise tests your mastery of unit test
assertion. We define a test case inheriting from [Link]. We use
[Link] to assert that our multiplication function correctly processes
the inputs and returns the exact expected mathematical output.
Exercise 32: Exception Testing
Problem Statement: Develop a Python script that implements exception
testing effectively.
Python Code Solution:
# Exercise 32: Exception Testing
import unittest
def get_item(lst, index):
return lst[index]
class TestList([Link]):
def test_bounds(self):
with [Link](IndexError):
get_item([1, 2], 37)
# [Link]()
Detailed Explanation: This exercise tests your mastery of exception testing.
Using the [Link] context manager, we instruct the test runner to
expect an IndexError. If the function successfully throws the error, the test
passes; otherwise, it fails.
Exercise 33: Logging Configuration
Problem Statement: Develop a Python script that implements logging
configuration effectively.
Python Code Solution:
# Exercise 33: Logging Configuration
import logging
[Link](level=[Link])
val = 330
[Link](f'Debugging variable state: val={val}')
[Link]('Operation finished safely.')
Detailed Explanation: This exercise tests your mastery of logging
configuration. Instead of using print(), we configure the built-in logging
module to display DEBUG level messages and above. This is the
professional standard for tracking application flow and internal states.
Exercise 34: Type Hinting
Problem Statement: Develop a Python script that implements type hinting
effectively.
Python Code Solution:
# Exercise 34: Type Hinting
from typing import List
def filter_evens(nums: List[int]) -> List[int]:
return [n for n in nums if n % 2 == 0]
res: List[int] = filter_evens([34, 35, 36])
print(res)
Detailed Explanation: This exercise tests your mastery of type hinting. We
apply PEP 484 type hints to the function arguments and return type. This
explicitly defines the expected data structures (Lists of integers), allowing
static analysis tools to catch type mismatch errors before execution.
Exercise 35: Test Setup Method
Problem Statement: Develop a Python script that implements test setup
method effectively.
Python Code Solution:
# Exercise 35: Test Setup Method
import unittest
class TestEnv([Link]):
def setUp(self):
self.test_data = [x for x in range(35)]
def test_data_length(self):
[Link](len(self.test_data), 35)
# [Link]()
Detailed Explanation: This exercise tests your mastery of test setup
method. The setUp() method is automatically called before every single test
method in the class. It is used to prepare the environment, such as opening
database connections or instantiating complex test data objects.
Exercise 36: Debugging Simulation
Problem Statement: Develop a Python script that implements debugging
simulation effectively.
Python Code Solution:
# Exercise 36: Debugging Simulation
def process_data(val):
modifier = 5
# breakpoint()
return val * modifier + 36
res = process_data(10)
print('Simulated debug output:', res)
Detailed Explanation: This exercise tests your mastery of debugging
simulation. In a live debugging scenario, inserting the built-in breakpoint()
function (or import pdb; pdb.set_trace()) pauses the script. This drops the
developer into an interactive console to manually inspect the values of
'modifier' and 'val'.
Exercise 37: Unit Test Assertion
Problem Statement: Develop a Python script that implements unit test
assertion effectively.
Python Code Solution:
# Exercise 37: Unit Test Assertion
import unittest
def multiply(a, b): return a * b
class TestMath([Link]):
def test_mult(self):
[Link](multiply(37, 2), 74)
# [Link]()
Detailed Explanation: This exercise tests your mastery of unit test
assertion. We define a test case inheriting from [Link]. We use
[Link] to assert that our multiplication function correctly processes
the inputs and returns the exact expected mathematical output.
Exercise 38: Exception Testing
Problem Statement: Develop a Python script that implements exception
testing effectively.
Python Code Solution:
# Exercise 38: Exception Testing
import unittest
def get_item(lst, index):
return lst[index]
class TestList([Link]):
def test_bounds(self):
with [Link](IndexError):
get_item([1, 2], 43)
# [Link]()
Detailed Explanation: This exercise tests your mastery of exception testing.
Using the [Link] context manager, we instruct the test runner to
expect an IndexError. If the function successfully throws the error, the test
passes; otherwise, it fails.
Exercise 39: Logging Configuration
Problem Statement: Develop a Python script that implements logging
configuration effectively.
Python Code Solution:
# Exercise 39: Logging Configuration
import logging
[Link](level=[Link])
val = 390
[Link](f'Debugging variable state: val={val}')
[Link]('Operation finished safely.')
Detailed Explanation: This exercise tests your mastery of logging
configuration. Instead of using print(), we configure the built-in logging
module to display DEBUG level messages and above. This is the
professional standard for tracking application flow and internal states.
Exercise 40: Type Hinting
Problem Statement: Develop a Python script that implements type hinting
effectively.
Python Code Solution:
# Exercise 40: Type Hinting
from typing import List
def filter_evens(nums: List[int]) -> List[int]:
return [n for n in nums if n % 2 == 0]
res: List[int] = filter_evens([40, 41, 42])
print(res)
Detailed Explanation: This exercise tests your mastery of type hinting. We
apply PEP 484 type hints to the function arguments and return type. This
explicitly defines the expected data structures (Lists of integers), allowing
static analysis tools to catch type mismatch errors before execution.
Exercise 41: Test Setup Method
Problem Statement: Develop a Python script that implements test setup
method effectively.
Python Code Solution:
# Exercise 41: Test Setup Method
import unittest
class TestEnv([Link]):
def setUp(self):
self.test_data = [x for x in range(41)]
def test_data_length(self):
[Link](len(self.test_data), 41)
# [Link]()
Detailed Explanation: This exercise tests your mastery of test setup
method. The setUp() method is automatically called before every single test
method in the class. It is used to prepare the environment, such as opening
database connections or instantiating complex test data objects.
Exercise 42: Debugging Simulation
Problem Statement: Develop a Python script that implements debugging
simulation effectively.
Python Code Solution:
# Exercise 42: Debugging Simulation
def process_data(val):
modifier = 5
# breakpoint()
return val * modifier + 42
res = process_data(10)
print('Simulated debug output:', res)
Detailed Explanation: This exercise tests your mastery of debugging
simulation. In a live debugging scenario, inserting the built-in breakpoint()
function (or import pdb; pdb.set_trace()) pauses the script. This drops the
developer into an interactive console to manually inspect the values of
'modifier' and 'val'.
Exercise 43: Unit Test Assertion
Problem Statement: Develop a Python script that implements unit test
assertion effectively.
Python Code Solution:
# Exercise 43: Unit Test Assertion
import unittest
def multiply(a, b): return a * b
class TestMath([Link]):
def test_mult(self):
[Link](multiply(43, 2), 86)
# [Link]()
Detailed Explanation: This exercise tests your mastery of unit test
assertion. We define a test case inheriting from [Link]. We use
[Link] to assert that our multiplication function correctly processes
the inputs and returns the exact expected mathematical output.
Exercise 44: Exception Testing
Problem Statement: Develop a Python script that implements exception
testing effectively.
Python Code Solution:
# Exercise 44: Exception Testing
import unittest
def get_item(lst, index):
return lst[index]
class TestList([Link]):
def test_bounds(self):
with [Link](IndexError):
get_item([1, 2], 49)
# [Link]()
Detailed Explanation: This exercise tests your mastery of exception testing.
Using the [Link] context manager, we instruct the test runner to
expect an IndexError. If the function successfully throws the error, the test
passes; otherwise, it fails.
Exercise 45: Logging Configuration
Problem Statement: Develop a Python script that implements logging
configuration effectively.
Python Code Solution:
# Exercise 45: Logging Configuration
import logging
[Link](level=[Link])
val = 450
[Link](f'Debugging variable state: val={val}')
[Link]('Operation finished safely.')
Detailed Explanation: This exercise tests your mastery of logging
configuration. Instead of using print(), we configure the built-in logging
module to display DEBUG level messages and above. This is the
professional standard for tracking application flow and internal states.
Conclusion
Congratulations on completing Chapter 8! You are no longer just writing scripts; you
are writing professional, production-ready software. You have learned how to
proactively prevent bugs using the unittest framework, track application health
using the logging module, inspect complex logic using pdb , and enforce
structure using Type Hinting. These are the hallmarks of a senior Python developer.