@@ -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
104189The 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
395496A non-exhaustive discussion of some common types of tests.
396497
397- ^ _ ^ Dont Panic ^ _ ^
498+ Dont Panic!
398499
399500Depending on your project, you may not need many, or most of these kinds of
400501tests.
@@ -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
474559Testing random input, using tools like Hypothesis, is similar to testing edge
0 commit comments