doc updates for new assertion debugging
This commit is contained in:
parent
d53feaf6f0
commit
e22d3e03fe
|
@ -39,23 +39,6 @@ assertion fails you will see the value of ``x``::
|
||||||
test_assert1.py:5: AssertionError
|
test_assert1.py:5: AssertionError
|
||||||
========================= 1 failed in 0.02 seconds =========================
|
========================= 1 failed in 0.02 seconds =========================
|
||||||
|
|
||||||
Reporting details about the failing assertion is achieved by re-evaluating
|
|
||||||
the assert expression and recording the intermediate values.
|
|
||||||
|
|
||||||
Note: If evaluating the assert expression has side effects you may get a
|
|
||||||
warning that the intermediate values could not be determined safely. A
|
|
||||||
common example of this issue is an assertion which reads from a file::
|
|
||||||
|
|
||||||
assert f.read() != '...'
|
|
||||||
|
|
||||||
If this assertion fails then the re-evaluation will probably succeed!
|
|
||||||
This is because ``f.read()`` will return an empty string when it is
|
|
||||||
called the second time during the re-evaluation. However, it is
|
|
||||||
easy to rewrite the assertion and avoid any trouble::
|
|
||||||
|
|
||||||
content = f.read()
|
|
||||||
assert content != '...'
|
|
||||||
|
|
||||||
|
|
||||||
assertions about expected exceptions
|
assertions about expected exceptions
|
||||||
------------------------------------------
|
------------------------------------------
|
||||||
|
@ -137,6 +120,46 @@ Special comparisons are done for a number of cases:
|
||||||
|
|
||||||
See the :ref:`reporting demo <tbreportdemo>` for many more examples.
|
See the :ref:`reporting demo <tbreportdemo>` for many more examples.
|
||||||
|
|
||||||
|
|
||||||
|
Assertion debugging details
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
Reporting details about the failing assertion is achieved either by rewriting
|
||||||
|
assert statements before they are run or re-evaluating the assert expression and
|
||||||
|
recording the intermediate values. Which technique is used depends on the
|
||||||
|
location of the assert, py.test's configuration, and Python version being used
|
||||||
|
to run py.test.
|
||||||
|
|
||||||
|
By default, if the Python version is greater than or equal to 2.6, py.test
|
||||||
|
rewrites assert statements in test modules. Rewritten assert statements put
|
||||||
|
debugging information into the assertion failure message. Note py.test only
|
||||||
|
rewrites test modules directly discovered by its test collection process, so
|
||||||
|
asserts in supporting modules will not be rewritten.
|
||||||
|
|
||||||
|
If an assert statement has not been rewritten or the Python version is less than
|
||||||
|
2.6, py.test falls back on assert reinterpretation. In assert reinterpretation,
|
||||||
|
py.test walks the frame of the function containing the assert statement to
|
||||||
|
discover sub-expression results of the failing assert statement. You can force
|
||||||
|
py.test to always use assertion reinterpretation by passing the
|
||||||
|
``--assertmode=old`` option.
|
||||||
|
|
||||||
|
Assert reinterpretation has a caveat not present with assert rewriting: If
|
||||||
|
evaluating the assert expression has side effects you may get a warning that the
|
||||||
|
intermediate values could not be determined safely. A common example of this
|
||||||
|
issue is an assertion which reads from a file::
|
||||||
|
|
||||||
|
assert f.read() != '...'
|
||||||
|
|
||||||
|
If this assertion fails then the re-evaluation will probably succeed!
|
||||||
|
This is because ``f.read()`` will return an empty string when it is
|
||||||
|
called the second time during the re-evaluation. However, it is
|
||||||
|
easy to rewrite the assertion and avoid any trouble::
|
||||||
|
|
||||||
|
content = f.read()
|
||||||
|
assert content != '...'
|
||||||
|
|
||||||
|
All assert debugging can be turned off by passing ``--assertmode=off``.
|
||||||
|
|
||||||
..
|
..
|
||||||
Defining your own comparison
|
Defining your own comparison
|
||||||
----------------------------------------------
|
----------------------------------------------
|
||||||
|
|
18
doc/faq.txt
18
doc/faq.txt
|
@ -47,13 +47,17 @@ customizable testing frameworks for Python. However,
|
||||||
``py.test`` still uses many metaprogramming techniques and
|
``py.test`` still uses many metaprogramming techniques and
|
||||||
reading its source is thus likely not something for Python beginners.
|
reading its source is thus likely not something for Python beginners.
|
||||||
|
|
||||||
A second "magic" issue arguably the assert statement re-intepreation:
|
A second "magic" issue arguably the assert statement debugging feature. When
|
||||||
When an ``assert`` statement fails, py.test re-interprets the expression
|
loading test modules py.test rewrites the source code of assert statements. When
|
||||||
to show intermediate values if a test fails. If your expression
|
a rewritten assert statement fails, its error message has more information than
|
||||||
has side effects (better to avoid them anyway!) the intermediate values
|
the original. py.test has a second assert debugging technique. When an
|
||||||
may not be the same, obfuscating the initial error (this is also
|
``assert`` statement that was missed by the rewriter fails, py.test
|
||||||
explained at the command line if it happens).
|
re-interprets the expression to show intermediate values if a test fails. This
|
||||||
``py.test --no-assert`` turns off assert re-interpretation.
|
second technique suffers from caveat that the rewriting does not: If your
|
||||||
|
expression has side effects (better to avoid them anyway!) the intermediate
|
||||||
|
values may not be the same, confusing the reinterpreter and obfuscating the
|
||||||
|
initial error (this is also explained at the command line if it happens).
|
||||||
|
You can turn off all assertion debugging with ``py.test --assertmode=off``.
|
||||||
|
|
||||||
.. _`py namespaces`: index.html
|
.. _`py namespaces`: index.html
|
||||||
.. _`py/__init__.py`: http://bitbucket.org/hpk42/py-trunk/src/trunk/py/__init__.py
|
.. _`py/__init__.py`: http://bitbucket.org/hpk42/py-trunk/src/trunk/py/__init__.py
|
||||||
|
|
Loading…
Reference in New Issue