Code without tests (aka. legacy code) is extremely difficult to work with
Unit tests...
Essentially none, but writing unit tests ...
For writing, compiling and running unit tests, a unit testing framework is required.
There are many concurring unit testing frameworks for Python.
At the time of this writing, pytest offers the best features.
def add_to(n):
"""
Return the sum of all values from 1 to n.
"""
sum = 0
for i in range(n+1):
sum += i
return sum
Download before_refactoring.py
After experiencing performance problems, we want to use a faster algorithm
# after refacturing
def add_to(n):
"""
Return the sum of all values from 1 to n.
"""
return (n / 2.0) * (n + 1)
Download after_refactoring.py
How can we apply the change without risking to destroy our application?
Using pencil and paper / brainstorming: define relevant test cases
25 is a possible common case.
Add 26 as an even input. 500000000 is a possible large input.
The edge cases should include 0 and 4294967295.
Ideally, also add 1, 2, 4294967293 and 4294967294.
Expected results for these are 325, 351, 125000000250000000, 0 and 9223372034707292160 as well as 1, 3, 9223372026117357571 and 9223372030412324865.
from before_refactoring import add_to
# from after_refactoring import add_to
# from after_refactoring_fixed import add_to
def test_add_to():
assert add_to(0) == 0
assert add_to(1) == 1
assert add_to(2) == 3
assert add_to(25) == 325
assert add_to(26) == 351
assert add_to(500000000) == 125000000250000000
def test_add_to_slow():
assert add_to(4294967293) == 9223372026117357571
assert add_to(4294967294) == 9223372030412324865
assert add_to(4294967295) == 9223372034707292160
Download sum_to_test.py
# takes rather long; can be interrupted via [Ctrl]+[C]
# tests are discovered automatically
pytest # or `python -m pytest`
What to do now?
pytest --help
pytest --collect-only # list all available tests
pytest -k "not slow" # ignore tests with `slow` in their name
For the sake of the presentation, instead of applying the change, we use another source file.
Download after_refactoring.pyAdjust the test to import from the new implementation and run the tests.
pytest
pip install --user --upgrade pip
pip install --user --upgrade pytest
or use your operating system's package manager
sudo apt install python3-pytest
Comprehensive documentation can be found on pytest.org.
TDD is a methodology that emphasizes writing tests before the actual code
Helps ensure that code is tested thoroughly and avoids regressions
Repeat the cycle for each new piece of functionality
Whenever you are tempted to type something into a print
statement or a debugger expression, write it as a test instead.