doc updates for new assertion debugging

This commit is contained in:
Benjamin Peterson 2011-05-26 21:08:55 -05:00
parent d53feaf6f0
commit e22d3e03fe
2 changed files with 51 additions and 24 deletions

View File

@ -39,23 +39,6 @@ assertion fails you will see the value of ``x``::
test_assert1.py:5: AssertionError
========================= 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
------------------------------------------
@ -137,6 +120,46 @@ Special comparisons are done for a number of cases:
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
----------------------------------------------

View File

@ -47,13 +47,17 @@ customizable testing frameworks for Python. However,
``py.test`` still uses many metaprogramming techniques and
reading its source is thus likely not something for Python beginners.
A second "magic" issue arguably the assert statement re-intepreation:
When an ``assert`` statement fails, py.test re-interprets the expression
to show intermediate values if a test fails. If your expression
has side effects (better to avoid them anyway!) the intermediate values
may not be the same, obfuscating the initial error (this is also
explained at the command line if it happens).
``py.test --no-assert`` turns off assert re-interpretation.
A second "magic" issue arguably the assert statement debugging feature. When
loading test modules py.test rewrites the source code of assert statements. When
a rewritten assert statement fails, its error message has more information than
the original. py.test has a second assert debugging technique. When an
``assert`` statement that was missed by the rewriter fails, py.test
re-interprets the expression to show intermediate values if a test fails. This
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/__init__.py`: http://bitbucket.org/hpk42/py-trunk/src/trunk/py/__init__.py