Compare commits

...

52 Commits
2.8.3 ... 2.8.4

Author SHA1 Message Date
Ronny Pfannschmidt
8c17c7cd12 correct copy&paste error in the release announcement version number 2015-12-06 17:44:08 +01:00
Ronny Pfannschmidt
b7459b8a64 finish release announcement 2015-12-06 16:46:44 +01:00
Ronny Pfannschmidt
b920f09a95 doc regen for release 2.8.4 2015-12-06 16:14:23 +01:00
Ronny Pfannschmidt
a3353c49fd prepare release 2.8.4 - changelog updates + version bump 2015-12-06 16:13:55 +01:00
Ronny Pfannschmidt
f508a52ca9 Merge pull request #1225 from pytest-dev/skipping-docs-inconsistency
Fix inconsistency in skipif example
2015-12-05 20:44:01 +01:00
Bruno Oliveira
382efc6363 Fix same inconsistency in next example 2015-12-05 00:43:06 -02:00
Bruno Oliveira
1bed514eb6 Fix inconsistency in skipif example
Fix #1224
2015-12-05 00:35:31 -02:00
Bruno Oliveira
41f19796e8 Merge pull request #1212 from nicoddemus/goodpractices
Goodpractises docs reorganization/review
2015-12-05 00:27:28 -02:00
Ronny Pfannschmidt
427e6c3b4d Merge pull request #1222 from nicoddemus/pastebin-unicode
Fix #1222 - pastebin when captured output contains non-ascii characters
2015-12-04 07:10:49 +01:00
Bruno Oliveira
14bc3c4009 Fix pastebin when captured output contains non-ascii characters
Fix #1219
2015-12-03 20:07:18 -02:00
Florian Bruhin
7e063eec08 Merge pull request #1221 from jeffwidman/patch-1
Fix typo: previosuly --> previously
2015-12-03 21:25:40 +01:00
Jeff Widman
61934ae82d Fix typo: previosuly --> previously 2015-12-03 11:56:18 -08:00
Bruno Oliveira
8c74bb0d25 Improve description on how pytest starts test collection in goodpractises 2015-12-03 01:01:34 -02:00
Bruno Oliveira
bb4771cedf Remove promise about documenting how to create a zipped pytest 2015-12-03 00:13:16 -02:00
Bruno Oliveira
9475cd3fb8 Replace "--assertmode=off" by "--assert=plain"
Fix #1214
2015-12-02 18:39:32 -02:00
Bruno Oliveira
464e16deca Removed incorrect note about genscript requiring wheels 2015-12-02 18:33:53 -02:00
Bruno Oliveira
d9b78f2a95 Remove reference to distutils 2015-12-02 18:30:12 -02:00
Ronny Pfannschmidt
7232b45f25 Merge pull request #1213 from nicoddemus/pastebin-py3
merge Pastebin py3 support

 also closes #1202 and fixes #1198
2015-12-02 09:08:50 +01:00
Bruno Oliveira
a54e4e64cd Merge remote-tracking branch 'upstream/master' into pastebin-py3 2015-12-01 23:51:14 -02:00
Bruno Oliveira
edfb567091 Add #1198 fix to CHANGELOG 2015-12-01 23:37:16 -02:00
Bruno Oliveira
6a2ebddc7c Decode urlopen response in pastebin
Fix #1198
2015-12-01 23:33:37 -02:00
Bruno Oliveira
5040dde0c5 Fix genscript deprecation version and document reasons for such 2015-12-01 23:09:15 -02:00
Bruno Oliveira
095abfd035 Fix formatting errors 2015-12-01 22:52:22 -02:00
Bruno Oliveira
69ef0ab189 Merged virtual env into the Tox section
Nowadays virtualenv use is widespread so we don't need to
devote a how-to section in pytest's docs
2015-12-01 22:47:36 -02:00
Bruno Oliveira
d851a8fd07 Fixed some formatting 2015-12-01 22:43:11 -02:00
Bruno Oliveira
0704fcacd7 Removed setuptools/genscript session 2015-12-01 22:32:07 -02:00
Bruno Oliveira
4f17d56ecb Move deprecated genscript method to the bottom of the document 2015-12-01 22:30:08 -02:00
Bruno Oliveira
b1f6dc23da Moved "conventions for Python test discovery to the top" 2015-12-01 22:28:20 -02:00
Bruno Oliveira
c6f90c25e3 Remove finalize_options override from goodpractices
This is not required in latest versions of `setuptools`, and
`self.test_args` is a read-only attribute in some of the
versions of the 18.X series.

Fix #1134
2015-12-01 22:20:40 -02:00
Florian Bruhin
f0e5cb362e Merge pull request #1211 from nchammas/patch-1
Update xdist newhooks.py link; BitBucket -> GitHub
2015-12-01 20:15:40 +01:00
Nicholas Chammas
c7cf4adfd0 Update xdist link; BitBucket -> GitHub
xdist is now hosted on GitHub.
2015-12-01 13:20:55 -05:00
Ronny Pfannschmidt
def543924b Merge pull request #1209 from jeffwidman/master
Fix spelling: explicitely --> explicitly
2015-12-01 10:51:26 +01:00
Jeff Widman
6be6798cdf Fix spelling: explicitely --> explicitly 2015-12-01 01:41:47 -08:00
Ronny Pfannschmidt
ce4eb51ee0 Merge pull request #1208 from The-Compiler/no-tests-run-spelling
Fix spelling mistake in #1207.
2015-11-30 17:40:26 +01:00
Florian Bruhin
0d2668017d Fix spelling mistake in #1207. 2015-11-30 17:33:34 +01:00
Ronny Pfannschmidt
e7e4860ded Merge pull request #1207 from The-Compiler/no-tests-run
Fix terminal output if no tests were run.
2015-11-30 17:26:47 +01:00
Florian Bruhin
aba55a0fb2 Fix terminal output if no tests were run.
Before:
====  in 0.00 seconds ====

After:
==== no tests run in 0.00 seconds ====
2015-11-30 17:24:40 +01:00
Ronny Pfannschmidt
b5d65e5139 Merge pull request #1206 from The-Compiler/collect-getattr
Don't collect classes with truthy __getattr__.
2015-11-30 17:23:47 +01:00
Ronny Pfannschmidt
3a3f0f5c56 Merge pull request #1205 from The-Compiler/reportinfo-getattr
Fix getting line number with nasty __getattr__. fixes #1204
2015-11-30 17:23:05 +01:00
Florian Bruhin
ba9146c131 Don't collect classes with truthy __getattr__.
When we have a metaclass which returns something truthy (like a method) in its
__getattr__, we collected the class because pytest thought its __test__
attribute was set to True.

We can work around this to some degree by assuming __test__ will always be set
to an explicit True if that's what the user has intended, and if it's something
other than that, this is probably a mistake.

Fixes #1204.
2015-11-30 16:41:13 +01:00
Florian Bruhin
c790f7475e Fix getting line number with nasty __getattr__.
When an object has a custom __getattr__ which always returns a non-int, we
tried to get compat_co_firstlineno from it and checked it was a integer, which
caused an exception if such a class is mistakenly collected.

If we still mistakenly collect such a class (which is likely to be something
other than a test), we now skip it with a warning (because it probably has an
__init__) instead of producing an error.

