Skip to content

Commit 9fa6673

Browse files
authored
Merge pull request #8434 from evildmp/evolutionary-documentation-restructure
2 parents af9f27a + dd57650 commit 9fa6673

File tree

14 files changed

+757
-670
lines changed

14 files changed

+757
-670
lines changed

AUTHORS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ Daniel Grana
7878
Daniel Hahler
7979
Daniel Nuri
8080
Daniel Wandschneider
81+
Daniele Procida
8182
Danielle Jenkins
8283
Daniil Galiev
8384
Dave Hunt

doc/en/_templates/globaltoc.html

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,20 @@ <h3><a href="{{ pathto(master_doc) }}">{{ _('Table Of Contents') }}</a></h3>
22

33
<ul>
44
<li><a href="{{ pathto('index') }}">Home</a></li>
5+
56
<li><a href="{{ pathto('getting-started') }}">Get started</a></li>
7+
<li><a href="{{ pathto('how-to/index') }}">How-to guides</a></li>
8+
<li><a href="{{ pathto('reference/index') }}">Reference guides</a></li>
9+
<li><a href="{{ pathto('explanation/index') }}">Explanation</a></li>
10+
611
<li><a href="{{ pathto('example/index') }}">Examples</a></li>
12+
713
<li><a href="{{ pathto('reference/customize') }}">Customize</a></li>
814
<li><a href="{{ pathto('reference/reference') }}">API Reference</a></li>
915
<li><a href="{{ pathto('reference/plugin_list') }}">3rd party plugins</a></li>
16+
1017
<li><a href="{{ pathto('contents') }}">Complete table of contents</a></li>
18+
1119
<li><a href="{{ pathto('changelog') }}">Changelog</a></li>
1220
<li><a href="{{ pathto('contributing') }}">Contributing</a></li>
1321
<li><a href="{{ pathto('backwards-compatibility') }}">Backwards Compatibility</a></li>

doc/en/contents.rst

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ How-to guides
3535
how-to/plugins
3636
how-to/nose
3737
how-to/bash-completion
38+
how-to/fixtures
3839

3940

4041
Reference guides
@@ -43,7 +44,7 @@ Reference guides
4344
.. toctree::
4445
:maxdepth: 2
4546

46-
reference/fixture
47+
reference/fixtures
4748
reference/warnings
4849
reference/doctest
4950
reference/cache
@@ -56,15 +57,25 @@ Reference guides
5657
reference/reference
5758

5859

60+
Explanation
61+
-----------------
62+
63+
.. toctree::
64+
:maxdepth: 2
65+
66+
explanation/anatomy
67+
explanation/fixtures
68+
explanation/goodpractices
69+
explanation/flaky
70+
explanation/pythonpath
71+
72+
5973
Further topics
6074
-----------------
6175

6276
.. toctree::
6377
:maxdepth: 2
6478

65-
goodpractices
66-
flaky
67-
pythonpath
6879
example/index
6980

7081
backwards-compatibility

doc/en/example/simple.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ Here is a basic pattern to achieve this:
6969
7070
7171
For this to work we need to add a command line option and
72-
provide the ``cmdopt`` through a :ref:`fixture function <fixture function>`:
72+
provide the ``cmdopt`` through a :ref:`fixture function <fixture>`:
7373

7474
.. code-block:: python
7575

