Merge branch 'pytest-dev'

# Conflicts:
#	AUTHORS
This commit is contained in:
elizabeth
2015-08-24 22:55:11 +03:00
149 changed files with 1334 additions and 427 deletions

View File

@@ -46,7 +46,7 @@ installall: clean install installpdf
@echo "done"
regen:
PYTHONDONTWRITEBYTECODE=1 COLUMNS=76 regendoc --update *.txt */*.txt
PYTHONDONTWRITEBYTECODE=1 COLUMNS=76 regendoc --update *.rst */*.rst
html:
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html

View File

@@ -6,7 +6,7 @@ def get_version_string():
fn = py.path.local(__file__).join("..", "..", "..",
"_pytest", "__init__.py")
for line in fn.readlines():
if "version" in line:
if "version" in line and not line.strip().startswith('#'):
return eval(line.split("=")[-1])
def get_minor_version_string():

27
doc/en/apiref.rst Normal file
View File

@@ -0,0 +1,27 @@
.. _apiref:
pytest reference documentation
================================================
.. toctree::
:maxdepth: 2
builtin
customize
assert
fixture
yieldfixture
parametrize
xunit_setup
capture
monkeypatch
xdist
tmpdir
mark
skipping
recwarn
unittest
nose
doctest

View File

@@ -1,27 +0,0 @@
.. _apiref:
pytest reference documentation
================================================
.. toctree::
:maxdepth: 2
builtin.txt
customize.txt
assert.txt
fixture.txt
yieldfixture.txt
parametrize.txt
xunit_setup.txt
capture.txt
monkeypatch.txt
xdist.txt
tmpdir.txt
mark.txt
skipping.txt
recwarn.txt
unittest.txt
nose.txt
doctest.txt

View File

@@ -114,6 +114,16 @@ like documenting unfixed bugs (where the test describes what "should" happen)
or bugs in dependencies.
.. _`assertwarns`:
Assertions about expected warnings
-----------------------------------------
.. versionadded:: 2.8
You can check that code raises a particular warning using
:ref:`pytest.warns <warns>`.
.. _newreport:
@@ -228,9 +238,7 @@ Reporting details about a 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, ``pytest`` configuration, and Python version being used
to run ``pytest``. Note that for assert statements with a manually provided
message, i.e. ``assert expr, message``, no assertion introspection takes place
and the manually provided message will be rendered in tracebacks.
to run ``pytest``.
By default, if the Python version is greater than or equal to 2.6, ``pytest``
rewrites assert statements in test modules. Rewritten assert statements put

View File