See #1204.
2015-11-30 16:13:15 +01:00
mehdy
f9b1e39b8a fix #1198 - decoding monkeypatched data to unicode 2015-11-29 19:42:50 +03:30
mehdy
81ad1689b9 fix #1198 - removed docoding the result 2015-11-29 19:20:37 +03:30
mehdy
44f60ba141 fixed #1198 issue by encoding the unicode parameters to bytes and decoding the
bytes response to unicode
2015-11-29 18:27:05 +03:30
Ronny Pfannschmidt
bced5a3f81 Merge pull request #1200 from macrotim/master
Merge #1200 - correct various documentation spelling misstakes
2015-11-28 08:00:24 +01:00
Tim Chan
a8d7e513f4 Fixed docs 2015-11-27 22:46:45 -08:00
Ronny Pfannschmidt
604a021a2a Merge pull request #1196 from nicoddemus/deprecated-call-1190
Make deprecated_call() use monkey-patching again , fixes #1190
2015-11-27 22:09:09 +01:00
Bruno Oliveira
603d81ef2f deprecated_call now uses monkey patching strategy to capture warnings
similar to what we had in 2.7, with a few enhancements

Fix #1190
2015-11-26 16:48:58 -02:00
Bruno Oliveira
6378cdf7a9 Restored 2.7 implentation of deprecated_call 2015-11-26 15:54:57 -02:00
Bruno Oliveira
320c95ca43 Fix formatting in HOWTORELEASE.rst 2015-11-24 12:05:41 -02:00
Bruno Oliveira
b20803f0a6 Mention pytest_enter_pdb in the docs 2015-11-23 18:00:02 -02:00
Ronny Pfannschmidt
af46ffe021 bump to 2.8.4.dev 2015-11-19 22:01:34 +01:00
41 changed files with 441 additions and 295 deletions

View File

@@ -1,3 +1,26 @@
2.8.4
-----
- fix #1190: ``deprecated_call()`` now works when the deprecated
function has been already called by another test in the same
module. Thanks Mikhail Chernykh for the report and Bruno Oliveira for the
PR.
- fix #1198: ``--pastebin`` option now works on Python 3. Thanks
Mehdy Khoshnoody for the PR.
- fix #1219: ``--pastebin`` now works correctly when captured output contains
non-ascii characters. Thanks Bruno Oliveira for the PR.
- fix #1204: another error when collecting with a nasty __getattr__().
Thanks Florian Bruhin for the PR.
- fix the summary printed when no tests did run.
Thanks Florian Bruhin for the PR.
- a number of documentation modernizations wrt good practices.
Thanks Bruno Oliveira for the PR.
2.8.3
-----

View File

@@ -57,25 +57,25 @@ Note: this assumes you have already registered on pypi.
cd doc/en
make install # or "installall" if you have LaTeX installed for PDF
This requires ssh-login permission on pytest.org because it uses
rsync.
Note that the ``install`` target of ``doc/en/Makefile`` defines where the
rsync goes to, typically to the "latest" section of pytest.org.
This requires ssh-login permission on pytest.org because it uses
rsync.
Note that the ``install`` target of ``doc/en/Makefile`` defines where the
rsync goes to, typically to the "latest" section of pytest.org.
If you are making a minor release (e.g. 5.4), you also need to manually
create a symlink for "latest"::
If you are making a minor release (e.g. 5.4), you also need to manually
create a symlink for "latest"::
ssh pytest-dev@pytest.org
ln -s 5.4 latest
ssh pytest-dev@pytest.org
ln -s 5.4 latest
Browse to pytest.org to verify.
Browse to pytest.org to verify.
11. Publish to pypi::
devpi push pytest-VERSION pypi:NAME
where NAME is the name of pypi.python.org as configured in your ``~/.pypirc``
file `for devpi <http://doc.devpi.net/latest/quickstart-releaseprocess.html?highlight=pypirc#devpi-push-releasing-to-an-external-index>`_.
where NAME is the name of pypi.python.org as configured in your ``~/.pypirc``
file `for devpi <http://doc.devpi.net/latest/quickstart-releaseprocess.html?highlight=pypirc#devpi-push-releasing-to-an-external-index>`_.
12. Send release announcement to mailing lists:
@@ -86,5 +86,5 @@ Note: this assumes you have already registered on pypi.
13. **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``).
to the next Minor release version (i.e. if you released ``pytest-2.8.0``,
set it to ``pytest-2.9.0.dev1``).

View File

@@ -115,7 +115,7 @@ tags: feature
- introduce pytest.mark.nocollect for not considering a function for
test collection at all. maybe also introduce a pytest.mark.test to
explicitely mark a function to become a tested one. Lookup JUnit ways
explicitly mark a function to become a tested one. Lookup JUnit ways
of tagging tests.
introduce pytest.mark.importorskip

View File

@@ -1,2 +1,2 @@
#
__version__ = '2.8.3'
__version__ = '2.8.4'

View File

