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.
The edge cases should
include 0 and 4294967295.
Expected results for these are 325, 351, 0 and 9223372034707292160.
Let's also add 500000000 (expected result 125000000250000000) as 4294967295 does not terminate with the current implementation.
from before_refactoring import add_to
# from after_refactoring import add_to
def test_add_to():
assert add_to(0) == 0
assert add_to(25) == 325
assert add_to(26) == 351
assert add_to(500000000) == 125000000250000000
def test_add_to_slow():
assert add_to(4294967295) == 9223372034707292160
Download test_sum_to.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.
Adjust 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.