The previous class involved writing a Python program to find unique combinations of 3 numbers from a list that sum to a target number.
The task included providing doctests for specific test cases.
Example:
List: [1, 2, 3, 4, 5, 6, 7, 8, 9]
Target: 12
Combinations: [(1, 3, 8), (1, 4, 7), (1, 2, 9), (1, 5, 6), (3, 4, 5), (2, 3, 7), (2, 4, 6)]
Example:
List: [1, 2, 3, 4, 5, 6, 7, 8, 9]
Target: 17
Combinations: [(4, 5, 8), (2, 6, 9), (3, 5, 9), (2, 7, 8), (4, 6, 7), (3, 6, 8), (1, 7, 9)]
Unit testing involves testing individual units or components of code to ensure proper functioning.
The correct approach to unit testing is to test all code parts individually.
All tests should be within a subclass TestCase
from the unittest
library.
Each test is a function named starting with test_
.
Assert methods are used to check for expected results.
The setUp()
method is called before each test, used to define elements needed for the tests.
The tearDown()
method is called after each test, used to reset definitions after each test.
assertTrue
: Succeeds if the expression is true.
assertFalse
: Succeeds if the expression is false.
assertEqual
, assertNotEqual
: Checks equality and inequality.
assertAlmostEqual
: Used for comparing floating-point numbers.
assertNotAlmostEqual
Create a workspace where all tests are located.
Configure tests in the testing tab.
Select unittest
-> Root directory -> test_*.py
.
If test files are not appearing, reload the window:
Control + Shift + p
(Windows)
Command + Shift + p
(Mac)
Options: "Reload window", "Configure python tests"
If the explorer is not working, run tests in the terminal:
python -m unittest discover -v -s . -p "test_*.py"
For test discovery errors, reload the window.
Create a new folder for each exercise.
Configure Python tests in each exercise by changing the folder in the configuration.
Each exercise should have at least two files: class_name.py
and test_class_name.py
.
Exercise 1 - Calculator Class:
Step 1: Create tests for all methods (add
, subtract
, multiply
, divide
) using pytest
and unittest
.
Step 2: Implement the functions to make tests pass.
Test cases provided for each method with expected results.
For example:
add(1, 3)
should return 4.
subtract(8, 7)
should return 1.
multiply(8, 3)
should return 24.
divide(10, 5)
should return 2.
Exercise 2 - Temperature Converter Class:
Step 1: Create tests for all methods (celsius_to_fahrenheit
, fahrenheit_to_celsius
, celsius_to_kelvin
, kelvin_to_celsius
) using pytest
and unittest
.
Step 2: Implement the functions to make tests pass.
Test cases provided for each method with expected results.
celsius_to_fahrenheit(0)
should return 32.
fahrenheit_to_celsius(32)
should return 0.
celsius_to_kelvin(25)
should return 298.15.
kelvin_to_celsius(273.15)
should return 0.
Supports unittests.
Allows selecting specific tests using the -k
flag.
Provides mark tests:
@pytest.mark.skip
: Skips the test.
@pytest.mark.xfail
: Marks the test as expected to fail.
Filter by marked tests using the -m
flag.
Run from the last failed test using the --lf
flag.
Mock objects imitate real objects but with fake data.
Commonly used for API calls.
Decouples tested code from other calls.
Example:
Mocking an expensive API call to speed up tests.
import time
def compute(x):
response = expensive_api_call()
return response + x
def expensive_api_call():
time.sleep(1000) # takes 1,000 seconds
return 123
import unittest
import compute_expensive
class TestComputeExpensive(unittest.TestCase):
def test_compute(self):
self.assertEqual(compute_expensive.compute(1), 124)
import unittest
from unittest.mock import patch
import compute_expensive
class TestComputeExpensive(unittest.TestCase):
@patch('compute_expensive.expensive_api_call', return_value=123)
def test_compute(self, mock_expensive_api_call):
# calls the compute function mocking the expensive_api_call
self.assertEqual(124, compute_expensive.compute(1))
# asserts that expensive_api_call was called once
mock_expensive_api_call.assert_called_once()
Tracks which lines of code are executed during tests.
Provides a report describing test coverage.
Tool to gain insight into what the tests are doing.
Not the sole definition of a good test suite.
Right-click in the folder where test folders are located and select "Run Tests with Coverage".
If a No module named 'coverage'
error occurs, install the coverage package:
pip install coverage
or pip3 install coverage
if pip
is not working.
The percentage of code covered appears next to the file name once configured correctly.
Exercise 3 - Bank Account Class:
Step 1: Create test cases for BankAccount
class methods (__init__
, deposit
, withdraw
, get_balance
).
Step 2: Implement failing tests.
Step 3: Implement the code to make the tests pass.
Exercise 4 - Counter Class:
Step 1: Create test cases for Counter
class methods (__init__
, increment
, decrement
, reset
, get_value
).
Step 2: Implement failing tests.
Step 3: Implement the code to make the tests pass.
Exercise 5 - To-Do List Class:
Step 1: Create test cases for ToDoList
class methods (__init__
, add_task
, remove_task
, get_tasks
).
Step 2: Implement failing tests.
Step 3: Implement the code to make the tests pass.
Exercise 6 - Shapes:
Create tests using inheritance and abstract methods for shapes (rectangle, circle, square).
Each shape should have perimeter and area calculations.