@@ -291,4 +291,6 @@ def pytest_exception_interact(node, call, report):
"""
def pytest_enter_pdb():
""" called upon pdb.set_trace()"""
""" called upon pdb.set_trace(), can be used by plugins to take special
action just before the python debugger enters in interactive mode.
"""

View File

@@ -13,17 +13,21 @@ def pytest_addoption(parser):
@pytest.hookimpl(trylast=True)
def pytest_configure(config):
import py
if config.option.pastebin == "all":
tr = config.pluginmanager.getplugin('terminalreporter')
# if no terminal reporter plugin is present, nothing we can do here;
# this can happen when this function executes in a slave node
# when using pytest-xdist, for example
if tr is not None:
config._pastebinfile = tempfile.TemporaryFile('w+')
# pastebin file will be utf-8 encoded binary file
config._pastebinfile = tempfile.TemporaryFile('w+b')
oldwrite = tr._tw.write
def tee_write(s, **kwargs):
oldwrite(s, **kwargs)
config._pastebinfile.write(str(s))
if py.builtin._istext(s):
s = s.encode('utf-8')
config._pastebinfile.write(s)
tr._tw.write = tee_write
def pytest_unconfigure(config):
@@ -45,7 +49,7 @@ def create_new_paste(contents):
"""
Creates a new paste using bpaste.net service.
:contents: paste contents
:contents: paste contents as utf-8 encoded bytes
:returns: url to the pasted contents
"""
import re
@@ -61,8 +65,8 @@ def create_new_paste(contents):
'expiry': '1week',
}
url = 'https://bpaste.net'
response = urlopen(url, data=urlencode(params)).read()
m = re.search(r'href="/raw/(\w+)"', response)
response = urlopen(url, data=urlencode(params).encode('ascii')).read()
m = re.search(r'href="/raw/(\w+)"', response.decode('utf-8'))
if m:
return '%s/show/%s' % (url, m.group(1))
else:

View File

@@ -384,12 +384,13 @@ class PyobjMixin(PyobjContext):
def reportinfo(self):
# XXX caching?
obj = self.obj
if hasattr(obj, 'compat_co_firstlineno'):
compat_co_firstlineno = getattr(obj, 'compat_co_firstlineno', None)
if isinstance(compat_co_firstlineno, int):
# nose compatibility
fspath = sys.modules[obj.__module__].__file__
if fspath.endswith(".pyc"):
fspath = fspath[:-1]
lineno = obj.compat_co_firstlineno
lineno = compat_co_firstlineno
else:
fspath, lineno = getfslineno(obj)
modpath = self.getmodpath()
@@ -405,7 +406,10 @@ class PyCollector(PyobjMixin, pytest.Collector):
""" Look for the __test__ attribute, which is applied by the
@nose.tools.istest decorator
"""
return safe_getattr(obj, '__test__', False)
# We explicitly check for "is True" here to not mistakenly treat
# classes with a custom __getattr__ returning something truthy (like a
# function) as test classes.
return safe_getattr(obj, '__test__', False) is True
def classnamefilter(self, name):
return self._matches_prefix_or_glob_option('python_classes', name)

View File

@@ -29,18 +29,39 @@ def pytest_namespace():
def deprecated_call(func, *args, **kwargs):
"""Assert that ``func(*args, **kwargs)`` triggers a DeprecationWarning.
"""
wrec = WarningsRecorder()
with wrec:
warnings.simplefilter('always') # ensure all warnings are triggered
ret = func(*args, **kwargs)
""" assert that calling ``func(*args, **kwargs)`` triggers a
``DeprecationWarning`` or ``PendingDeprecationWarning``.
depwarnings = (DeprecationWarning, PendingDeprecationWarning)
if not any(r.category in depwarnings for r in wrec):
Note: we cannot use WarningsRecorder here because it is still subject
to the mechanism that prevents warnings of the same type from being
triggered twice for the same module. See #1190.
"""
categories = []
def warn_explicit(message, category, *args, **kwargs):
categories.append(category)
old_warn_explicit(message, category, *args, **kwargs)
def warn(message, category=None, **kwargs):
if isinstance(message, Warning):
categories.append(message.__class__)
else:
categories.append(category)
old_warn(message, category, *args, **kwargs)
old_warn = warnings.warn
old_warn_explicit = warnings.warn_explicit
warnings.warn_explicit = warn_explicit
warnings.warn = warn
try:
ret = func(*args, **kwargs)
finally:
warnings.warn_explicit = old_warn_explicit
warnings.warn = old_warn
deprecation_categories = (DeprecationWarning, PendingDeprecationWarning)
if not any(issubclass(c, deprecation_categories) for c in categories):
__tracebackhide__ = True
raise AssertionError("%r did not produce DeprecationWarning" % (func,))
return ret

View File

@@ -469,7 +469,7 @@ def skip(msg=""):
skip.Exception = Skipped
def fail(msg="", pytrace=True):
""" explicitely fail an currently-executing test with the given Message.
""" explicitly fail an currently-executing test with the given Message.
:arg pytrace: if false the msg represents the full failure information
and no python traceback will be reported.

View File

@@ -544,7 +544,11 @@ def build_summary_stats_line(stats):
if val:
key_name = key_translation.get(key, key)
parts.append("%d %s" % (len(val), key_name))
line = ", ".join(parts)
if parts:
line = ", ".join(parts)
else:
line = "no tests ran"
if 'failed' in stats or 'error' in stats:
color = 'red'

View File

@@ -573,7 +573,7 @@ class _MultiCall:
# XXX note that the __multicall__ argument is supported only
# for pytest compatibility reasons. It was never officially
# supported there and is explicitely deprecated since 2.8
# supported there and is explicitly deprecated since 2.8
# so we can remove it soon, allowing to avoid the below recursion
# in execute() and simplify/speed up the execute loop.

View File

@@ -5,6 +5,8 @@ Release announcements
.. toctree::
:maxdepth: 2
release-2.8.4
release-2.8.3
release-2.8.2
release-2.7.2

View File

@@ -0,0 +1,52 @@
pytest-2.8.4
============
pytest is a mature Python testing tool with more than a 1100 tests
against itself, passing on many different interpreters and platforms.
This release is supposed to be drop-in compatible to 2.8.2.
See below for the changes and see docs at:
http://pytest.org
As usual, you can upgrade from pypi via::
pip install -U pytest
Thanks to all who contributed to this release, among them:
Bruno Oliveira
Florian Bruhin
Jeff Widman
Mehdy Khoshnoody
Nicholas Chammas
Ronny Pfannschmidt
Tim Chan
Happy testing,
The py.test Development Team
2.8.4 (compared to 2.8.3)
-----------------------------
- fix #1190: ``deprecated_call()`` now works when the deprecated
function has been already called by another test in the same
module. Thanks Mikhail Chernykh for the report and Bruno Oliveira for the
PR.
- fix #1198: ``--pastebin`` option now works on Python 3. Thanks
Mehdy Khoshnoody for the PR.
- fix #1219: ``--pastebin`` now works correctly when captured output contains
non-ascii characters. Thanks Bruno Oliveira for the PR.
- fix #1204: another error when collecting with a nasty __getattr__().
Thanks Florian Bruhin for the PR.
- fix the summary printed when no tests did run.
Thanks Florian Bruhin for the PR.
- a number of documentation modernizations wrt good practices.
Thanks Bruno Oliveira for the PR.

View File

@@ -26,7 +26,7 @@ you will see the return value of the function call::
$ py.test test_assert1.py
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.3, py-1.4.30, pluggy-0.3.1
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile:
collected 1 items
@@ -146,7 +146,7 @@ if you run this module::
$ py.test test_assert2.py
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.3, py-1.4.30, pluggy-0.3.1
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile:
collected 1 items

View File

@@ -131,4 +131,4 @@ You can ask for available builtin or project-custom
directory. The returned object is a `py.path.local`_
path object.
in 0.12 seconds
no tests ran in 0.12 seconds

View File

@@ -5,7 +5,7 @@ Cache: working with cross-testrun state
.. warning::
The functionality of this core plugin was previosuly distributed
The functionality of this core plugin was previously distributed
as a third party plugin named ``pytest-cache``. The core plugin
is compatible regarding command line options and API usage except that you
can only store/receive data between test runs that is json-serializable.
@@ -80,7 +80,7 @@ If you then run it with ``--lf``::
$ py.test --lf
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.3, py-1.4.30, pluggy-0.3.1
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1
run-last-failure: rerun last 2 failures
rootdir: $REGENDOC_TMPDIR, inifile:
collected 50 items
@@ -121,7 +121,7 @@ of ``FF`` and dots)::
$ py.test --ff
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.3, py-1.4.30, pluggy-0.3.1
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1
run-last-failure: rerun last 2 failures first
rootdir: $REGENDOC_TMPDIR, inifile:
collected 50 items
@@ -226,7 +226,7 @@ You can always peek at the content of the cache using the
$ py.test --cache-clear
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.3, py-1.4.30, pluggy-0.3.1
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile:
collected 1 items

View File

@@ -64,7 +64,7 @@ of the failing function and hide the other one::
$ py.test
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.3, py-1.4.30, pluggy-0.3.1
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile:
collected 2 items

View File

@@ -162,7 +162,7 @@ Builtin configuration file options
.. versionadded:: 2.8
Sets list of directories that should be searched for tests when
no specific directories or files are given in the command line when
no specific directories, files or test ids are given in the command line when
executing pytest from the :ref:`rootdir <rootdir>` directory.
Useful when all project tests are in a known location to speed up
test collection and to avoid picking up undesired tests by accident.

View File

@@ -46,7 +46,7 @@ then you can just invoke ``py.test`` without command line options::
$ py.test
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.3, py-1.4.30, pluggy-0.3.1
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile: pytest.ini
collected 1 items

View File

@@ -31,7 +31,7 @@ You can then restrict a test run to only run tests marked with ``webtest``::
$ py.test -v -m webtest
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.3, py-1.4.30, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.4
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.4
cachedir: .cache
rootdir: $REGENDOC_TMPDIR, inifile:
collecting ... collected 4 items
@@ -45,7 +45,7 @@ Or the inverse, running all tests except the webtest ones::
$ py.test -v -m "not webtest"
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.3, py-1.4.30, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.4
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.4
cachedir: .cache
rootdir: $REGENDOC_TMPDIR, inifile:
collecting ... collected 4 items
@@ -66,7 +66,7 @@ tests based on their module, class, method, or function name::
$ py.test -v test_server.py::TestClass::test_method
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.3, py-1.4.30, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.4
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.4
cachedir: .cache
rootdir: $REGENDOC_TMPDIR, inifile:
collecting ... collected 5 items
@@ -79,7 +79,7 @@ You can also select on the class::
$ py.test -v test_server.py::TestClass
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.3, py-1.4.30, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.4
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.4
cachedir: .cache
rootdir: $REGENDOC_TMPDIR, inifile:
collecting ... collected 4 items
@@ -92,7 +92,7 @@ Or select multiple nodes::
$ py.test -v test_server.py::TestClass test_server.py::test_send_http
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.3, py-1.4.30, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.4
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.4
cachedir: .cache
rootdir: $REGENDOC_TMPDIR, inifile:
collecting ... collected 8 items
@@ -130,7 +130,7 @@ select tests based on their names::
$ py.test -v -k http # running with the above defined example module
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.3, py-1.4.30, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.4
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.4
cachedir: .cache
rootdir: $REGENDOC_TMPDIR, inifile:
collecting ... collected 4 items
@@ -144,7 +144,7 @@ And you can also run all tests except the ones that match the keyword::
$ py.test -k "not send_http" -v
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.3, py-1.4.30, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.4
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.4
cachedir: .cache
rootdir: $REGENDOC_TMPDIR, inifile:
collecting ... collected 4 items
@@ -160,7 +160,7 @@ Or to select "http" and "quick" tests::
$ py.test -k "http or quick" -v
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.3, py-1.4.30, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.4
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.4
cachedir: .cache
rootdir: $REGENDOC_TMPDIR, inifile:
collecting ... collected 4 items
@@ -219,7 +219,7 @@ For an example on how to add and work with markers from a plugin, see
.. note::
It is recommended to explicitely register markers so that:
It is recommended to explicitly register markers so that:
* there is one place in your test suite defining your markers
@@ -350,7 +350,7 @@ the test needs::
$ py.test -E stage2
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.3, py-1.4.30, pluggy-0.3.1
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile:
collected 1 items
@@ -362,7 +362,7 @@ and here is one that specifies exactly the environment needed::
$ py.test -E stage1
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.3, py-1.4.30, pluggy-0.3.1
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile:
collected 1 items
@@ -481,7 +481,7 @@ then you will see two test skipped and two executed tests as expected::
$ py.test -rs # this option reports skip reasons
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.3, py-1.4.30, pluggy-0.3.1
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile:
collected 4 items
@@ -495,7 +495,7 @@ Note that if you specify a platform via the marker-command line option like this
$ py.test -m linux2
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.3, py-1.4.30, pluggy-0.3.1
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile:
collected 4 items
@@ -547,7 +547,7 @@ We can now use the ``-m option`` to select one set::
$ py.test -m interface --tb=short
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.3, py-1.4.30, pluggy-0.3.1
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile:
collected 4 items
@@ -569,7 +569,7 @@ or to select both "event" and "interface" tests::
$ py.test -m "interface or event" --tb=short
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.3, py-1.4.30, pluggy-0.3.1
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile:
collected 4 items

View File

@@ -27,11 +27,11 @@ now execute the test specification::
nonpython $ py.test test_simple.yml
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.3, py-1.4.30, pluggy-0.3.1
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR/nonpython, inifile:
collected 2 items
test_simple.yml F.
test_simple.yml .F
======= FAILURES ========
_______ usecase: hello ________
@@ -59,13 +59,13 @@ consulted when reporting in ``verbose`` mode::
nonpython $ py.test -v
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.3, py-1.4.30, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.4
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.4
cachedir: .cache
rootdir: $REGENDOC_TMPDIR/nonpython, inifile:
collecting ... collected 2 items
test_simple.yml::hello FAILED
test_simple.yml::ok PASSED
test_simple.yml::hello FAILED
======= FAILURES ========
_______ usecase: hello ________
@@ -81,11 +81,11 @@ interesting to just look at the collection tree::
nonpython $ py.test --collect-only
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.3, py-1.4.30, pluggy-0.3.1
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR/nonpython, inifile:
collected 2 items
<YamlFile 'test_simple.yml'>
<YamlItem 'hello'>
<YamlItem 'ok'>
<YamlItem 'hello'>
======= in 0.12 seconds ========
======= no tests ran in 0.12 seconds ========

View File

@@ -130,7 +130,7 @@ objects, they are still using the default pytest representation::
$ py.test test_time.py --collect-only
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.3, py-1.4.30, pluggy-0.3.1
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile:
collected 6 items
<Module 'test_time.py'>
@@ -141,7 +141,7 @@ objects, they are still using the default pytest representation::
<Function 'test_timedistance_v2[20011212-20011211-expected0]'>
<Function 'test_timedistance_v2[20011211-20011212-expected1]'>
======= in 0.12 seconds ========
======= no tests ran in 0.12 seconds ========
A quick port of "testscenarios"
------------------------------------
@@ -181,7 +181,7 @@ this is a fully self-contained example which you can run with::
$ py.test test_scenarios.py
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.3, py-1.4.30, pluggy-0.3.1
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile:
collected 4 items
@@ -194,7 +194,7 @@ If you just collect tests you'll also nicely see 'advanced' and 'basic' as varia
$ py.test --collect-only test_scenarios.py
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.3, py-1.4.30, pluggy-0.3.1
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile:
collected 4 items
<Module 'test_scenarios.py'>
@@ -205,7 +205,7 @@ If you just collect tests you'll also nicely see 'advanced' and 'basic' as varia
<Function 'test_demo1[advanced]'>
<Function 'test_demo2[advanced]'>
======= in 0.12 seconds ========
======= no tests ran in 0.12 seconds ========
Note that we told ``metafunc.parametrize()`` that your scenario values
should be considered class-scoped. With pytest-2.3 this leads to a
@@ -259,14 +259,14 @@ Let's first see how it looks like at collection time::
$ py.test test_backends.py --collect-only
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.3, py-1.4.30, pluggy-0.3.1
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile:
collected 2 items
<Module 'test_backends.py'>
<Function 'test_db_initialized[d1]'>
<Function 'test_db_initialized[d2]'>
======= in 0.12 seconds ========
======= no tests ran in 0.12 seconds ========
And then when we run the test::
@@ -320,25 +320,25 @@ The result of this test will be successful::
$ py.test test_indirect_list.py --collect-only
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.3, py-1.4.30, pluggy-0.3.1
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile:
collected 1 items
<Module 'test_indirect_list.py'>
<Function 'test_indirect[a-b]'>
======= in 0.12 seconds ========
======= no tests ran in 0.12 seconds ========
.. regendoc:wipe
Parametrizing test methods through per-class configuration
--------------------------------------------------------------
.. _`unittest parameterizer`: http://code.google.com/p/unittest-ext/source/browse/trunk/params.py
.. _`unittest parametrizer`: http://code.google.com/p/unittest-ext/source/browse/trunk/params.py
Here is an example ``pytest_generate_function`` function implementing a
parametrization scheme similar to Michael Foord's `unittest
parameterizer`_ but in a lot less code::
parametrizer`_ but in a lot less code::
# content of ./test_parametrize.py
import pytest
@@ -399,8 +399,8 @@ Running it results in some skips if we don't have all the python interpreters in
. $ py.test -rs -q multipython.py
ssssssssssss...ssssssssssss
======= short test summary info ========
SKIP [12] $REGENDOC_TMPDIR/CWD/multipython.py:22: 'python3.3' not found
SKIP [12] $REGENDOC_TMPDIR/CWD/multipython.py:22: 'python2.6' not found
SKIP [12] $REGENDOC_TMPDIR/CWD/multipython.py:22: 'python3.3' not found
3 passed, 24 skipped in 0.12 seconds
Indirect parametrization of optional implementations/imports
@@ -448,7 +448,7 @@ If you run this with reporting for skips enabled::
$ py.test -rs test_module.py
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.3, py-1.4.30, pluggy-0.3.1
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile:
collected 2 items

View File

@@ -82,7 +82,7 @@ then the test collection looks like this::
$ py.test --collect-only
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.3, py-1.4.30, pluggy-0.3.1
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile: setup.cfg
collected 2 items
<Module 'check_myapp.py'>
@@ -91,7 +91,7 @@ then the test collection looks like this::
<Function 'simple_check'>
<Function 'complex_check'>
======= in 0.12 seconds ========
======= no tests ran in 0.12 seconds ========
.. note::
@@ -128,7 +128,7 @@ You can always peek at the collection tree without running tests like this::
. $ py.test --collect-only pythoncollection.py
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.3, py-1.4.30, pluggy-0.3.1
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile: pytest.ini
collected 3 items
<Module 'CWD/pythoncollection.py'>
@@ -138,7 +138,7 @@ You can always peek at the collection tree without running tests like this::
<Function 'test_method'>
<Function 'test_anothermethod'>
======= in 0.12 seconds ========
======= no tests ran in 0.12 seconds ========
customizing test collection to find all .py files
---------------------------------------------------------
@@ -175,18 +175,18 @@ And then if you have a module file like this::
and a setup.py dummy file like this::
# content of setup.py
0/0 # will raise exeption if imported
0/0 # will raise exception if imported
then a pytest run on python2 will find the one test when run with a python2
interpreters and will leave out the setup.py file::
$ py.test --collect-only
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.3, py-1.4.30, pluggy-0.3.1
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile: pytest.ini
collected 0 items
======= in 0.12 seconds ========
======= no tests ran in 0.12 seconds ========
If you run with a Python3 interpreter the moduled added through the conftest.py file will not be considered for test collection.

View File

@@ -13,7 +13,7 @@ get on the terminal - we are working on that):
assertion $ py.test failure_demo.py
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.3, py-1.4.30, pluggy-0.3.1
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR/assertion, inifile:
collected 42 items
@@ -361,7 +361,7 @@ get on the terminal - we are working on that):
> int(s)
E ValueError: invalid literal for int() with base 10: 'qwe'
<0-codegen $PYTHON_PREFIX/lib/python3.4/site-packages/_pytest/python.py:1296>:1: ValueError
<0-codegen $PYTHON_PREFIX/lib/python3.4/site-packages/_pytest/python.py:1300>:1: ValueError
_______ TestRaises.test_raises_doesnt ________
self = <failure_demo.TestRaises object at 0xdeadbeef>

View File

@@ -108,11 +108,11 @@ directory with the above conftest.py::
$ py.test
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.3, py-1.4.30, pluggy-0.3.1
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile:
collected 0 items
======= in 0.12 seconds ========
======= no tests ran in 0.12 seconds ========
.. _`excontrolskip`:
@@ -156,7 +156,7 @@ and when running it will see a skipped "slow" test::
$ py.test -rs # "-rs" means report details on the little 's'
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.3, py-1.4.30, pluggy-0.3.1
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile:
collected 2 items
@@ -170,7 +170,7 @@ Or run it including the ``slow`` marked test::
$ py.test --runslow
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.3, py-1.4.30, pluggy-0.3.1
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile:
collected 2 items
@@ -262,12 +262,12 @@ which will add the string to the test header accordingly::
$ py.test
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.3, py-1.4.30, pluggy-0.3.1
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1
project deps: mylib-1.1
rootdir: $REGENDOC_TMPDIR, inifile:
collected 0 items
======= in 0.12 seconds ========
======= no tests ran in 0.12 seconds ========
.. regendoc:wipe
@@ -286,24 +286,24 @@ which will add info only when run with "--v"::
$ py.test -v
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.3, py-1.4.30, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.4
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.4
cachedir: .cache
info1: did you know that ...
did you?
rootdir: $REGENDOC_TMPDIR, inifile:
collecting ... collected 0 items
======= in 0.12 seconds ========
======= no tests ran in 0.12 seconds ========
and nothing when run plainly::
$ py.test
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.3, py-1.4.30, pluggy-0.3.1
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile:
collected 0 items
======= in 0.12 seconds ========
======= no tests ran in 0.12 seconds ========
profiling test duration
--------------------------
@@ -313,7 +313,7 @@ profiling test duration
.. versionadded: 2.2
If you have a slow running large test suite you might want to find
out which tests are the slowest. Let's make an artifical test suite::
out which tests are the slowest. Let's make an artificial test suite::
# content of test_some_are_slow.py
@@ -332,7 +332,7 @@ Now we can profile which test functions execute the slowest::
$ py.test --durations=3
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.3, py-1.4.30, pluggy-0.3.1
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile:
collected 3 items
@@ -341,7 +341,7 @@ Now we can profile which test functions execute the slowest::
======= slowest 3 test durations ========
0.20s call test_some_are_slow.py::test_funcslow2
0.10s call test_some_are_slow.py::test_funcslow1
0.00s setup test_some_are_slow.py::test_funcslow2
0.00s teardown test_some_are_slow.py::test_funcslow2
======= 3 passed in 0.12 seconds ========
incremental testing - test steps
@@ -394,7 +394,7 @@ If we run this::
$ py.test -rx
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.3, py-1.4.30, pluggy-0.3.1
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile:
collected 4 items
@@ -427,7 +427,7 @@ by placing fixture functions in a ``conftest.py`` file in that directory
You can use all types of fixtures including :ref:`autouse fixtures
<autouse fixtures>` which are the equivalent of xUnit's setup/teardown
concept. It's however recommended to have explicit fixture references in your
tests or test classes rather than relying on implicitely executing
tests or test classes rather than relying on implicitly executing
setup/teardown functions, especially if they are far away from the actual tests.
Here is a an example for making a ``db`` fixture available in a directory::
@@ -465,7 +465,7 @@ We can run this::
$ py.test
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.3, py-1.4.30, pluggy-0.3.1
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile:
collected 7 items
@@ -479,7 +479,7 @@ We can run this::
file $REGENDOC_TMPDIR/b/test_error.py, line 1
def test_root(db): # no db here, will error out
fixture 'db' not found
available fixtures: monkeypatch, recwarn, pytestconfig, record_xml_property, capsys, cache, tmpdir, capfd, tmpdir_factory
available fixtures: tmpdir, record_xml_property, cache, capsys, monkeypatch, recwarn, pytestconfig, tmpdir_factory, capfd
use 'py.test --fixtures [testpath]' for help on them.
$REGENDOC_TMPDIR/b/test_error.py:1
@@ -569,7 +569,7 @@ and run them::
$ py.test test_module.py
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.3, py-1.4.30, pluggy-0.3.1
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile:
collected 2 items
@@ -660,7 +660,7 @@ and run it::
$ py.test -s test_module.py
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.3, py-1.4.30, pluggy-0.3.1
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile:
collected 3 items

View File

@@ -60,7 +60,7 @@ and customizable testing framework for Python. Note, however, that
thus likely not something for Python beginners.
A second "magic" issue was the assert statement debugging feature.
Nowadays, ``pytest`` explicitely rewrites assert statements in test modules
Nowadays, ``pytest`` explicitly rewrites assert statements in test modules
in order to provide more useful :ref:`assert feedback <assertfeedback>`.
This completely avoids previous issues of confusing assertion-reporting.
It also means, that you can use Python's ``-O`` optimization without losing
@@ -76,7 +76,7 @@ be the same, confusing the reinterpreter and obfuscating the initial
error (this is also explained at the command line if it happens).
You can also turn off all assertion interaction using the
``--assertmode=off`` option.
``--assert=plain`` option.
.. _`py namespaces`: index.html
.. _`py/__init__.py`: http://bitbucket.org/hpk42/py-trunk/src/trunk/py/__init__.py

View File

@@ -75,7 +75,7 @@ marked ``smtp`` fixture function. Running the test looks like this::
$ py.test test_smtpsimple.py
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.3, py-1.4.30, pluggy-0.3.1
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile:
collected 1 items
@@ -193,7 +193,7 @@ inspect what is going on and can now run the tests::
$ py.test test_module.py
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.3, py-1.4.30, pluggy-0.3.1
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile:
collected 2 items
@@ -480,7 +480,7 @@ Running the above tests results in the following test IDs being used::
$ py.test --collect-only
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.3, py-1.4.30, pluggy-0.3.1
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile:
collected 10 items
<Module 'test_anothersmtp.py'>
@@ -497,7 +497,7 @@ Running the above tests results in the following test IDs being used::
<Function 'test_ehlo[mail.python.org]'>
<Function 'test_noop[mail.python.org]'>
======= in 0.12 seconds ========
======= no tests ran in 0.12 seconds ========
.. _`interdependent fixtures`:
@@ -531,7 +531,7 @@ Here we declare an ``app`` fixture which receives the previously defined
$ py.test -v test_appsetup.py
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.3, py-1.4.30, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.4
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.4
cachedir: .cache
rootdir: $REGENDOC_TMPDIR, inifile:
collecting ... collected 2 items
@@ -597,7 +597,7 @@ Let's run the tests in verbose mode and with looking at the print-output::
$ py.test -v -s test_module.py
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.3, py-1.4.30, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.4
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1 -- $PYTHON_PREFIX/bin/python3.4
cachedir: .cache
rootdir: $REGENDOC_TMPDIR, inifile:
collecting ... collected 8 items

View File

@@ -209,7 +209,7 @@ fixtures:
and let pytest figure things out for you.
* if you used parametrization and funcarg factories which made use of
``request.cached_setup()`` it is recommeneded to invest a few minutes
``request.cached_setup()`` it is recommended to invest a few minutes
and simplify your fixture function code to use the :ref:`@pytest.fixture`
decorator instead. This will also allow to take advantage of
the automatic per-resource grouping of tests.

View File

@@ -27,7 +27,7 @@ Installation options::
To check your installation has installed the correct version::
$ py.test --version
This is pytest version 2.8.3, imported from $PYTHON_PREFIX/lib/python3.4/site-packages/pytest.py
This is pytest version 2.8.4, imported from $PYTHON_PREFIX/lib/python3.4/site-packages/pytest.py
If you get an error checkout :ref:`installation issues`.
@@ -49,7 +49,7 @@ That's it. You can execute the test function now::
$ py.test
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.3, py-1.4.30, pluggy-0.3.1
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile:
collected 1 items

View File

@@ -4,29 +4,28 @@
Good Integration Practices
=================================================
Work with virtual environments
-----------------------------------------------------------
We recommend to use virtualenv_ environments and use pip_
(or easy_install_) for installing your application and any dependencies
as well as the ``pytest`` package itself. This way you will get an isolated
and reproducible environment. Given you have installed virtualenv_
and execute it from the command line, here is an example session for unix
or windows::
.. _`test discovery`:
.. _`Python test discovery`:
virtualenv . # create a virtualenv directory in the current directory
Conventions for Python test discovery
-------------------------------------------------
source bin/activate # on unix
``pytest`` implements the following standard test discovery:
scripts/activate # on Windows
* If no arguments are specified then collection starts from :confval:`testpaths`
(if configured) or the current directory. Alternatively, command line arguments
can be used in any combination of directories, file names or node ids.
* recurse into directories, unless they match :confval:`norecursedirs`
* ``test_*.py`` or ``*_test.py`` files, imported by their `test package name`_.
* ``Test`` prefixed test classes (without an ``__init__`` method)
* ``test_`` prefixed test functions or methods are test items
We can now install pytest::
For examples of how to customize your test discovery :doc:`example/pythoncollection`.
pip install pytest
Within Python modules, ``pytest`` also discovers tests using the standard
:ref:`unittest.TestCase <unittest.TestCase>` subclassing technique.
Due to the ``activate`` step above the ``pip`` will come from
the virtualenv directory and install any package into the isolated
virtual environment.
Choosing a test layout / import rules
------------------------------------------
@@ -135,8 +134,13 @@ required configurations.
.. _`use tox`:
Use tox and Continuous Integration servers
-------------------------------------------------
Tox
------
For development, we recommend to use virtualenv_ environments and pip_
for installing your application and any dependencies
as well as the ``pytest`` package itself. This ensures your code and
dependencies are isolated from the system Python installation.
If you frequently release code and want to make sure that your actual
package passes all tests you may want to look into `tox`_, the
@@ -148,45 +152,21 @@ options. It will run tests against the installed package and not
against your source code checkout, helping to detect packaging
glitches.
If you want to use Jenkins_ you can use the ``--junitxml=PATH`` option
to create a JUnitXML file that Jenkins_ can pick up and generate reports.
.. _standalone:
.. _`genscript method`:
(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
a standalone ``pytest`` script::
py.test --genscript=runtests.py
This generates a ``runtests.py`` script which is a fully functional basic
``pytest`` script, running unchanged under Python2 and Python3.
You can tell people to download the script and then e.g. run it like this::
python runtests.py
.. note::
You must have pytest and its dependencies installed as an sdist, not
as wheels because genscript need the source code for generating a
standalone script.
Continuous integration services such as Jenkins_ can make use of the
``--junitxml=PATH`` option to create a JUnitXML file and generate reports.
Integrating with setuptools / ``python setup.py test`` / ``pytest-runner``
--------------------------------------------------------------------------
You can integrate test runs into your setuptools based project
with pytest-runner.
with the `pytest-runner <https://pypi.python.org/pypi/pytest-runner>`_ plugin.
Add this to ``setup.py`` file::
Add this to ``setup.py`` file:
from distutils.core import setup
# you can also import from setuptools
.. code-block:: python
from setuptools import setup
setup(
#...,
@@ -195,7 +175,11 @@ Add this to ``setup.py`` file::
#...,
)
And create an alias into ``setup.cfg``file::
And create an alias into ``setup.cfg`` file:
.. code-block:: ini
[aliases]
test=pytest
@@ -210,59 +194,14 @@ required for calling the test command. You can also pass additional
arguments to py.test such as your test directory or other
options using ``--addopts``.
Integrating with setuptools / ``python setup.py test`` / ``genscript``
----------------------------------------------------------------------
You can integrate test runs into your
setuptools based project. Use the `genscript method`_
to generate a standalone ``pytest`` script::
Manual Integration
^^^^^^^^^^^^^^^^^^
py.test --genscript=runtests.py
If for some reason you don't want/can't use ``pytest-runner``, you can write
your own setuptools Test command for invoking pytest.
and make this script part of your distribution and then add
this to your ``setup.py`` file::
from distutils.core import setup, Command
# you can also import from setuptools
class PyTest(Command):
user_options = []
def initialize_options(self):
pass
def finalize_options(self):
pass
def run(self):
import subprocess
import sys
errno = subprocess.call([sys.executable, 'runtests.py'])
raise SystemExit(errno)
setup(
#...,
cmdclass = {'test': PyTest},
#...,
)
If you now type::
python setup.py test
this will execute your tests using ``runtests.py``. As this is a
standalone version of ``pytest`` no prior installation whatsoever is
required for calling the test command. You can also pass additional
arguments to the subprocess-calls such as your test directory or other
options.
Integration with setuptools test commands
----------------------------------------------------
Setuptools supports writing our own Test command for invoking pytest.
Most often it is better to use tox_ instead, but here is how you can
get started with setuptools integration::
.. code-block:: python
import sys
@@ -276,11 +215,6 @@ get started with setuptools integration::
TestCommand.initialize_options(self)
self.pytest_args = []
def finalize_options(self):
TestCommand.finalize_options(self)
self.test_args = []
self.test_suite = True
def run_tests(self):
#import here, cause outside the eggs aren't loaded
import pytest
@@ -306,32 +240,39 @@ using the ``--pytest-args`` or ``-a`` command-line option. For example::
is equivalent to running ``py.test --durations=5``.
.. seealso::
For a more powerful solution, take a look at the
`pytest-runner <https://pypi.python.org/pypi/pytest-runner>`_ plugin.
.. _standalone:
.. _`genscript method`:
.. _`test discovery`:
.. _`Python test discovery`:
(deprecated) Create a pytest standalone script
-----------------------------------------------
Conventions for Python test discovery
-------------------------------------------------
.. deprecated:: 2.8
``pytest`` implements the following standard test discovery:
.. note::
* collection starts from paths specified in :confval:`testpaths` if configured,
otherwise from initial command line arguments which may be directories,
filenames or test ids. If :confval:`testpaths` is not configured and no
directories or files were given in the command line, start collection from
the current directory.
* recurse into directories, unless they match :confval:`norecursedirs`
* ``test_*.py`` or ``*_test.py`` files, imported by their `test package name`_.
* ``Test`` prefixed test classes (without an ``__init__`` method)
* ``test_`` prefixed test functions or methods are test items
``genscript`` has been deprecated because:
For examples of how to customize your test discovery :doc:`example/pythoncollection`.
* It cannot support plugins, rendering its usefulness extremely limited;
* Tooling has become much better since ``genscript`` was introduced;
* It is possible to build a zipped ``pytest`` application without the
shortcomings above.
There's no planned version in which this command will be removed
at the moment of this writing, but its use is discouraged for new
applications.
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
a standalone ``pytest`` script::
py.test --genscript=runtests.py
This generates a ``runtests.py`` script which is a fully functional basic
``pytest`` script, running unchanged under Python2 and Python3.
You can tell people to download the script and then e.g. run it like this::
python runtests.py
Within Python modules, ``pytest`` also discovers tests using the standard
:ref:`unittest.TestCase <unittest.TestCase>` subclassing technique.
.. include:: links.inc

View File

@@ -55,7 +55,7 @@ them in turn::
$ py.test
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.3, py-1.4.30, pluggy-0.3.1
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile:
collected 3 items
@@ -103,7 +103,7 @@ Let's run this::
$ py.test
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.3, py-1.4.30, pluggy-0.3.1
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile:
collected 3 items
@@ -201,7 +201,7 @@ list::
$ py.test -q -rs test_strings.py
s
======= short test summary info ========
SKIP [1] $PYTHON_PREFIX/lib/python3.4/site-packages/_pytest/python.py:1413: got empty parameter set, function test_valid_string at $REGENDOC_TMPDIR/test_strings.py:1
SKIP [1] $PYTHON_PREFIX/lib/python3.4/site-packages/_pytest/python.py:1417: got empty parameter set, function test_valid_string at $REGENDOC_TMPDIR/test_strings.py:1
1 skipped in 0.12 seconds
For further examples, you might want to look at :ref:`more

View File

@@ -83,8 +83,8 @@ 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',
reason="requires windows")
@pytest.mark.skipif(sys.platform == 'win32',
reason="does not run on windows")
class TestPosixCalls:
def test_function(self):
@@ -97,8 +97,8 @@ 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',
reason="requires Windows")
pytestmark = pytest.mark.skipif(sys.platform == 'win32',
reason="does not run on windows")
def test_function(self):
"will not be setup or run under 'win32' platform"
@@ -165,7 +165,7 @@ Running it with the report-on-xfail option gives this output::
example $ py.test -rx xfail_demo.py
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.3, py-1.4.30, pluggy-0.3.1
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR/example, inifile:
collected 7 items

View File

@@ -29,7 +29,7 @@ Running this would result in a passed test except for the last
$ py.test test_tmpdir.py
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.3, py-1.4.30, pluggy-0.3.1
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile:
collected 1 items

View File

@@ -88,7 +88,7 @@ the ``self.db`` values in the traceback::
$ py.test test_unittest_db.py
======= test session starts ========
platform linux -- Python 3.4.3, pytest-2.8.3, py-1.4.30, pluggy-0.3.1
platform linux -- Python 3.4.3, pytest-2.8.4, py-1.4.30, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile:
collected 2 items
@@ -126,7 +126,7 @@ when writing the class-scoped fixture function above.
autouse fixtures and accessing other fixtures
-------------------------------------------------------------------
Although it's usually better to explicitely declare use of fixtures you need
Although it's usually better to explicitly declare use of fixtures you need
for a given test, you may sometimes want to have fixtures that are
automatically used in a given context. After all, the traditional
style of unittest-setup mandates the use of this implicit fixture writing

View File

@@ -123,7 +123,7 @@ automatically disables its output capture when you enter PDB_ tracing:
such.
* Any later output produced within the same test will not be captured and will
instead get sent directly to ``sys.stdout``. Note that this holds true even
for test output occuring after you exit the interactive PDB_ tracing session
for test output occurring after you exit the interactive PDB_ tracing session
and continue with the regular test run.
.. versionadded: 2.4.0

View File

@@ -204,7 +204,7 @@ plugin. Given that you have an installed plugin you can enable the
:py:class:`testdir <_pytest.pytester.Testdir>` fixture via specifying a
command line option to include the pytester plugin (``-p pytester``) or
by putting ``pytest_plugins = "pytester"`` into your test or
``conftest.py`` file. You then will have a ``testdir`` fixure which you
``conftest.py`` file. You then will have a ``testdir`` fixture which you
can use like this::
# content of test_myplugin.py
@@ -386,7 +386,7 @@ are expected.
For an example, see `newhooks.py`_ from :ref:`xdist`.
.. _`newhooks.py`: https://bitbucket.org/pytest-dev/pytest-xdist/src/52082f70e7dd04b00361091b8af906c60fd6700f/xdist/newhooks.py?at=default
.. _`newhooks.py`: https://github.com/pytest-dev/pytest-xdist/blob/974bd566c599dc6a9ea291838c6f226197208b46/xdist/newhooks.py
Optionally using hooks from 3rd party plugins
@@ -501,7 +501,7 @@ reporting or interaction with exceptions:
.. autofunction:: pytest_internalerror
.. autofunction:: pytest_keyboard_interrupt
.. autofunction:: pytest_exception_interact
.. autofunction:: pytest_enter_pdb
Reference of objects involved in hooks

View File

@@ -880,6 +880,21 @@ class TestReportInfo:
pass
"""
def test_reportinfo_with_nasty_getattr(self, testdir):
# https://github.com/pytest-dev/pytest/issues/1204
modcol = testdir.getmodulecol("""
# lineno 0
class TestClass:
def __getattr__(self, name):
return "this is not an int"
def test_foo(self):
pass
""")
classcol = testdir.collect_by_name(modcol, "TestClass")
instance = classcol.collect()[0]
fspath, lineno, msg = instance.reportinfo()
def test_customized_python_discovery(testdir):
testdir.makeini("""

View File

@@ -283,6 +283,35 @@ class TestNoselikeTestAttribute:
assert len(call.items) == 1
assert call.items[0].cls.__name__ == "TC"
def test_class_with_nasty_getattr(self, testdir):
"""Make sure we handle classes with a custom nasty __getattr__ right.
With a custom __getattr__ which e.g. returns a function (like with a
RPC wrapper), we shouldn't assume this meant "__test__ = True".
"""
# https://github.com/pytest-dev/pytest/issues/1204
testdir.makepyfile("""
class MetaModel(type):
def __getattr__(cls, key):
return lambda: None
BaseModel = MetaModel('Model', (), {})
class Model(BaseModel):
__metaclass__ = MetaModel
def test_blah(self):
pass
""")
reprec = testdir.inline_run()
assert not reprec.getfailedcollections()
call = reprec.getcalls("pytest_collection_modifyitems")[0]
assert not call.items
@pytest.mark.issue351
class TestParameterize:

View File

@@ -1,7 +1,8 @@
# encoding: utf-8
import sys
import pytest
class TestPasting:
class TestPasteCapture:
@pytest.fixture
def pastebinlist(self, monkeypatch, request):
@@ -27,6 +28,7 @@ class TestPasting:
assert reprec.countoutcomes() == [1,1,1]
def test_all(self, testdir, pastebinlist):
from _pytest.pytester import LineMatcher
testpath = testdir.makepyfile("""
import pytest
def test_pass():
@@ -39,9 +41,34 @@ class TestPasting:
reprec = testdir.inline_run(testpath, "--pastebin=all", '-v')
assert reprec.countoutcomes() == [1,1,1]
assert len(pastebinlist) == 1
s = pastebinlist[0]
for x in 'test_fail test_skip test_pass'.split():
assert x in s
contents = pastebinlist[0].decode('utf-8')
matcher = LineMatcher(contents.splitlines())
matcher.fnmatch_lines([
'*test_pass PASSED*',
'*test_fail FAILED*',
'*test_skip SKIPPED*',
'*== 1 failed, 1 passed, 1 skipped in *'
])
def test_non_ascii_paste_text(self, testdir):
"""Make sure that text which contains non-ascii characters is pasted
correctly. See #1219.
"""
testdir.makepyfile(test_unicode="""
# encoding: utf-8
def test():
assert '' == 1
""")
result = testdir.runpytest('--pastebin=all')
if sys.version_info[0] == 3:
expected_msg = "*assert '' == 1*"
else:
expected_msg = "*assert '\\xe2\\x98\\xba' == 1*"
result.stdout.fnmatch_lines([
expected_msg,
"*== 1 failed in *",
'*Sending information to Paste Service*',
])
class TestPaste:
@@ -62,7 +89,7 @@ class TestPaste:
class DummyFile:
def read(self):
# part of html of a normal response
return 'View <a href="/raw/3c0c6750bd">raw</a>.'
return b'View <a href="/raw/3c0c6750bd">raw</a>.'
return DummyFile()
if sys.version_info < (3, 0):
@@ -74,14 +101,15 @@ class TestPaste:
return calls
def test_create_new_paste(self, pastebin, mocked_urlopen):
result = pastebin.create_new_paste('full-paste-contents')
result = pastebin.create_new_paste(b'full-paste-contents')
assert result == 'https://bpaste.net/show/3c0c6750bd'
assert len(mocked_urlopen) == 1
url, data = mocked_urlopen[0]
assert type(data) is bytes
lexer = 'python3' if sys.version_info[0] == 3 else 'python'
assert url == 'https://bpaste.net'
assert 'lexer=%s' % lexer in data
assert 'code=full-paste-contents' in data
assert 'expiry=1week' in data
assert 'lexer=%s' % lexer in data.decode()
assert 'code=full-paste-contents' in data.decode()
assert 'expiry=1week' in data.decode()

View File

@@ -63,32 +63,30 @@ class TestWarningsRecorderChecker(object):
with rec:
pass # can't enter twice
#
# ============ test pytest.deprecated_call() ==============
#
def dep(i):
if i == 0:
py.std.warnings.warn("is deprecated", DeprecationWarning)
return 42
reg = {}
def dep_explicit(i):
if i == 0:
py.std.warnings.warn_explicit("dep_explicit", category=DeprecationWarning,
filename="hello", lineno=3)
class TestDeprecatedCall(object):
"""test pytest.deprecated_call()"""
def dep(self, i):
if i == 0:
py.std.warnings.warn("is deprecated", DeprecationWarning)
return 42
def dep_explicit(self, i):
if i == 0:
py.std.warnings.warn_explicit("dep_explicit", category=DeprecationWarning,
filename="hello", lineno=3)
def test_deprecated_call_raises(self):
excinfo = pytest.raises(AssertionError,
"pytest.deprecated_call(dep, 3)")
with pytest.raises(AssertionError) as excinfo:
pytest.deprecated_call(self.dep, 3)
assert str(excinfo).find("did not produce") != -1
def test_deprecated_call(self):
pytest.deprecated_call(dep, 0)
pytest.deprecated_call(self.dep, 0)
def test_deprecated_call_ret(self):
ret = pytest.deprecated_call(dep, 0)
ret = pytest.deprecated_call(self.dep, 0)
assert ret == 42
def test_deprecated_call_preserves(self):
@@ -104,25 +102,48 @@ class TestDeprecatedCall(object):
assert warn_explicit is py.std.warnings.warn_explicit
def test_deprecated_explicit_call_raises(self):
pytest.raises(AssertionError,
"pytest.deprecated_call(dep_explicit, 3)")
with pytest.raises(AssertionError):
pytest.deprecated_call(self.dep_explicit, 3)
def test_deprecated_explicit_call(self):
pytest.deprecated_call(dep_explicit, 0)
pytest.deprecated_call(dep_explicit, 0)
pytest.deprecated_call(self.dep_explicit, 0)
pytest.deprecated_call(self.dep_explicit, 0)
def test_deprecated_call_pending(self):
f = lambda: py.std.warnings.warn(PendingDeprecationWarning("hi"))
def f():
py.std.warnings.warn(PendingDeprecationWarning("hi"))
pytest.deprecated_call(f)
def test_deprecated_call_specificity(self):
other_warnings = [Warning, UserWarning, SyntaxWarning, RuntimeWarning,
FutureWarning, ImportWarning, UnicodeWarning]
for warning in other_warnings:
f = lambda: py.std.warnings.warn(warning("hi"))
def f():
py.std.warnings.warn(warning("hi"))
with pytest.raises(AssertionError):
pytest.deprecated_call(f)
def test_deprecated_function_already_called(self, testdir):
"""deprecated_call should be able to catch a call to a deprecated
function even if that function has already been called in the same
module. See #1190.
"""
testdir.makepyfile("""
import warnings
import pytest
def deprecated_function():
warnings.warn("deprecated", DeprecationWarning)
def test_one():
deprecated_function()
def test_two():
pytest.deprecated_call(deprecated_function)
""")
result = testdir.runpytest()
result.stdout.fnmatch_lines('*=== 2 passed in *===')
class TestWarns(object):
def test_strings(self):

View File

@@ -779,10 +779,10 @@ def test_terminal_summary(testdir):
("green", "1 passed, 1 xpassed", {"xpassed": (1,), "passed": (1,)}),
# Likewise if no tests were found at all
("yellow", "", {}),
("yellow", "no tests ran", {}),
# Test the empty-key special case
("yellow", "", {"": (1,)}),
("yellow", "no tests ran", {"": (1,)}),
("green", "1 passed", {"": (1,), "passed": (1,)}),