@@ -47,7 +47,7 @@ extensions = ['sphinx.ext.autodoc', 'sphinx.ext.todo', 'sphinx.ext.autosummary',
templates_path = ['_templates']
# The suffix of source filenames.
source_suffix = '.txt'
source_suffix = '.rst'
# The encoding of source files.
#source_encoding = 'utf-8-sig'
@@ -73,13 +73,13 @@ copyright = u'2015, holger krekel and pytest-dev team'
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
exclude_patterns = ['links.inc', '_build', 'naming20.txt', 'test/*',
exclude_patterns = ['links.inc', '_build', 'naming20.rst', 'test/*',
"old_*",
'*attic*',
'*/attic*',
'funcargs.txt',
'setup.txt',
'example/remoteinterp.txt',
'funcargs.rst',
'setup.rst',
'example/remoteinterp.rst',
]

View File

@@ -17,11 +17,11 @@ Full pytest documentation
example/index
talks
contributing
funcarg_compare.txt
funcarg_compare
announce/index
.. toctree::
:hidden:
changelog.txt
changelog

View File

@@ -219,3 +219,10 @@ Builtin configuration file options
One or more doctest flag names from the standard ``doctest`` module.
:doc:`See how py.test handles doctests <doctest>`.
.. confval:: confcutdir
Sets a directory where search upwards for ``conftest.py`` files stops.
By default, pytest will stop searching for ``conftest.py`` files upwards
from ``pytest.ini``/``tox.ini``/``setup.cfg`` of the project if any,
or up to the file-system root.

View File

@@ -72,3 +72,18 @@ ignore lengthy exception stack traces you can just write::
# content of pytest.ini
[pytest]
doctest_optionflags= NORMALIZE_WHITESPACE IGNORE_EXCEPTION_DETAIL
py.test also introduces a new ``ALLOW_UNICODE`` option flag: when enabled, the
``u`` prefix is stripped from unicode strings in expected doctest output. This
allows doctests which use unicode to run in Python 2 and 3 unchanged.
As with any other option flag, this flag can be enabled in ``pytest.ini`` using
the ``doctest_optionflags`` ini option or by an inline comment in the doc test
itself::
# content of example.rst
>>> get_unicode_greeting() # doctest: +ALLOW_UNICODE
'Hello'

View File

@@ -25,10 +25,10 @@ The following examples aim at various use cases you might encounter.
.. toctree::
:maxdepth: 2
reportingdemo.txt
simple.txt
parametrize.txt
markers.txt
special.txt
pythoncollection.txt
nonpython.txt
reportingdemo
simple
parametrize
markers
special
pythoncollection
nonpython

View File

@@ -81,7 +81,7 @@ Numbers, strings, booleans and None will have their usual string representation
used in the test ID. For other objects, pytest will make a string based on
the argument name::
# contents of test_time.py
# content of test_time.py
from datetime import datetime, timedelta

View File

@@ -534,23 +534,24 @@ case we just write some informations out to a ``failures`` file::
import pytest
import os.path
@pytest.hookimpl(tryfirst=True)
def pytest_runtest_makereport(item, call, __multicall__):
@pytest.hookimpl(tryfirst=True, hookwrapper=True)
def pytest_runtest_makereport(item, call):
# execute all other hooks to obtain the report object
rep = __multicall__.execute()
outcome = yield
rep = outcome.get_result()
# we only look at actual failing test calls, not setup/teardown
if rep.when == "call" and rep.failed:
mode = "a" if os.path.exists("failures") else "w"
with open("failures", mode) as f:
# let's also access a fixture for the fun of it
if "tmpdir" in item.funcargs:
if "tmpdir" in item.fixturenames:
extra = " (%s)" % item.funcargs["tmpdir"]
else:
extra = ""
f.write(rep.nodeid + extra + "\n")
return rep
if you then have failing tests::
@@ -606,16 +607,16 @@ here is a little example implemented via a local plugin::
import pytest
@pytest.hookimpl(tryfirst=True)
def pytest_runtest_makereport(item, call, __multicall__):
@pytest.hookimpl(tryfirst=True, hookwrapper=True)
def pytest_runtest_makereport(item, call):
# execute all other hooks to obtain the report object
rep = __multicall__.execute()
outcome = yield
rep = outcome.get_result()
# set an report attribute for each phase of a call, which can
# be "setup", "call", "teardown"
setattr(item, "rep_" + rep.when, rep)
return rep
@pytest.fixture
@@ -742,5 +743,4 @@ over to ``pytest`` instead. For example::
This makes it convenient to execute your tests from within your frozen
application, using standard ``py.test`` command-line options::
$ ./app_main --pytest --verbose --tb=long --junit-xml=results.xml test-suite/
/bin/sh: ./app_main: No such file or directory
./app_main --pytest --verbose --tb=long --junit-xml=results.xml test-suite/

View File

@@ -154,8 +154,8 @@ to create a JUnitXML file that Jenkins_ can pick up and generate reports.
.. _standalone:
.. _`genscript method`:
Create a pytest standalone script
-------------------------------------------
(deprecated) Create a pytest standalone script
-----------------------------------------------
If you are a maintainer or application developer and want people
who don't deal with python much to easily run tests you may generate

View File

@@ -5,10 +5,10 @@ Getting started basics
.. toctree::
:maxdepth: 2
index.txt
getting-started.txt
usage.txt
goodpractises.txt
projects.txt
faq.txt
index
getting-started
usage
goodpractises
projects
faq

View File

@@ -114,6 +114,18 @@ Let's run this::
The one parameter set which caused a failure previously now
shows up as an "xfailed (expected to fail)" test.
To get all combinations of multiple parametrized arguments you can stack
``parametrize`` decorators::
import pytest
@pytest.mark.parametrize("x", [0, 1])
@pytest.mark.parametrize("y", [2, 3])
def test_foo(x, y):
pass
This will run the test with the arguments set to x=0/y=2, x=0/y=3, x=1/y=2 and
x=1/y=3.
.. note::
In versions prior to 2.4 one needed to specify the argument

116
doc/en/recwarn.rst Normal file
View File

@@ -0,0 +1,116 @@
Asserting Warnings
=====================================================
.. _warns:
Asserting warnings with the warns function
-----------------------------------------------
.. versionadded:: 2.8
You can check that code raises a particular warning using ``pytest.warns``,
which works in a similar manner to :ref:`raises <assertraises>`::
import warnings
import pytest
def test_warning():
with pytest.warns(UserWarning):
warnings.warn("my warning", UserWarning)
The test will fail if the warning in question is not raised.
You can also call ``pytest.warns`` on a function or code string::
pytest.warns(expected_warning, func, *args, **kwargs)
pytest.warns(expected_warning, "func(*args, **kwargs)")
The function also returns a list of all raised warnings (as
``warnings.WarningMessage`` objects), which you can query for
additional information::
with pytest.warns(RuntimeWarning) as record:
warnings.warn("another warning", RuntimeWarning)
# check that only one warning was raised
assert len(record) == 1
# check that the message matches
assert record[0].message.args[0] == "another warning"
Alternatively, you can examine raised warnings in detail using the
:ref:`recwarn <recwarn>` fixture (see below).
.. _recwarn:
Recording warnings
------------------------
You can record raised warnings either using ``pytest.warns`` or with
the ``recwarn`` fixture.
To record with ``pytest.warns`` without asserting anything about the warnings,
pass ``None`` as the expected warning type::
with pytest.warns(None) as record:
warnings.warn("user", UserWarning)
warnings.warn("runtime", RuntimeWarning)
assert len(record) == 2
assert str(record[0].message) == "user"
assert str(record[1].message) == "runtime"
The ``recwarn`` fixture will record warnings for the whole function::
import warnings
def test_hello(recwarn):
warnings.warn("hello", UserWarning)
assert len(recwarn) == 1
w = recwarn.pop(UserWarning)
assert issubclass(w.category, UserWarning)
assert str(w.message) == "hello"
assert w.filename
assert w.lineno
Both ``recwarn`` and ``pytest.warns`` return the same interface for recorded
warnings: a WarningsRecorder instance. To view the recorded warnings, you can
iterate over this instance, call ``len`` on it to get the number of recorded
warnings, or index into it to get a particular recorded warning. It also
provides these methods:
.. autoclass:: _pytest.recwarn.WarningsRecorder()
:members:
Each recorded warning has the attributes ``message``, ``category``,
``filename``, ``lineno``, ``file``, and ``line``. The ``category`` is the
class of the warning. The ``message`` is the warning itself; calling
``str(message)`` will return the actual message of the warning.
.. _ensuring_function_triggers:
Ensuring a function triggers a deprecation warning
-------------------------------------------------------
You can also call a global helper for checking
that a certain function call triggers a ``DeprecationWarning``::
import pytest
def test_global():
pytest.deprecated_call(myfunction, 17)
By default, deprecation warnings will not be caught when using ``pytest.warns``
or ``recwarn``, since the default Python warnings filters hide
DeprecationWarnings. If you wish to record them in your own code, use the
command ``warnings.simplefilter('always')``::
import warnings
import pytest
def test_deprecation(recwarn):
warnings.simplefilter('always')
warnings.warn("deprecated", DeprecationWarning)
assert len(recwarn) == 1
assert recwarn.pop(DeprecationWarning)

View File

@@ -1,46 +0,0 @@
Asserting deprecation and other warnings
=====================================================
.. _function_argument:
The recwarn function argument
------------------------------------
You can use the ``recwarn`` funcarg to assert that code triggers
warnings through the Python warnings system. Here is a simple
self-contained test::
# content of test_recwarn.py
def test_hello(recwarn):
from warnings import warn
warn("hello", DeprecationWarning)
w = recwarn.pop(DeprecationWarning)
assert issubclass(w.category, DeprecationWarning)
assert 'hello' in str(w.message)
assert w.filename
assert w.lineno
The ``recwarn`` function argument provides these methods:
.. method:: pop(category=None)
Return last warning matching the category.
.. method:: clear()
Clear list of warnings
.. _ensuring_function_triggers:
Ensuring a function triggers a deprecation warning
-------------------------------------------------------
You can also call a global helper for checking
that a certain function call triggers a ``DeprecationWarning``::
import pytest
def test_global():
pytest.deprecated_call(myfunction, 17)

View File

@@ -1,54 +0,0 @@
pytest release checklist
-------------------------
For doing a release of pytest (status April 2015) this rough checklist is used:
1. change version numbers in ``_pytest/__init__.py`` to the to-be-released version.
(the version number in ``setup.py`` reads from that init file as well)
2. finalize ``./CHANGELOG`` (don't forget the the header).
3. write ``doc/en/announce/release-VERSION.txt``
(usually copying from an earlier release version).
4. regenerate doc examples with ``tox -e regen`` and check with ``git diff``
if the differences show regressions. It's a bit of a manual process because
there a large part of the diff is about pytest headers or differences in
speed ("tests took X.Y seconds"). (XXX automate doc/example diffing to ignore
such changes and integrate it into "tox -e regen").
5. ``devpi upload`` to `your developer devpi index <http://doc.devpi.net/latest/quickstart-releaseprocess.html>`_. You can create your own user and index on https://devpi.net,
an inofficial service from the devpi authors.
6. run ``devpi use INDEX`` and ``devpi test`` from linux and windows machines
and verify test results on the index. On linux typically all environments
pass (April 2015 there is a setup problem with a cx_freeze environment)
but on windows all involving ``pexpect`` fail because pexpect does not exist
on windows and tox does not allow to have platform-specific environments.
Also on windows ``py33-trial`` fails but should probably pass (March 2015).
In any case, py26,py27,py33,py34 are required to pass for all platforms.
7. You can fix tests/code and repeat number 6. until everything passes.
8. Once you have sufficiently passing tox tests you can do the actual release::
cd doc/en/
make install # will install to 2.7, 2.8, ... according to _pytest/__init__.py
make install-pdf # optional, requires latex packages installed
ssh pytest-dev@pytest.org # MANUAL: symlink "pytest.org/latest" to the just
# installed release docs
# browse to pytest.org to see
devpi push pytest-VERSION pypi:NAME
git commit -a -m "... finalized pytest-VERSION"
git tag VERSION
git push
9. send out release announcement to pytest-dev@python.org,
testing-in-python@lists.idyll.org and python-announce-list@python.org .
10. **after the release** bump the version number in ``_pytest/__init__.py``,
to the next Minor release version (i.e. if you released ``pytest-2.8.0``,
set it to ``pytest-2.9.0.dev1``).
11. already done :)

View File

@@ -83,7 +83,7 @@ As with all function :ref:`marking <mark>` you can skip test functions at the
`whole class- or module level`_. If your code targets python2.6 or above you
use the skipif decorator (and any other marker) on classes::
@pytest.mark.skipif(sys.platform == 'win32',
@pytest.mark.skipif(sys.platform != 'win32',
reason="requires windows")
class TestPosixCalls:
@@ -97,7 +97,7 @@ If your code targets python2.5 where class-decorators are not available,
you can set the ``pytestmark`` attribute of a class::
class TestPosixCalls:
pytestmark = pytest.mark.skipif(sys.platform == 'win32',
pytestmark = pytest.mark.skipif(sys.platform != 'win32',
reason="requires Windows")
def test_function(self):

View File

@@ -1,5 +1,5 @@
generate standalone test script to be distributed along with an application.
(deprecated) generate standalone test script to be distributed along with an application.
============================================================================

View File

@@ -153,6 +153,36 @@ integration servers, use this invocation::
to create an XML file at ``path``.
record_xml_property
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. versionadded:: 2.8
If you want to log additional information for a test, you can use the
``record_xml_property`` fixture:
.. code-block:: python
def test_function(record_xml_property):
record_xml_property("example_key", 1)
assert 0
This will add an extra property ``example_key="1"`` to the generated
``testcase`` tag:
.. code-block:: xml
<testcase classname="test_function" example_key="1" file="test_function.py" line="0" name="test_function" time="0.0009">
.. warning::
This is an experimental feature, and its interface might be replaced
by something more powerful and general in future versions. The
functionality per-se will be kept, however.
Also please note that using this feature will break any schema verification.
This might be a problem when used with some CI servers.
Creating resultlog format files
----------------------------------------------------

Some files were not shown because too many files have changed in this diff Show More