doc/en/explanation/anatomy.rst

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
.. _test-anatomy:
2+
3+
Anatomy of a test
4+
=================
5+
6+
In the simplest terms, a test is meant to look at the result of a particular
7+
behavior, and make sure that result aligns with what you would expect.
8+
Behavior is not something that can be empirically measured, which is why writing
9+
tests can be challenging.
10+
11+
"Behavior" is the way in which some system **acts in response** to a particular
12+
situation and/or stimuli. But exactly *how* or *why* something is done is not
13+
quite as important as *what* was done.
14+
15+
You can think of a test as being broken down into four steps:
16+
17+
1. **Arrange**
18+
2. **Act**
19+
3. **Assert**
20+
4. **Cleanup**
21+
22+
**Arrange** is where we prepare everything for our test. This means pretty
23+
much everything except for the "**act**". It's lining up the dominoes so that
24+
the **act** can do its thing in one, state-changing step. This can mean
25+
preparing objects, starting/killing services, entering records into a database,
26+
or even things like defining a URL to query, generating some credentials for a
27+
user that doesn't exist yet, or just waiting for some process to finish.
28+
29+
**Act** is the singular, state-changing action that kicks off the **behavior**
30+
we want to test. This behavior is what carries out the changing of the state of
31+
the system under test (SUT), and it's the resulting changed state that we can
32+
look at to make a judgement about the behavior. This typically takes the form of
33+
a function/method call.
34+
35+
**Assert** is where we look at that resulting state and check if it looks how
36+
we'd expect after the dust has settled. It's where we gather evidence to say the
37+
behavior does or does not aligns with what we expect. The ``assert`` in our test
38+
is where we take that measurement/observation and apply our judgement to it. If
39+
something should be green, we'd say ``assert thing == "green"``.
40+
41+
**Cleanup** is where the test picks up after itself, so other tests aren't being
42+
accidentally influenced by it.
43+
44+
At its core, the test is ultimately the **act** and **assert** steps, with the
45+
**arrange** step only providing the context. **Behavior** exists between **act**
46+
and **assert**.

