Skip to content

Commit 5716e45

Browse files
committed
add section on test suites
1 parent 64785eb commit 5716e45

File tree

1 file changed

+103
-18
lines changed

1 file changed

+103
-18
lines changed

docs/pages/principles/testing.md

Lines changed: 103 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,91 @@ minimizing the use of mocks/patches/test-doubles.
9999
> your test suite(s) grow, taxonomy of test cases, the and the use/need for
100100
> different kinds of tests will become more clear.
101101
102+
## Test Suites
103+
104+
Not all test cases are the same. In the following sections we will discuss many
105+
kinds of tests, which serve different purposes and provide different benefits.
106+
Tests should be divided up into different Suites, which can be run independently
107+
of one another.
108+
109+
Tests which "Fail Fast" save both developer and compute time. Some tests are by
110+
necessity very slow. [Unit Tests](#unit-tests) should run extremely quickly in
111+
just a few seconds at most, while [end-to-end](#end-to-end-tests) require time
112+
to set up and may depend on slow and unreliable external services. By organizing
113+
tests into suites based on execution time, you can run fast suites first and
114+
stop if an error is encountered before running slower suites.
115+
116+
### Advantages of Test Suites
117+
118+
- Developers can run relevant tests quickly and frequently.
119+
- Tests can 'Fail Fast', while still reporting all failures within that suite.
120+
- Test cases can be divided up conceptually, making them easier to read and
121+
reason about.
122+
- We can avoid false positives, by not running tests we expect to fail due to
123+
external factors.
124+
125+
### Guidelines for Test Suites
126+
127+
- Organize test cases into suites based on the type of test and execution time.
128+
- Set up test-runners (Make, shell scripts, CI/CD) to run fast suites first, and
129+
stop when a suite reports a failure.
130+
- Use markers to enable developers to run the sub-sets of test which are most
131+
relevant to their work, with minimal time spent waiting.
132+
133+
### Creating Test Suites
134+
135+
The simplest way to start, is separating tests into directories inside of the
136+
`tests/` directory:
137+
138+
```
139+
tests/
140+
|- unit/
141+
|- integration/
142+
|- e2e/
143+
```
144+
145+
These suites can be run directly with pytest `pytest tests/unit/`.
146+
147+
[Markers](https://docs.pytest.org/en/stable/example/markers.html) provide an
148+
additional layer of organization, by labeling individual tests. This lets us
149+
create specialized suites based on markers, independent of directory structure
150+
or type of test. For example we can mark extremely slow or flakey tests that are
151+
conceptually part of a larger suite, and skip them when needed.
152+
153+
First, define a new marker in `pyproject.toml`:
154+
155+
```toml
156+
[tool.pytest.ini_options]
157+
markers = [
158+
"unit: marks unit tests",
159+
"slow: marks tests as slow (deselect with '-m \"not slow\"')",
160+
"online: tests which require internet access",
161+
]
162+
```
163+
164+
To mark an individual test, decorate the test case:
165+
166+
```python
167+
import pytest
168+
169+
170+
@pytest.mark.slow
171+
def test_somthing_slow(): ...
172+
```
173+
174+
To mark every test in a directory, add the following to the `conftest.py` in the
175+
target folder:
176+
177+
```python
178+
# tests/unit/conftest.py
179+
import pytest
180+
181+
182+
def pytest_collection_modifyitems(session, config, items):
183+
for item in items:
184+
item.add_marker(pytest.mark.unit)
185+
```
186+
102187
## Project Level Integration Tests
103188

104189
The term "Integration Test" is unfortunately overloaded, and used to describe
@@ -390,11 +475,27 @@ def test_pytest(mocker):
390475
dangerous_sideffects()
391476
```
392477

393-
## A Brief Taxonomy of Test Suites
478+
## Testing Edgecases
479+
480+
While writing unit tests, you may be tempted to test edgecases. You may have a
481+
critical private function or algorithm, which is not part of the public API (so
482+
not a good candidate for External testing) and you are concerned about many
483+
edgecases that you want to defend against using tests.
484+
485+
It is perfectly valid to write extensive edgecase testing for private code, but
486+
these tests should be kept separate from the unit test suite. Extensive edgecase
487+
testing makes tests long, and difficult to read (tests are documentation). They
488+
can slow down execution, we want unit tests to run first, fast, and often.
489+
490+
- Place them in separate files from unit tests, to improve readability
491+
- [mark them](https://docs.pytest.org/en/stable/how-to/mark.html) so that they
492+
can be run as a separate test suite, after your unit test pass
493+
494+
## Additional Types of Test Suites
394495

395496
A non-exhaustive discussion of some common types of tests.
396497

397-
^_^ Dont Panic ^_^
498+
Dont Panic!
398499

399500
Depending on your project, you may not need many, or most of these kinds of
400501
tests.
@@ -453,22 +554,6 @@ production-like system, and run tests against it. Some examples are:
453554
- Processing data from a pre-loaded test database
454555
- Manual QA testing
455556

456-
## Testing Edgecases
457-
458-
While writing unit tests, you may be tempted to test edgecases. You may have a
459-
critical private function or algorithm, which is not part of the public API (so
460-
not a good candidate for External testing) and you are concerned about many
461-
edgecases that you want to defend against using tests.
462-
463-
It is perfectly valid to write extensive edgecase testing for private code, but
464-
these tests should be kept separate from the unit test suite. Extensive edgecase
465-
testing makes tests long, and difficult to read (tests are documentation). They
466-
can slow down execution, we want unit tests to run first, fast, and often.
467-
468-
- Place them in separate files from unit tests, to improve readability
469-
- [mark them](https://docs.pytest.org/en/stable/how-to/mark.html) so that they
470-
can be run as a separate test suite, after your unit test pass
471-
472557
### Fuzz Tests and other slow tests
473558

474559
Testing random input, using tools like Hypothesis, is similar to testing edge

0 commit comments

Comments
 (0)