Writing Python tests
π§ This section is still in active development and is subject to changes π§
What to write tests for
Write tests for:
- Every function, class, and method.
- Every possible input and output.
- Every possible error within the function.
How to write tests
Test location
We use pytest for testing our Python code and keep the tests outside the application code in a tests
directory, like so:
sprout/
βββ core/
β βββ my_function.py
βββ tests/
β βββ test_my_function.py
Test files
Make one test file per Python script and only test the functions within that script. This makes it easier to do a cycle of writing and testing, since you only need to run the one test file and not all the tests.
Always name the test file the same as the Python script, but with test_
as a prefix. E.g., my_function.py
β> test_my_function.py
.
Test names
Use the following general pattern for naming tests:
test_<action>_<condition>
. E.g.,test_returns_relative_path_with_multi_digits
ortest_rejects_unsupported_format
.- If there are multiple functions in the same script, you can include the function name in the test name:
test_<function>_<action>_<condition>
.
Test structure
Use the following general structure for tests:
- Given: Set up the test data and any other necessary conditions.
- When: Call the function or method being tested.
- Then: Check the output of the function or method.
This is sometimes called βArrange, act, assertβ.
If tests are short and very simple, you donβt have to use these sections explicitly. But as tests get longer and more complex, it can be helpful - for reviewers and your future self - to include them.
Keep the tests as simple as possible and only test one thing at a time. If you need to test multiple things, write multiple tests.
To avoid repeating yourself, use parameterized tests to test multiple inputs and outputs with the same test function.