doc/en/explanation/fixtures.rst

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
.. _about-fixtures:
2+
3+
About fixtures
4+
===============
5+
6+
.. seealso:: :ref:`how-to-fixtures`
7+
.. seealso:: :ref:`Fixtures reference <reference-fixtures>`
8+
9+
10+
What fixtures are
11+
-----------------
12+
13+
In testing, a `fixture <https://en.wikipedia.org/wiki/Test_fixture#Software>`_
14+
provides a defined, reliable and consistent context for the tests. This could
15+
include environment (for example a database configured with known parameters)
16+
or content (such as a dataset).
17+
18+
Fixtures define the steps and data that constitute the *arrange* phase of a
19+
test (see :ref:`test-anatomy`). In pytest, they are functions you define that
20+
serve this purpose. They can also be used to define a test's *act* phase; this
21+
is a powerful technique for designing more complex tests.
22+
23+
The services, state, or other operating environments set up by fixtures are
24+
accessed by test functions through arguments. For each fixture used by a test
25+
function there is typically a parameter (named after the fixture) in the test
26+
function's definition.
27+
28+
We can tell pytest that a particular function is a fixture by decorating it with
29+
:py:func:`@pytest.fixture <pytest.fixture>`. Here's a simple example of
30+
what a fixture in pytest might look like:
31+
32+
.. code-block:: python
33+
34+
import pytest
35+
36+
37+
class Fruit:
38+
def __init__(self, name):
39+
self.name = name
40+
41+
def __eq__(self, other):
42+
return self.name == other.name
43+
44+
45+
@pytest.fixture
46+
def my_fruit():
47+
return Fruit("apple")
48+
49+
50+
@pytest.fixture
51+
def fruit_basket(my_fruit):
52+
return [Fruit("banana"), my_fruit]
53+
54+
55+
def test_my_fruit_in_basket(my_fruit, fruit_basket):
56+
assert my_fruit in fruit_basket
57+
58+
Tests don't have to be limited to a single fixture, either. They can depend on
59+
as many fixtures as you want, and fixtures can use other fixtures, as well. This
60+
is where pytest's fixture system really shines.
61+
62+
63+
Improvements over xUnit-style setup/teardown functions
64+
-----------------------------------------------------------
65+
66+
pytest fixtures offer dramatic improvements over the classic xUnit
67+
style of setup/teardown functions:
68+
69+
* fixtures have explicit names and are activated by declaring their use
70+
from test functions, modules, classes or whole projects.
71+
72+
* fixtures are implemented in a modular manner, as each fixture name
73+
triggers a *fixture function* which can itself use other fixtures.
74+
75+
* fixture management scales from simple unit to complex
76+
functional testing, allowing to parametrize fixtures and tests according
77+
to configuration and component options, or to re-use fixtures
78+
across function, class, module or whole test session scopes.
79+
80+
* teardown logic can be easily, and safely managed, no matter how many fixtures
81+
are used, without the need to carefully handle errors by hand or micromanage
82+
the order that cleanup steps are added.
83+
84+
In addition, pytest continues to support :ref:`xunitsetup`. You can mix
85+
both styles, moving incrementally from classic to new style, as you
86+
prefer. You can also start out from existing :ref:`unittest.TestCase
87+
style <unittest.TestCase>` or :ref:`nose based <nosestyle>` projects.
88+
89+
90+
91+
Fixture errors
92+
--------------
93+
94+
pytest does its best to put all the fixtures for a given test in a linear order
95+
so that it can see which fixture happens first, second, third, and so on. If an
96+
earlier fixture has a problem, though, and raises an exception, pytest will stop
97+
executing fixtures for that test and mark the test as having an error.
98+
99+
When a test is marked as having an error, it doesn't mean the test failed,
100+
though. It just means the test couldn't even be attempted because one of the
101+
things it depends on had a problem.
102+
103+
This is one reason why it's a good idea to cut out as many unnecessary
104+
dependencies as possible for a given test. That way a problem in something
105+
unrelated isn't causing us to have an incomplete picture of what may or may not
106+
have issues.
107+
108+
Here's a quick example to help explain:
109+
110+
.. code-block:: python
111+
112+
import pytest
113+
114+
115+
@pytest.fixture
116+
def order():
117+
return []
118+
119+
120+
@pytest.fixture
121+
def append_first(order):
122+
order.append(1)
123+
124+
125+
@pytest.fixture
126+
def append_second(order, append_first):
127+
order.extend([2])
128+
129+
130+
@pytest.fixture(autouse=True)
131+
def append_third(order, append_second):
132+
order += [3]
133+
134+
135+
def test_order(order):
136+
assert order == [1, 2, 3]
137+
138+
139+
If, for whatever reason, ``order.append(1)`` had a bug and it raises an exception,
140+
we wouldn't be able to know if ``order.extend([2])`` or ``order += [3]`` would
141+
also have problems. After ``append_first`` throws an exception, pytest won't run
142+
any more fixtures for ``test_order``, and it won't even try to run
143+
``test_order`` itself. The only things that would've run would be ``order`` and
144+
``append_first``.
145+
146+
147+
Sharing test data
148+
-----------------
149+
150+
If you want to make test data from files available to your tests, a good way
151+
to do this is by loading these data in a fixture for use by your tests.
152+
This makes use of the automatic caching mechanisms of pytest.
153+
154+
Another good approach is by adding the data files in the ``tests`` folder.
155+
There are also community plugins available to help managing this aspect of
156+
testing, e.g. `pytest-datadir <https://pypi.org/project/pytest-datadir/>`__
157+
and `pytest-datafiles <https://pypi.org/project/pytest-datafiles/>`__.
File renamed without changes.

doc/en/goodpractices.rst renamed to doc/en/explanation/goodpractices.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ Conventions for Python test discovery
4848
* ``test`` prefixed test functions or methods outside of class
4949
* ``test`` prefixed test functions or methods inside ``Test`` prefixed test classes (without an ``__init__`` method)
5050

51-
For examples of how to customize your test discovery :doc:`example/pythoncollection`.
51+
For examples of how to customize your test discovery :doc:`/example/pythoncollection`.
5252

5353
Within Python modules, ``pytest`` also discovers tests using the standard
5454
:ref:`unittest.TestCase <unittest.TestCase>` subclassing technique.

doc/en/explanation/index.rst

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
:orphan:
2+
3+
Explanation
4+
================
5+
6+
.. toctree::
7+
:maxdepth: 1
8+
9+
anatomy
10+
fixtures
11+
goodpractices
12+
flaky
13+
pythonpath
File renamed without changes.

0 commit comments

Comments
 (0)