Compare commits
32 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4b395d56cc | ||
|
|
018860d626 | ||
|
|
19a76337a4 | ||
|
|
0780f2573f | ||
|
|
cec7d47c1f | ||
|
|
3d00cd35fc | ||
|
|
5aa5b9748d | ||
|
|
cb65c56037 | ||
|
|
ae090740c5 | ||
|
|
2248a31a44 | ||
|
|
9fdfa155fb | ||
|
|
e49eca8d59 | ||
|
|
263b0e7d99 | ||
|
|
42b1033385 | ||
|
|
05f6422392 | ||
|
|
f83a65c8ae | ||
|
|
071960250f | ||
|
|
16d98541f2 | ||
|
|
2b8f4214c3 | ||
|
|
d3c9927fee | ||
|
|
acc5679bc8 | ||
|
|
2ba77cb1f4 | ||
|
|
8f65418d34 | ||
|
|
8ae79e09c0 | ||
|
|
c62bfaefd6 | ||
|
|
236fff00ad | ||
|
|
9b9355b8da | ||
|
|
446bcf44fb | ||
|
|
1db6fc87c7 | ||
|
|
895d52471b | ||
|
|
d226b2faf4 | ||
|
|
74ea94625a |
2
.hgtags
2
.hgtags
@@ -60,3 +60,5 @@ b93ac0cdae02effaa3c136a681cc45bba757fe46 1.4.14
|
||||
0000000000000000000000000000000000000000 1.4.14
|
||||
0000000000000000000000000000000000000000 1.4.14
|
||||
0000000000000000000000000000000000000000 1.4.14
|
||||
af860de70cc3f157ac34ca1d4bf557a057bff775 2.4.0
|
||||
8828c924acae0b4cad2e2cb92943d51da7cb744a 2.4.1
|
||||
|
||||
47
CHANGELOG
47
CHANGELOG
@@ -1,3 +1,50 @@
|
||||
Changes between 2.4.1 and 2.4.2
|
||||
-----------------------------------
|
||||
|
||||
- on Windows require colorama and a newer py lib so that py.io.TerminalWriter()
|
||||
now uses colorama instead of its own ctypes hacks. (fixes issue365)
|
||||
thanks Paul Moore for bringing it up.
|
||||
|
||||
- fix "-k" matching of tests where "repr" and "attr" and other names would
|
||||
cause wrong matches because of an internal implementation quirk
|
||||
(don't ask) which is now properly implemented. fixes issue345.
|
||||
|
||||
- avoid tmpdir fixture to create too long filenames especially
|
||||
when parametrization is used (issue354)
|
||||
|
||||
- fix pytest-pep8 and pytest-flakes / pytest interactions
|
||||
(collection names in mark plugin was assuming an item always
|
||||
has a function which is not true for those plugins etc.)
|
||||
Thanks Andi Zeidler.
|
||||
|
||||
- introduce node.get_marker/node.add_marker API for plugins
|
||||
like pytest-pep8 and pytest-flakes to avoid the messy
|
||||
details of the node.keywords pseudo-dicts. Adapated
|
||||
docs.
|
||||
|
||||
- remove attempt to "dup" stdout at startup as it's icky.
|
||||
the normal capturing should catch enough possibilities
|
||||
of tests messing up standard FDs.
|
||||
|
||||
- add pluginmanager.do_configure(config) as a link to
|
||||
config.do_configure() for plugin-compatibility
|
||||
|
||||
Changes between 2.4.0 and 2.4.1
|
||||
-----------------------------------
|
||||
|
||||
- When using parser.addoption() unicode arguments to the
|
||||
"type" keyword should also be converted to the respective types.
|
||||
thanks Floris Bruynooghe, @dnozay. (fixes issue360 and issue362)
|
||||
|
||||
- fix dotted filename completion when using argcomplete
|
||||
thanks Anthon van der Neuth. (fixes issue361)
|
||||
|
||||
- fix regression when a 1-tuple ("arg",) is used for specifying
|
||||
parametrization (the values of the parametrization were passed
|
||||
nested in a tuple). Thanks Donald Stufft.
|
||||
|
||||
- merge doc typo fixes, thanks Andy Dirnberger
|
||||
|
||||
Changes between 2.3.5 and 2.4
|
||||
-----------------------------------
|
||||
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
|
||||
Changelog: http://pytest.org/latest/changelog.html
|
||||
|
||||
The ``py.test`` testing tool makes it easy to write small tests, yet
|
||||
scales to support complex functional testing. It provides
|
||||
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
#
|
||||
__version__ = '2.4.0'
|
||||
__version__ = '2.4.2'
|
||||
|
||||
@@ -74,9 +74,13 @@ class FastFilesCompleter:
|
||||
else:
|
||||
prefix_dir = 0
|
||||
completion = []
|
||||
globbed = []
|
||||
if '*' not in prefix and '?' not in prefix:
|
||||
if prefix[-1] == os.path.sep: # we are on unix, otherwise no bash
|
||||
globbed.extend(glob(prefix + '.*'))
|
||||
prefix += '*'
|
||||
for x in sorted(glob(prefix)):
|
||||
globbed.extend(glob(prefix))
|
||||
for x in sorted(globbed):
|
||||
if os.path.isdir(x):
|
||||
x += '/'
|
||||
# append stripping the prefix (like bash, not like compgen)
|
||||
|
||||
@@ -3,7 +3,6 @@ support for presenting detailed information in failing assertions.
|
||||
"""
|
||||
import py
|
||||
import sys
|
||||
import pytest
|
||||
from _pytest.monkeypatch import monkeypatch
|
||||
from _pytest.assertion import util
|
||||
|
||||
@@ -19,7 +18,7 @@ def pytest_addoption(parser):
|
||||
to provide assert expression information. """)
|
||||
group.addoption('--no-assert', action="store_true", default=False,
|
||||
dest="noassert", help="DEPRECATED equivalent to --assert=plain")
|
||||
group.addoption('--nomagic', '--no-magic', action="store_true",
|
||||
group.addoption('--nomagic', '--no-magic', action="store_true",
|
||||
default=False, help="DEPRECATED equivalent to --assert=plain")
|
||||
|
||||
class AssertionState:
|
||||
|
||||
@@ -29,7 +29,7 @@ def pytest_load_initial_conftests(early_config, parser, args, __multicall__):
|
||||
except ValueError:
|
||||
pass
|
||||
early_config.pluginmanager.add_shutdown(teardown)
|
||||
# make sure logging does not raise exceptions if it is imported
|
||||
# make sure logging does not raise exceptions at the end
|
||||
def silence_logging_at_shutdown():
|
||||
if "logging" in sys.modules:
|
||||
sys.modules["logging"].raiseExceptions = False
|
||||
|
||||
@@ -238,7 +238,7 @@ class Argument:
|
||||
pass
|
||||
else:
|
||||
# this might raise a keyerror as well, don't want to catch that
|
||||
if isinstance(typ, str):
|
||||
if isinstance(typ, py.builtin._basestring):
|
||||
if typ == 'choice':
|
||||
if self.TYPE_WARN:
|
||||
py.std.warnings.warn(
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"""
|
||||
pytest PluginManager, basic initialization and tracing.
|
||||
"""
|
||||
import sys, os
|
||||
import sys
|
||||
import inspect
|
||||
import py
|
||||
|
||||
@@ -76,6 +76,10 @@ class PluginManager(object):
|
||||
self._shutdown = []
|
||||
self.hook = HookRelay(hookspecs or [], pm=self)
|
||||
|
||||
def do_configure(self, config):
|
||||
# backward compatibility
|
||||
config.do_configure()
|
||||
|
||||
def set_register_callback(self, callback):
|
||||
assert not hasattr(self, "_registercallback")
|
||||
self._registercallback = callback
|
||||
|
||||
@@ -2,14 +2,12 @@
|
||||
|
||||
import py
|
||||
import pytest, _pytest
|
||||
import inspect
|
||||
import os, sys, imp
|
||||
try:
|
||||
from collections import MutableMapping as MappingMixin
|
||||
except ImportError:
|
||||
from UserDict import DictMixin as MappingMixin
|
||||
|
||||
from _pytest.mark import MarkInfo
|
||||
from _pytest.runner import collect_one_node, Skipped
|
||||
|
||||
tracebackcutdir = py.path.local(_pytest.__file__).dirpath()
|
||||
@@ -172,30 +170,39 @@ def compatproperty(name):
|
||||
|
||||
class NodeKeywords(MappingMixin):
|
||||
def __init__(self, node):
|
||||
parent = node.parent
|
||||
bases = parent and (parent.keywords._markers,) or ()
|
||||
self._markers = type("dynmarker", bases, {node.name: True})
|
||||
self.node = node
|
||||
self.parent = node.parent
|
||||
self._markers = {node.name: True}
|
||||
|
||||
def __getitem__(self, key):
|
||||
try:
|
||||
return getattr(self._markers, key)
|
||||
except AttributeError:
|
||||
raise KeyError(key)
|
||||
return self._markers[key]
|
||||
except KeyError:
|
||||
if self.parent is None:
|
||||
raise
|
||||
return self.parent.keywords[key]
|
||||
|
||||
def __setitem__(self, key, value):
|
||||
setattr(self._markers, key, value)
|
||||
self._markers[key] = value
|
||||
|
||||
def __delitem__(self, key):
|
||||
delattr(self._markers, key)
|
||||
raise ValueError("cannot delete key in keywords dict")
|
||||
|
||||
def __iter__(self):
|
||||
return iter(self.keys())
|
||||
seen = set(self._markers)
|
||||
if self.parent is not None:
|
||||
seen.update(self.parent.keywords)
|
||||
return iter(seen)
|
||||
|
||||
def __len__(self):
|
||||
return len(self.keys())
|
||||
return len(self.__iter__())
|
||||
|
||||
def keys(self):
|
||||
return dir(self._markers)
|
||||
return list(self)
|
||||
|
||||
def __repr__(self):
|
||||
return "<NodeKeywords for node %s>" % (self.node, )
|
||||
|
||||
|
||||
class Node(object):
|
||||
""" base class for Collector and Item the test collection tree.
|
||||
@@ -314,6 +321,27 @@ class Node(object):
|
||||
chain.reverse()
|
||||
return chain
|
||||
|
||||
def add_marker(self, marker):
|
||||
""" dynamically add a marker object to the node.
|
||||
|
||||
``marker`` can be a string or pytest.mark.* instance.
|
||||
"""
|
||||
from _pytest.mark import MarkDecorator
|
||||
if isinstance(marker, py.builtin._basestring):
|
||||
marker = MarkDecorator(marker)
|
||||
elif not isinstance(marker, MarkDecorator):
|
||||
raise ValueError("is not a string or pytest.mark.* Marker")
|
||||
self.keywords[marker.name] = marker
|
||||
|
||||
def get_marker(self, name):
|
||||
""" get a marker object from this node or None if
|
||||
the node doesn't have a marker with that name. """
|
||||
val = self.keywords.get(name, None)
|
||||
if val is not None:
|
||||
from _pytest.mark import MarkInfo, MarkDecorator
|
||||
if isinstance(val, (MarkDecorator, MarkInfo)):
|
||||
return val
|
||||
|
||||
def listextrakeywords(self):
|
||||
""" Return a set of all extra keywords in self and any parents."""
|
||||
extra_keywords = set()
|
||||
|
||||
@@ -81,11 +81,8 @@ def pytest_collection_modifyitems(items, config):
|
||||
|
||||
|
||||
class MarkMapping:
|
||||
"""Provides a local mapping for markers.
|
||||
Only the marker names from the given :class:`NodeKeywords` will be mapped,
|
||||
so the names are taken only from :class:`MarkInfo` or
|
||||
:class:`MarkDecorator` items.
|
||||
"""
|
||||
"""Provides a local mapping for markers where item access
|
||||
resolves to True if the marker is present. """
|
||||
def __init__(self, keywords):
|
||||
mymarks = set()
|
||||
for key, value in keywords.items():
|
||||
@@ -93,8 +90,8 @@ class MarkMapping:
|
||||
mymarks.add(key)
|
||||
self._mymarks = mymarks
|
||||
|
||||
def __getitem__(self, markname):
|
||||
return markname in self._mymarks
|
||||
def __getitem__(self, name):
|
||||
return name in self._mymarks
|
||||
|
||||
|
||||
class KeywordMapping:
|
||||
@@ -139,8 +136,9 @@ def matchkeyword(colitem, keywordexpr):
|
||||
mapped_names.add(name)
|
||||
|
||||
# Add the names attached to the current function through direct assignment
|
||||
for name in colitem.function.__dict__:
|
||||
mapped_names.add(name)
|
||||
if hasattr(colitem, 'function'):
|
||||
for name in colitem.function.__dict__:
|
||||
mapped_names.add(name)
|
||||
|
||||
return eval(keywordexpr, {}, KeywordMapping(mapped_names))
|
||||
|
||||
@@ -201,13 +199,17 @@ class MarkDecorator:
|
||||
pass
|
||||
"""
|
||||
def __init__(self, name, args=None, kwargs=None):
|
||||
self.markname = name
|
||||
self.name = name
|
||||
self.args = args or ()
|
||||
self.kwargs = kwargs or {}
|
||||
|
||||
@property
|
||||
def markname(self):
|
||||
return self.name # for backward-compat (2.4.1 had this attr)
|
||||
|
||||
def __repr__(self):
|
||||
d = self.__dict__.copy()
|
||||
name = d.pop('markname')
|
||||
name = d.pop('name')
|
||||
return "<MarkDecorator %r %r>" % (name, d)
|
||||
|
||||
def __call__(self, *args, **kwargs):
|
||||
@@ -227,19 +229,19 @@ class MarkDecorator:
|
||||
else:
|
||||
func.pytestmark = [self]
|
||||
else:
|
||||
holder = getattr(func, self.markname, None)
|
||||
holder = getattr(func, self.name, None)
|
||||
if holder is None:
|
||||
holder = MarkInfo(
|
||||
self.markname, self.args, self.kwargs
|
||||
self.name, self.args, self.kwargs
|
||||
)
|
||||
setattr(func, self.markname, holder)
|
||||
setattr(func, self.name, holder)
|
||||
else:
|
||||
holder.add(self.args, self.kwargs)
|
||||
return func
|
||||
kw = self.kwargs.copy()
|
||||
kw.update(kwargs)
|
||||
args = self.args + args
|
||||
return self.__class__(self.markname, args=args, kwargs=kw)
|
||||
return self.__class__(self.name, args=args, kwargs=kw)
|
||||
|
||||
|
||||
class MarkInfo:
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
""" monkeypatching and mocking functionality. """
|
||||
|
||||
import os, sys, inspect
|
||||
import pytest
|
||||
import os, sys
|
||||
|
||||
def pytest_funcarg__monkeypatch(request):
|
||||
"""The returned ``monkeypatch`` funcarg provides these
|
||||
@@ -28,6 +27,7 @@ def pytest_funcarg__monkeypatch(request):
|
||||
|
||||
|
||||
def derive_importpath(import_path):
|
||||
import pytest
|
||||
if not isinstance(import_path, str) or "." not in import_path:
|
||||
raise TypeError("must be absolute import path string, not %r" %
|
||||
(import_path,))
|
||||
@@ -82,6 +82,7 @@ class monkeypatch:
|
||||
which means it will raise).
|
||||
"""
|
||||
__tracebackhide__ = True
|
||||
import inspect
|
||||
|
||||
if value is notset:
|
||||
if not isinstance(target, str):
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
""" run test suites written for nose. """
|
||||
|
||||
import pytest, py
|
||||
import inspect
|
||||
import sys
|
||||
from _pytest import unittest
|
||||
|
||||
|
||||
@@ -4,7 +4,6 @@ import py, pytest
|
||||
import sys, os
|
||||
import codecs
|
||||
import re
|
||||
import inspect
|
||||
import time
|
||||
from fnmatch import fnmatch
|
||||
from _pytest.main import Session, EXIT_OK
|
||||
@@ -661,6 +660,12 @@ class LineMatcher:
|
||||
else:
|
||||
raise ValueError("line %r not found in output" % line)
|
||||
|
||||
def get_lines_after(self, fnline):
|
||||
for i, line in enumerate(self.lines):
|
||||
if fnline == line or fnmatch(line, fnline):
|
||||
return self.lines[i+1:]
|
||||
raise ValueError("line %r not found in output" % fnline)
|
||||
|
||||
def fnmatch_lines(self, lines2):
|
||||
def show(arg1, arg2):
|
||||
py.builtin.print_(arg1, arg2, file=py.std.sys.stderr)
|
||||
|
||||
@@ -710,8 +710,8 @@ class Metafunc(FuncargnamesCompatAttr):
|
||||
|
||||
if not isinstance(argnames, (tuple, list)):
|
||||
argnames = [x.strip() for x in argnames.split(",") if x.strip()]
|
||||
if len(argnames) == 1:
|
||||
argvalues = [(val,) for val in argvalues]
|
||||
if len(argnames) == 1:
|
||||
argvalues = [(val,) for val in argvalues]
|
||||
if not argvalues:
|
||||
argvalues = [(_notexists,) * len(argnames)]
|
||||
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
""" recording warnings during test function execution. """
|
||||
|
||||
import py
|
||||
import sys, os
|
||||
import sys
|
||||
|
||||
def pytest_funcarg__recwarn(request):
|
||||
"""Return a WarningsRecorder instance that provides these methods:
|
||||
|
||||
* ``pop(category=None)``: return last warning matching the category.
|
||||
* ``clear()``: clear list of warnings
|
||||
|
||||
|
||||
See http://docs.python.org/library/warnings.html for information
|
||||
on warning categories.
|
||||
"""
|
||||
|
||||
@@ -6,7 +6,6 @@ sources = """
|
||||
import sys
|
||||
import base64
|
||||
import zlib
|
||||
import imp
|
||||
|
||||
class DictImporter(object):
|
||||
def __init__(self, sources):
|
||||
|
||||
@@ -33,22 +33,7 @@ def pytest_addoption(parser):
|
||||
|
||||
def pytest_configure(config):
|
||||
config.option.verbose -= config.option.quiet
|
||||
# we try hard to make printing resilient against
|
||||
# later changes on FD level. (unless capturing is turned off)
|
||||
stdout = py.std.sys.stdout
|
||||
capture = config.option.capture != "no"
|
||||
if capture and hasattr(os, 'dup') and hasattr(stdout, 'fileno'):
|
||||
try:
|
||||
newstdout = py.io.dupfile(stdout, buffering=1,
|
||||
encoding=stdout.encoding)
|
||||
except ValueError:
|
||||
pass
|
||||
else:
|
||||
config._cleanup.append(lambda: newstdout.close())
|
||||
assert stdout.encoding == newstdout.encoding
|
||||
stdout = newstdout
|
||||
|
||||
reporter = TerminalReporter(config, stdout)
|
||||
reporter = TerminalReporter(config, sys.stdout)
|
||||
config.pluginmanager.register(reporter, 'terminalreporter')
|
||||
if config.option.debug or config.option.traceconfig:
|
||||
def mywriter(tags, args):
|
||||
|
||||
@@ -64,5 +64,8 @@ def tmpdir(request):
|
||||
"""
|
||||
name = request.node.name
|
||||
name = py.std.re.sub("[\W]", "_", name)
|
||||
MAXVAL = 30
|
||||
if len(name) > MAXVAL:
|
||||
name = name[:MAXVAL]
|
||||
x = request.config._tmpdirhandler.mktemp(name, numbered=True)
|
||||
return x
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
""" discovery and running of std-library "unittest" style tests. """
|
||||
import pytest, py
|
||||
import sys, pdb
|
||||
import sys
|
||||
|
||||
# for transfering markers
|
||||
from _pytest.python import transfer_markers
|
||||
|
||||
@@ -7,4 +7,4 @@ if __name__ == '__main__':
|
||||
p = pstats.Stats("prof")
|
||||
p.strip_dirs()
|
||||
p.sort_stats('cumulative')
|
||||
print(p.print_stats(30))
|
||||
print(p.print_stats(50))
|
||||
|
||||
@@ -12,7 +12,7 @@ PAPEROPT_a4 = -D latex_paper_size=a4
|
||||
PAPEROPT_letter = -D latex_paper_size=letter
|
||||
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
|
||||
|
||||
SITETARGET=dev
|
||||
SITETARGET=latest
|
||||
|
||||
.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest
|
||||
|
||||
|
||||
@@ -5,6 +5,9 @@ Release announcements
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
release-2.4.2
|
||||
release-2.4.1
|
||||
release-2.4.0
|
||||
release-2.3.5
|
||||
release-2.3.4
|
||||
release-2.3.3
|
||||
|
||||
225
doc/en/announce/release-2.4.0.txt
Normal file
225
doc/en/announce/release-2.4.0.txt
Normal file
@@ -0,0 +1,225 @@
|
||||
pytest-2.4.0: new fixture features/hooks and bug fixes
|
||||
===========================================================================
|
||||
|
||||
The just released pytest-2.4.0 brings many improvements and numerous
|
||||
bug fixes while remaining plugin- and test-suite compatible apart
|
||||
from a few supposedly very minor incompatibilities. See below for
|
||||
a full list of details. A few feature highlights:
|
||||
|
||||
- new yield-style fixtures `pytest.yield_fixture
|
||||
<http://pytest.org/latest/yieldfixture.html>`_, allowing to use
|
||||
existing with-style context managers in fixture functions.
|
||||
|
||||
- improved pdb support: ``import pdb ; pdb.set_trace()`` now works
|
||||
without requiring prior disabling of stdout/stderr capturing.
|
||||
Also the ``--pdb`` options works now on collection and internal errors
|
||||
and we introduced a new experimental hook for IDEs/plugins to
|
||||
intercept debugging: ``pytest_exception_interact(node, call, report)``.
|
||||
|
||||
- shorter monkeypatch variant to allow specifying an import path as
|
||||
a target, for example: ``monkeypatch.setattr("requests.get", myfunc)``
|
||||
|
||||
- better unittest/nose compatibility: all teardown methods are now only
|
||||
called if the corresponding setup method succeeded.
|
||||
|
||||
- integrate tab-completion on command line options if you
|
||||
have `argcomplete <http://pypi.python.org/pypi/argcomplete>`_
|
||||
configured.
|
||||
|
||||
- allow boolean expression directly with skipif/xfail
|
||||
if a "reason" is also specified.
|
||||
|
||||
- a new hook ``pytest_load_initial_conftests`` allows plugins like
|
||||
`pytest-django <http://pypi.python.org/pypi/pytest-django>`_ to
|
||||
influence the environment before conftest files import ``django``.
|
||||
|
||||
- reporting: color the last line red or green depending if
|
||||
failures/errors occured or everything passed.
|
||||
|
||||
The documentation has been updated to accomodate the changes,
|
||||
see `http://pytest.org <http://pytest.org>`_
|
||||
|
||||
To install or upgrade pytest::
|
||||
|
||||
pip install -U pytest # or
|
||||
easy_install -U pytest
|
||||
|
||||
|
||||
**Many thanks to all who helped, including Floris Bruynooghe,
|
||||
Brianna Laugher, Andreas Pelme, Anthon van der Neut, Anatoly Bubenkoff,
|
||||
Vladimir Keleshev, Mathieu Agopian, Ronny Pfannschmidt, Christian
|
||||
Theunert and many others.**
|
||||
|
||||
may passing tests be with you,
|
||||
|
||||
holger krekel
|
||||
|
||||
Changes between 2.3.5 and 2.4
|
||||
-----------------------------------
|
||||
|
||||
known incompatibilities:
|
||||
|
||||
- if calling --genscript from python2.7 or above, you only get a
|
||||
standalone script which works on python2.7 or above. Use Python2.6
|
||||
to also get a python2.5 compatible version.
|
||||
|
||||
- all xunit-style teardown methods (nose-style, pytest-style,
|
||||
unittest-style) will not be called if the corresponding setup method failed,
|
||||
see issue322 below.
|
||||
|
||||
- the pytest_plugin_unregister hook wasn't ever properly called
|
||||
and there is no known implementation of the hook - so it got removed.
|
||||
|
||||
- pytest.fixture-decorated functions cannot be generators (i.e. use
|
||||
yield) anymore. This change might be reversed in 2.4.1 if it causes
|
||||
unforeseen real-life issues. However, you can always write and return
|
||||
an inner function/generator and change the fixture consumer to iterate
|
||||
over the returned generator. This change was done in lieu of the new
|
||||
``pytest.yield_fixture`` decorator, see below.
|
||||
|
||||
new features:
|
||||
|
||||
- experimentally introduce a new ``pytest.yield_fixture`` decorator
|
||||
which accepts exactly the same parameters as pytest.fixture but
|
||||
mandates a ``yield`` statement instead of a ``return statement`` from
|
||||
fixture functions. This allows direct integration with "with-style"
|
||||
context managers in fixture functions and generally avoids registering
|
||||
of finalization callbacks in favour of treating the "after-yield" as
|
||||
teardown code. Thanks Andreas Pelme, Vladimir Keleshev, Floris
|
||||
Bruynooghe, Ronny Pfannschmidt and many others for discussions.
|
||||
|
||||
- allow boolean expression directly with skipif/xfail
|
||||
if a "reason" is also specified. Rework skipping documentation
|
||||
to recommend "condition as booleans" because it prevents surprises
|
||||
when importing markers between modules. Specifying conditions
|
||||
as strings will remain fully supported.
|
||||
|
||||
- reporting: color the last line red or green depending if
|
||||
failures/errors occured or everything passed. thanks Christian
|
||||
Theunert.
|
||||
|
||||
- make "import pdb ; pdb.set_trace()" work natively wrt capturing (no
|
||||
"-s" needed anymore), making ``pytest.set_trace()`` a mere shortcut.
|
||||
|
||||
- fix issue181: --pdb now also works on collect errors (and
|
||||
on internal errors) . This was implemented by a slight internal
|
||||
refactoring and the introduction of a new hook
|
||||
``pytest_exception_interact`` hook (see next item).
|
||||
|
||||
- fix issue341: introduce new experimental hook for IDEs/terminals to
|
||||
intercept debugging: ``pytest_exception_interact(node, call, report)``.
|
||||
|
||||
- new monkeypatch.setattr() variant to provide a shorter
|
||||
invocation for patching out classes/functions from modules:
|
||||
|
||||
monkeypatch.setattr("requests.get", myfunc)
|
||||
|
||||
will replace the "get" function of the "requests" module with ``myfunc``.
|
||||
|
||||
- fix issue322: tearDownClass is not run if setUpClass failed. Thanks
|
||||
Mathieu Agopian for the initial fix. Also make all of pytest/nose
|
||||
finalizer mimick the same generic behaviour: if a setupX exists and
|
||||
fails, don't run teardownX. This internally introduces a new method
|
||||
"node.addfinalizer()" helper which can only be called during the setup
|
||||
phase of a node.
|
||||
|
||||
- simplify pytest.mark.parametrize() signature: allow to pass a
|
||||
CSV-separated string to specify argnames. For example:
|
||||
``pytest.mark.parametrize("input,expected", [(1,2), (2,3)])``
|
||||
works as well as the previous:
|
||||
``pytest.mark.parametrize(("input", "expected"), ...)``.
|
||||
|
||||
- add support for setUpModule/tearDownModule detection, thanks Brian Okken.
|
||||
|
||||
- integrate tab-completion on options through use of "argcomplete".
|
||||
Thanks Anthon van der Neut for the PR.
|
||||
|
||||
- change option names to be hyphen-separated long options but keep the
|
||||
old spelling backward compatible. py.test -h will only show the
|
||||
hyphenated version, for example "--collect-only" but "--collectonly"
|
||||
will remain valid as well (for backward-compat reasons). Many thanks to
|
||||
Anthon van der Neut for the implementation and to Hynek Schlawack for
|
||||
pushing us.
|
||||
|
||||
- fix issue 308 - allow to mark/xfail/skip individual parameter sets
|
||||
when parametrizing. Thanks Brianna Laugher.
|
||||
|
||||
- call new experimental pytest_load_initial_conftests hook to allow
|
||||
3rd party plugins to do something before a conftest is loaded.
|
||||
|
||||
Bug fixes:
|
||||
|
||||
- fix issue358 - capturing options are now parsed more properly
|
||||
by using a new parser.parse_known_args method.
|
||||
|
||||
- pytest now uses argparse instead of optparse (thanks Anthon) which
|
||||
means that "argparse" is added as a dependency if installing into python2.6
|
||||
environments or below.
|
||||
|
||||
- fix issue333: fix a case of bad unittest/pytest hook interaction.
|
||||
|
||||
- PR27: correctly handle nose.SkipTest during collection. Thanks
|
||||
Antonio Cuni, Ronny Pfannschmidt.
|
||||
|
||||
- fix issue355: junitxml puts name="pytest" attribute to testsuite tag.
|
||||
|
||||
- fix issue336: autouse fixture in plugins should work again.
|
||||
|
||||
- fix issue279: improve object comparisons on assertion failure
|
||||
for standard datatypes and recognise collections.abc. Thanks to
|
||||
Brianna Laugher and Mathieu Agopian.
|
||||
|
||||
- fix issue317: assertion rewriter support for the is_package method
|
||||
|
||||
- fix issue335: document py.code.ExceptionInfo() object returned
|
||||
from pytest.raises(), thanks Mathieu Agopian.
|
||||
|
||||
- remove implicit distribute_setup support from setup.py.
|
||||
|
||||
- fix issue305: ignore any problems when writing pyc files.
|
||||
|
||||
- SO-17664702: call fixture finalizers even if the fixture function
|
||||
partially failed (finalizers would not always be called before)
|
||||
|
||||
- fix issue320 - fix class scope for fixtures when mixed with
|
||||
module-level functions. Thanks Anatloy Bubenkoff.
|
||||
|
||||
- you can specify "-q" or "-qq" to get different levels of "quieter"
|
||||
reporting (thanks Katarzyna Jachim)
|
||||
|
||||
- fix issue300 - Fix order of conftest loading when starting py.test
|
||||
in a subdirectory.
|
||||
|
||||
- fix issue323 - sorting of many module-scoped arg parametrizations
|
||||
|
||||
- make sessionfinish hooks execute with the same cwd-context as at
|
||||
session start (helps fix plugin behaviour which write output files
|
||||
with relative path such as pytest-cov)
|
||||
|
||||
- fix issue316 - properly reference collection hooks in docs
|
||||
|
||||
- fix issue 306 - cleanup of -k/-m options to only match markers/test
|
||||
names/keywords respectively. Thanks Wouter van Ackooy.
|
||||
|
||||
- improved doctest counting for doctests in python modules --
|
||||
files without any doctest items will not show up anymore
|
||||
and doctest examples are counted as separate test items.
|
||||
thanks Danilo Bellini.
|
||||
|
||||
- fix issue245 by depending on the released py-1.4.14
|
||||
which fixes py.io.dupfile to work with files with no
|
||||
mode. Thanks Jason R. Coombs.
|
||||
|
||||
- fix junitxml generation when test output contains control characters,
|
||||
addressing issue267, thanks Jaap Broekhuizen
|
||||
|
||||
- fix issue338: honor --tb style for setup/teardown errors as well. Thanks Maho.
|
||||
|
||||
- fix issue307 - use yaml.safe_load in example, thanks Mark Eichin.
|
||||
|
||||
- better parametrize error messages, thanks Brianna Laugher
|
||||
|
||||
- pytest_terminal_summary(terminalreporter) hooks can now use
|
||||
".section(title)" and ".line(msg)" methods to print extra
|
||||
information at the end of a test run.
|
||||
|
||||
25
doc/en/announce/release-2.4.1.txt
Normal file
25
doc/en/announce/release-2.4.1.txt
Normal file
@@ -0,0 +1,25 @@
|
||||
pytest-2.4.1: fixing three regressions compared to 2.3.5
|
||||
===========================================================================
|
||||
|
||||
pytest-2.4.1 is a quick follow up release to fix three regressions
|
||||
compared to 2.3.5 before they hit more people:
|
||||
|
||||
- When using parser.addoption() unicode arguments to the
|
||||
"type" keyword should also be converted to the respective types.
|
||||
thanks Floris Bruynooghe, @dnozay. (fixes issue360 and issue362)
|
||||
|
||||
- fix dotted filename completion when using argcomplete
|
||||
thanks Anthon van der Neuth. (fixes issue361)
|
||||
|
||||
- fix regression when a 1-tuple ("arg",) is used for specifying
|
||||
parametrization (the values of the parametrization were passed
|
||||
nested in a tuple). Thanks Donald Stufft.
|
||||
|
||||
- also merge doc typo fixes, thanks Andy Dirnberger
|
||||
|
||||
as usual, docs at http://pytest.org and upgrades via::
|
||||
|
||||
pip install -U pytest
|
||||
|
||||
have fun,
|
||||
holger krekel
|
||||
39
doc/en/announce/release-2.4.2.txt
Normal file
39
doc/en/announce/release-2.4.2.txt
Normal file
@@ -0,0 +1,39 @@
|
||||
pytest-2.4.2: colorama on windows, plugin/tmpdir fixes
|
||||
===========================================================================
|
||||
|
||||
pytest-2.4.2 is another bug-fixing release:
|
||||
|
||||
- on Windows require colorama and a newer py lib so that py.io.TerminalWriter()
|
||||
now uses colorama instead of its own ctypes hacks. (fixes issue365)
|
||||
thanks Paul Moore for bringing it up.
|
||||
|
||||
- fix "-k" matching of tests where "repr" and "attr" and other names would
|
||||
cause wrong matches because of an internal implementation quirk
|
||||
(don't ask) which is now properly implemented. fixes issue345.
|
||||
|
||||
- avoid tmpdir fixture to create too long filenames especially
|
||||
when parametrization is used (issue354)
|
||||
|
||||
- fix pytest-pep8 and pytest-flakes / pytest interactions
|
||||
(collection names in mark plugin was assuming an item always
|
||||
has a function which is not true for those plugins etc.)
|
||||
Thanks Andi Zeidler.
|
||||
|
||||
- introduce node.get_marker/node.add_marker API for plugins
|
||||
like pytest-pep8 and pytest-flakes to avoid the messy
|
||||
details of the node.keywords pseudo-dicts. Adapated
|
||||
docs.
|
||||
|
||||
- remove attempt to "dup" stdout at startup as it's icky.
|
||||
the normal capturing should catch enough possibilities
|
||||
of tests messing up standard FDs.
|
||||
|
||||
- add pluginmanager.do_configure(config) as a link to
|
||||
config.do_configure() for plugin-compatibility
|
||||
|
||||
as usual, docs at http://pytest.org and upgrades via::
|
||||
|
||||
pip install -U pytest
|
||||
|
||||
have fun,
|
||||
holger krekel
|
||||
@@ -26,7 +26,7 @@ you will see the return value of the function call::
|
||||
|
||||
$ py.test test_assert1.py
|
||||
=========================== test session starts ============================
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.3.5
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.4.2
|
||||
collected 1 items
|
||||
|
||||
test_assert1.py F
|
||||
@@ -116,7 +116,7 @@ if you run this module::
|
||||
|
||||
$ py.test test_assert2.py
|
||||
=========================== test session starts ============================
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.3.5
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.4.2
|
||||
collected 1 items
|
||||
|
||||
test_assert2.py F
|
||||
@@ -191,6 +191,7 @@ the conftest file::
|
||||
E vals: 1 != 2
|
||||
|
||||
test_foocompare.py:8: AssertionError
|
||||
1 failed in 0.01 seconds
|
||||
|
||||
.. _assert-details:
|
||||
.. _`assert introspection`:
|
||||
|
||||
@@ -129,6 +129,7 @@ Let's run this module without output-capturing::
|
||||
E NameError: global name 'globresource' is not defined
|
||||
|
||||
test_glob.py:5: NameError
|
||||
2 failed in 0.01 seconds
|
||||
|
||||
The two tests see the same global ``globresource`` object.
|
||||
|
||||
@@ -177,6 +178,7 @@ And then re-run our test module::
|
||||
E NameError: global name 'globresource' is not defined
|
||||
|
||||
test_glob.py:5: NameError
|
||||
2 failed in 0.01 seconds
|
||||
|
||||
We are now running the two tests twice with two different global resource
|
||||
instances. Note that the tests are ordered such that only
|
||||
|
||||
@@ -120,3 +120,4 @@ You can ask for available builtin or project-custom
|
||||
path object.
|
||||
|
||||
|
||||
in 0.00 seconds
|
||||
|
||||
@@ -64,7 +64,7 @@ of the failing function and hide the other one::
|
||||
|
||||
$ py.test
|
||||
=========================== test session starts ============================
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.3.5
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.4.2
|
||||
collected 2 items
|
||||
|
||||
test_module.py .F
|
||||
@@ -78,7 +78,7 @@ of the failing function and hide the other one::
|
||||
|
||||
test_module.py:9: AssertionError
|
||||
----------------------------- Captured stdout ------------------------------
|
||||
setting up <function test_func2 at 0x2d79f50>
|
||||
setting up <function test_func2 at 0x282d2a8>
|
||||
==================== 1 failed, 1 passed in 0.01 seconds ====================
|
||||
|
||||
Accessing captured output from a test function
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
#
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
# The short X.Y version.
|
||||
version = release = "2.4.0.dev"
|
||||
version = "2.4.2"
|
||||
release = "2.4.2"
|
||||
|
||||
import sys, os
|
||||
|
||||
|
||||
@@ -44,12 +44,12 @@ then you can just invoke ``py.test`` without command line options::
|
||||
|
||||
$ py.test
|
||||
=========================== test session starts ============================
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.3.5
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.4.2
|
||||
collected 1 items
|
||||
|
||||
mymodule.py .
|
||||
|
||||
========================= 1 passed in 0.02 seconds =========================
|
||||
========================= 1 passed in 0.01 seconds =========================
|
||||
|
||||
It is possible to use fixtures using the ``getfixture`` helper::
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ You can then restrict a test run to only run tests marked with ``webtest``::
|
||||
|
||||
$ py.test -v -m webtest
|
||||
=========================== test session starts ============================
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.3.5 -- /home/hpk/p/pytest/.tox/regen/bin/python
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.4.2 -- /home/hpk/p/pytest/.tox/regen/bin/python
|
||||
collecting ... collected 3 items
|
||||
|
||||
test_server.py:3: test_send_http PASSED
|
||||
@@ -40,7 +40,7 @@ Or the inverse, running all tests except the webtest ones::
|
||||
|
||||
$ py.test -v -m "not webtest"
|
||||
=========================== test session starts ============================
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.3.5 -- /home/hpk/p/pytest/.tox/regen/bin/python
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.4.2 -- /home/hpk/p/pytest/.tox/regen/bin/python
|
||||
collecting ... collected 3 items
|
||||
|
||||
test_server.py:6: test_something_quick PASSED
|
||||
@@ -61,7 +61,7 @@ select tests based on their names::
|
||||
|
||||
$ py.test -v -k http # running with the above defined example module
|
||||
=========================== test session starts ============================
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.3.5 -- /home/hpk/p/pytest/.tox/regen/bin/python
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.4.2 -- /home/hpk/p/pytest/.tox/regen/bin/python
|
||||
collecting ... collected 3 items
|
||||
|
||||
test_server.py:3: test_send_http PASSED
|
||||
@@ -73,7 +73,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 linux2 -- Python 2.7.3 -- pytest-2.3.5 -- /home/hpk/p/pytest/.tox/regen/bin/python
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.4.2 -- /home/hpk/p/pytest/.tox/regen/bin/python
|
||||
collecting ... collected 3 items
|
||||
|
||||
test_server.py:6: test_something_quick PASSED
|
||||
@@ -86,7 +86,7 @@ Or to select "http" and "quick" tests::
|
||||
|
||||
$ py.test -k "http or quick" -v
|
||||
=========================== test session starts ============================
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.3.5 -- /home/hpk/p/pytest/.tox/regen/bin/python
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.4.2 -- /home/hpk/p/pytest/.tox/regen/bin/python
|
||||
collecting ... collected 3 items
|
||||
|
||||
test_server.py:3: test_send_http PASSED
|
||||
@@ -235,7 +235,7 @@ specifies via named environments::
|
||||
"env(name): mark test to run only on named environment")
|
||||
|
||||
def pytest_runtest_setup(item):
|
||||
envmarker = item.keywords.get("env", None)
|
||||
envmarker = item.get_marker("env")
|
||||
if envmarker is not None:
|
||||
envname = envmarker.args[0]
|
||||
if envname != item.config.getoption("-E"):
|
||||
@@ -255,7 +255,7 @@ the test needs::
|
||||
|
||||
$ py.test -E stage2
|
||||
=========================== test session starts ============================
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.3.5
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.4.2
|
||||
collected 1 items
|
||||
|
||||
test_someenv.py s
|
||||
@@ -266,7 +266,7 @@ and here is one that specifies exactly the environment needed::
|
||||
|
||||
$ py.test -E stage1
|
||||
=========================== test session starts ============================
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.3.5
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.4.2
|
||||
collected 1 items
|
||||
|
||||
test_someenv.py .
|
||||
@@ -318,7 +318,7 @@ test function. From a conftest file we can read it like this::
|
||||
import sys
|
||||
|
||||
def pytest_runtest_setup(item):
|
||||
g = item.keywords.get("glob", None)
|
||||
g = item.get_marker("glob")
|
||||
if g is not None:
|
||||
for info in g:
|
||||
print ("glob args=%s kwargs=%s" %(info.args, info.kwargs))
|
||||
@@ -331,6 +331,7 @@ Let's run this without capturing output and see what we get::
|
||||
glob args=('class',) kwargs={'x': 2}
|
||||
glob args=('module',) kwargs={'x': 1}
|
||||
.
|
||||
1 passed in 0.01 seconds
|
||||
|
||||
marking platform specific tests with pytest
|
||||
--------------------------------------------------------------
|
||||
@@ -353,7 +354,7 @@ for your particular platform, you could use the following plugin::
|
||||
def pytest_runtest_setup(item):
|
||||
if isinstance(item, item.Function):
|
||||
plat = sys.platform
|
||||
if plat not in item.keywords:
|
||||
if not item.get_marker(plat):
|
||||
if ALL.intersection(item.keywords):
|
||||
pytest.skip("cannot run on platform %s" %(plat))
|
||||
|
||||
@@ -383,12 +384,12 @@ 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 linux2 -- Python 2.7.3 -- pytest-2.3.5
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.4.2
|
||||
collected 4 items
|
||||
|
||||
test_plat.py s.s.
|
||||
========================= short test summary info ==========================
|
||||
SKIP [2] /tmp/doc-exec-273/conftest.py:12: cannot run on platform linux2
|
||||
SKIP [2] /tmp/doc-exec-598/conftest.py:12: cannot run on platform linux2
|
||||
|
||||
=================== 2 passed, 2 skipped in 0.01 seconds ====================
|
||||
|
||||
@@ -396,7 +397,7 @@ Note that if you specify a platform via the marker-command line option like this
|
||||
|
||||
$ py.test -m linux2
|
||||
=========================== test session starts ============================
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.3.5
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.4.2
|
||||
collected 4 items
|
||||
|
||||
test_plat.py .
|
||||
@@ -439,15 +440,15 @@ We want to dynamically define two markers and can do it in a
|
||||
def pytest_collection_modifyitems(items):
|
||||
for item in items:
|
||||
if "interface" in item.nodeid:
|
||||
item.keywords["interface"] = pytest.mark.interface
|
||||
item.add_marker(pytest.mark.interface)
|
||||
elif "event" in item.nodeid:
|
||||
item.keywords["event"] = pytest.mark.event
|
||||
item.add_marker(pytest.mark.event)
|
||||
|
||||
We can now use the ``-m option`` to select one set::
|
||||
|
||||
$ py.test -m interface --tb=short
|
||||
=========================== test session starts ============================
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.3.5
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.4.2
|
||||
collected 4 items
|
||||
|
||||
test_module.py FF
|
||||
@@ -468,7 +469,7 @@ or to select both "event" and "interface" tests::
|
||||
|
||||
$ py.test -m "interface or event" --tb=short
|
||||
=========================== test session starts ============================
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.3.5
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.4.2
|
||||
collected 4 items
|
||||
|
||||
test_module.py FFF
|
||||
|
||||
@@ -27,7 +27,7 @@ now execute the test specification::
|
||||
|
||||
nonpython $ py.test test_simple.yml
|
||||
=========================== test session starts ============================
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.3.5
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.4.2
|
||||
collected 2 items
|
||||
|
||||
test_simple.yml .F
|
||||
@@ -37,7 +37,7 @@ now execute the test specification::
|
||||
usecase execution failed
|
||||
spec failed: 'some': 'other'
|
||||
no further details known at this point.
|
||||
==================== 1 failed, 1 passed in 0.05 seconds ====================
|
||||
==================== 1 failed, 1 passed in 0.03 seconds ====================
|
||||
|
||||
You get one dot for the passing ``sub1: sub1`` check and one failure.
|
||||
Obviously in the above ``conftest.py`` you'll want to implement a more
|
||||
@@ -56,7 +56,7 @@ consulted when reporting in ``verbose`` mode::
|
||||
|
||||
nonpython $ py.test -v
|
||||
=========================== test session starts ============================
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.3.5 -- /home/hpk/p/pytest/.tox/regen/bin/python
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.4.2 -- /home/hpk/p/pytest/.tox/regen/bin/python
|
||||
collecting ... collected 2 items
|
||||
|
||||
test_simple.yml:1: usecase: ok PASSED
|
||||
@@ -67,17 +67,17 @@ consulted when reporting in ``verbose`` mode::
|
||||
usecase execution failed
|
||||
spec failed: 'some': 'other'
|
||||
no further details known at this point.
|
||||
==================== 1 failed, 1 passed in 0.05 seconds ====================
|
||||
==================== 1 failed, 1 passed in 0.03 seconds ====================
|
||||
|
||||
While developing your custom test collection and execution it's also
|
||||
interesting to just look at the collection tree::
|
||||
|
||||
nonpython $ py.test --collect-only
|
||||
=========================== test session starts ============================
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.3.5
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.4.2
|
||||
collected 2 items
|
||||
<YamlFile 'test_simple.yml'>
|
||||
<YamlItem 'ok'>
|
||||
<YamlItem 'hello'>
|
||||
|
||||
============================= in 0.05 seconds =============================
|
||||
============================= in 0.03 seconds =============================
|
||||
|
||||
@@ -46,6 +46,7 @@ This means that we only run 2 tests if we do not pass ``--all``::
|
||||
|
||||
$ py.test -q test_compute.py
|
||||
..
|
||||
2 passed in 0.01 seconds
|
||||
|
||||
We run only two computations, so we see two dots.
|
||||
let's run the full monty::
|
||||
@@ -62,6 +63,7 @@ let's run the full monty::
|
||||
E assert 4 < 4
|
||||
|
||||
test_compute.py:3: AssertionError
|
||||
1 failed, 4 passed in 0.01 seconds
|
||||
|
||||
As expected when running the full range of ``param1`` values
|
||||
we'll get an error on the last one.
|
||||
@@ -104,7 +106,7 @@ this is a fully self-contained example which you can run with::
|
||||
|
||||
$ py.test test_scenarios.py
|
||||
=========================== test session starts ============================
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.3.5
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.4.2
|
||||
collected 4 items
|
||||
|
||||
test_scenarios.py ....
|
||||
@@ -116,7 +118,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 linux2 -- Python 2.7.3 -- pytest-2.3.5
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.4.2
|
||||
collected 4 items
|
||||
<Module 'test_scenarios.py'>
|
||||
<Class 'TestSampleWithScenarios'>
|
||||
@@ -180,7 +182,7 @@ Let's first see how it looks like at collection time::
|
||||
|
||||
$ py.test test_backends.py --collect-only
|
||||
=========================== test session starts ============================
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.3.5
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.4.2
|
||||
collected 2 items
|
||||
<Module 'test_backends.py'>
|
||||
<Function 'test_db_initialized[d1]'>
|
||||
@@ -195,7 +197,7 @@ And then when we run the test::
|
||||
================================= FAILURES =================================
|
||||
_________________________ test_db_initialized[d2] __________________________
|
||||
|
||||
db = <conftest.DB2 instance at 0x2038f80>
|
||||
db = <conftest.DB2 instance at 0x2dbd950>
|
||||
|
||||
def test_db_initialized(db):
|
||||
# a dummy test
|
||||
@@ -204,6 +206,7 @@ And then when we run the test::
|
||||
E Failed: deliberately failing for demo purposes
|
||||
|
||||
test_backends.py:6: Failed
|
||||
1 failed, 1 passed in 0.01 seconds
|
||||
|
||||
The first invocation with ``db == "DB1"`` passed while the second with ``db == "DB2"`` failed. Our ``db`` fixture function has instantiated each of the DB values during the setup phase while the ``pytest_generate_tests`` generated two according calls to the ``test_db_initialized`` during the collection phase.
|
||||
|
||||
@@ -250,13 +253,14 @@ argument sets to use for each test function. Let's run it::
|
||||
================================= FAILURES =================================
|
||||
________________________ TestClass.test_equals[1-2] ________________________
|
||||
|
||||
self = <test_parametrize.TestClass instance at 0x1338f80>, a = 1, b = 2
|
||||
self = <test_parametrize.TestClass instance at 0x258a6c8>, a = 1, b = 2
|
||||
|
||||
def test_equals(self, a, b):
|
||||
> assert a == b
|
||||
E assert 1 == 2
|
||||
|
||||
test_parametrize.py:18: AssertionError
|
||||
1 failed, 2 passed in 0.02 seconds
|
||||
|
||||
Indirect parametrization with multiple fixtures
|
||||
--------------------------------------------------------------
|
||||
@@ -278,6 +282,7 @@ Running it results in some skips if we don't have all the python interpreters in
|
||||
............sss............sss............sss............ssssssssssssssssss
|
||||
========================= short test summary info ==========================
|
||||
SKIP [27] /home/hpk/p/pytest/doc/en/example/multipython.py:21: 'python2.8' not found
|
||||
48 passed, 27 skipped in 1.37 seconds
|
||||
|
||||
Indirect parametrization of optional implementations/imports
|
||||
--------------------------------------------------------------------
|
||||
@@ -324,12 +329,12 @@ If you run this with reporting for skips enabled::
|
||||
|
||||
$ py.test -rs test_module.py
|
||||
=========================== test session starts ============================
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.3.5
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.4.2
|
||||
collected 2 items
|
||||
|
||||
test_module.py .s
|
||||
test_module.py s.
|
||||
========================= short test summary info ==========================
|
||||
SKIP [1] /tmp/doc-exec-275/conftest.py:10: could not import 'opt2'
|
||||
SKIP [1] /tmp/doc-exec-600/conftest.py:10: could not import 'opt2'
|
||||
|
||||
=================== 1 passed, 1 skipped in 0.01 seconds ====================
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ then the test collection looks like this::
|
||||
|
||||
$ py.test --collect-only
|
||||
=========================== test session starts ============================
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.3.5
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.4.2
|
||||
collected 2 items
|
||||
<Module 'check_myapp.py'>
|
||||
<Class 'CheckMyApp'>
|
||||
@@ -82,7 +82,7 @@ You can always peek at the collection tree without running tests like this::
|
||||
|
||||
. $ py.test --collect-only pythoncollection.py
|
||||
=========================== test session starts ============================
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.3.5
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.4.2
|
||||
collected 3 items
|
||||
<Module 'pythoncollection.py'>
|
||||
<Function 'test_function'>
|
||||
@@ -135,7 +135,7 @@ interpreters and will leave out the setup.py file::
|
||||
|
||||
$ py.test --collect-only
|
||||
=========================== test session starts ============================
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.3.5
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.4.2
|
||||
collected 1 items
|
||||
<Module 'pkg/module_py2.py'>
|
||||
<Function 'test_only_on_python2'>
|
||||
|
||||
@@ -13,7 +13,7 @@ get on the terminal - we are working on that):
|
||||
|
||||
assertion $ py.test failure_demo.py
|
||||
=========================== test session starts ============================
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.3.5
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.4.2
|
||||
collected 39 items
|
||||
|
||||
failure_demo.py FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
|
||||
@@ -30,7 +30,7 @@ get on the terminal - we are working on that):
|
||||
failure_demo.py:15: AssertionError
|
||||
_________________________ TestFailing.test_simple __________________________
|
||||
|
||||
self = <failure_demo.TestFailing object at 0x1445e10>
|
||||
self = <failure_demo.TestFailing object at 0x26f8f50>
|
||||
|
||||
def test_simple(self):
|
||||
def f():
|
||||
@@ -40,13 +40,13 @@ get on the terminal - we are working on that):
|
||||
|
||||
> assert f() == g()
|
||||
E assert 42 == 43
|
||||
E + where 42 = <function f at 0x137c6e0>()
|
||||
E + and 43 = <function g at 0x137c758>()
|
||||
E + where 42 = <function f at 0x269d5f0>()
|
||||
E + and 43 = <function g at 0x269d6e0>()
|
||||
|
||||
failure_demo.py:28: AssertionError
|
||||
____________________ TestFailing.test_simple_multiline _____________________
|
||||
|
||||
self = <failure_demo.TestFailing object at 0x135a1d0>
|
||||
self = <failure_demo.TestFailing object at 0x26ade90>
|
||||
|
||||
def test_simple_multiline(self):
|
||||
otherfunc_multi(
|
||||
@@ -66,19 +66,19 @@ get on the terminal - we are working on that):
|
||||
failure_demo.py:11: AssertionError
|
||||
___________________________ TestFailing.test_not ___________________________
|
||||
|
||||
self = <failure_demo.TestFailing object at 0x1458ed0>
|
||||
self = <failure_demo.TestFailing object at 0x26aac10>
|
||||
|
||||
def test_not(self):
|
||||
def f():
|
||||
return 42
|
||||
> assert not f()
|
||||
E assert not 42
|
||||
E + where 42 = <function f at 0x137caa0>()
|
||||
E + where 42 = <function f at 0x269d8c0>()
|
||||
|
||||
failure_demo.py:38: AssertionError
|
||||
_________________ TestSpecialisedExplanations.test_eq_text _________________
|
||||
|
||||
self = <failure_demo.TestSpecialisedExplanations object at 0x14451d0>
|
||||
self = <failure_demo.TestSpecialisedExplanations object at 0x2861490>
|
||||
|
||||
def test_eq_text(self):
|
||||
> assert 'spam' == 'eggs'
|
||||
@@ -89,7 +89,7 @@ get on the terminal - we are working on that):
|
||||
failure_demo.py:42: AssertionError
|
||||
_____________ TestSpecialisedExplanations.test_eq_similar_text _____________
|
||||
|
||||
self = <failure_demo.TestSpecialisedExplanations object at 0x1458c90>
|
||||
self = <failure_demo.TestSpecialisedExplanations object at 0x26ade10>
|
||||
|
||||
def test_eq_similar_text(self):
|
||||
> assert 'foo 1 bar' == 'foo 2 bar'
|
||||
@@ -102,7 +102,7 @@ get on the terminal - we are working on that):
|
||||
failure_demo.py:45: AssertionError
|
||||
____________ TestSpecialisedExplanations.test_eq_multiline_text ____________
|
||||
|
||||
self = <failure_demo.TestSpecialisedExplanations object at 0x1434390>
|
||||
self = <failure_demo.TestSpecialisedExplanations object at 0x26f8ad0>
|
||||
|
||||
def test_eq_multiline_text(self):
|
||||
> assert 'foo\nspam\nbar' == 'foo\neggs\nbar'
|
||||
@@ -115,7 +115,7 @@ get on the terminal - we are working on that):
|
||||
failure_demo.py:48: AssertionError
|
||||
______________ TestSpecialisedExplanations.test_eq_long_text _______________
|
||||
|
||||
self = <failure_demo.TestSpecialisedExplanations object at 0x1459f50>
|
||||
self = <failure_demo.TestSpecialisedExplanations object at 0x26aa450>
|
||||
|
||||
def test_eq_long_text(self):
|
||||
a = '1'*100 + 'a' + '2'*100
|
||||
@@ -132,7 +132,7 @@ get on the terminal - we are working on that):
|
||||
failure_demo.py:53: AssertionError
|
||||
_________ TestSpecialisedExplanations.test_eq_long_text_multiline __________
|
||||
|
||||
self = <failure_demo.TestSpecialisedExplanations object at 0x135a790>
|
||||
self = <failure_demo.TestSpecialisedExplanations object at 0x26ad7d0>
|
||||
|
||||
def test_eq_long_text_multiline(self):
|
||||
a = '1\n'*100 + 'a' + '2\n'*100
|
||||
@@ -156,7 +156,7 @@ get on the terminal - we are working on that):
|
||||
failure_demo.py:58: AssertionError
|
||||
_________________ TestSpecialisedExplanations.test_eq_list _________________
|
||||
|
||||
self = <failure_demo.TestSpecialisedExplanations object at 0x138dfd0>
|
||||
self = <failure_demo.TestSpecialisedExplanations object at 0x26f8550>
|
||||
|
||||
def test_eq_list(self):
|
||||
> assert [0, 1, 2] == [0, 1, 3]
|
||||
@@ -166,7 +166,7 @@ get on the terminal - we are working on that):
|
||||
failure_demo.py:61: AssertionError
|
||||
______________ TestSpecialisedExplanations.test_eq_list_long _______________
|
||||
|
||||
self = <failure_demo.TestSpecialisedExplanations object at 0x135a990>
|
||||
self = <failure_demo.TestSpecialisedExplanations object at 0x26aa310>
|
||||
|
||||
def test_eq_list_long(self):
|
||||
a = [0]*100 + [1] + [3]*100
|
||||
@@ -178,12 +178,12 @@ get on the terminal - we are working on that):
|
||||
failure_demo.py:66: AssertionError
|
||||
_________________ TestSpecialisedExplanations.test_eq_dict _________________
|
||||
|
||||
self = <failure_demo.TestSpecialisedExplanations object at 0x1459310>
|
||||
self = <failure_demo.TestSpecialisedExplanations object at 0x26a6950>
|
||||
|
||||
def test_eq_dict(self):
|
||||
> assert {'a': 0, 'b': 1, 'c': 0} == {'a': 0, 'b': 2, 'd': 0}
|
||||
E assert {'a': 0, 'b': 1, 'c': 0} == {'a': 0, 'b': 2, 'd': 0}
|
||||
E Hiding 1 identical items, use -v to show
|
||||
E Omitting 1 identical items, use -v to show
|
||||
E Differing items:
|
||||
E {'b': 1} != {'b': 2}
|
||||
E Left contains more items:
|
||||
@@ -194,7 +194,7 @@ get on the terminal - we are working on that):
|
||||
failure_demo.py:69: AssertionError
|
||||
_________________ TestSpecialisedExplanations.test_eq_set __________________
|
||||
|
||||
self = <failure_demo.TestSpecialisedExplanations object at 0x1434310>
|
||||
self = <failure_demo.TestSpecialisedExplanations object at 0x26e4210>
|
||||
|
||||
def test_eq_set(self):
|
||||
> assert set([0, 10, 11, 12]) == set([0, 20, 21])
|
||||
@@ -210,7 +210,7 @@ get on the terminal - we are working on that):
|
||||
failure_demo.py:72: AssertionError
|
||||
_____________ TestSpecialisedExplanations.test_eq_longer_list ______________
|
||||
|
||||
self = <failure_demo.TestSpecialisedExplanations object at 0x138ded0>
|
||||
self = <failure_demo.TestSpecialisedExplanations object at 0x26f9c10>
|
||||
|
||||
def test_eq_longer_list(self):
|
||||
> assert [1,2] == [1,2,3]
|
||||
@@ -220,7 +220,7 @@ get on the terminal - we are working on that):
|
||||
failure_demo.py:75: AssertionError
|
||||
_________________ TestSpecialisedExplanations.test_in_list _________________
|
||||
|
||||
self = <failure_demo.TestSpecialisedExplanations object at 0x1459e10>
|
||||
self = <failure_demo.TestSpecialisedExplanations object at 0x26aac50>
|
||||
|
||||
def test_in_list(self):
|
||||
> assert 1 in [0, 2, 3, 4, 5]
|
||||
@@ -229,7 +229,7 @@ get on the terminal - we are working on that):
|
||||
failure_demo.py:78: AssertionError
|
||||
__________ TestSpecialisedExplanations.test_not_in_text_multiline __________
|
||||
|
||||
self = <failure_demo.TestSpecialisedExplanations object at 0x1434950>
|
||||
self = <failure_demo.TestSpecialisedExplanations object at 0x26a6b90>
|
||||
|
||||
def test_not_in_text_multiline(self):
|
||||
text = 'some multiline\ntext\nwhich\nincludes foo\nand a\ntail'
|
||||
@@ -247,7 +247,7 @@ get on the terminal - we are working on that):
|
||||
failure_demo.py:82: AssertionError
|
||||
___________ TestSpecialisedExplanations.test_not_in_text_single ____________
|
||||
|
||||
self = <failure_demo.TestSpecialisedExplanations object at 0x138dbd0>
|
||||
self = <failure_demo.TestSpecialisedExplanations object at 0x26f9d90>
|
||||
|
||||
def test_not_in_text_single(self):
|
||||
text = 'single foo line'
|
||||
@@ -260,7 +260,7 @@ get on the terminal - we are working on that):
|
||||
failure_demo.py:86: AssertionError
|
||||
_________ TestSpecialisedExplanations.test_not_in_text_single_long _________
|
||||
|
||||
self = <failure_demo.TestSpecialisedExplanations object at 0x14593d0>
|
||||
self = <failure_demo.TestSpecialisedExplanations object at 0x26f89d0>
|
||||
|
||||
def test_not_in_text_single_long(self):
|
||||
text = 'head ' * 50 + 'foo ' + 'tail ' * 20
|
||||
@@ -273,7 +273,7 @@ get on the terminal - we are working on that):
|
||||
failure_demo.py:90: AssertionError
|
||||
______ TestSpecialisedExplanations.test_not_in_text_single_long_term _______
|
||||
|
||||
self = <failure_demo.TestSpecialisedExplanations object at 0x1459650>
|
||||
self = <failure_demo.TestSpecialisedExplanations object at 0x26ad310>
|
||||
|
||||
def test_not_in_text_single_long_term(self):
|
||||
text = 'head ' * 50 + 'f'*70 + 'tail ' * 20
|
||||
@@ -292,7 +292,7 @@ get on the terminal - we are working on that):
|
||||
i = Foo()
|
||||
> assert i.b == 2
|
||||
E assert 1 == 2
|
||||
E + where 1 = <failure_demo.Foo object at 0x1434850>.b
|
||||
E + where 1 = <failure_demo.Foo object at 0x26e4650>.b
|
||||
|
||||
failure_demo.py:101: AssertionError
|
||||
_________________________ test_attribute_instance __________________________
|
||||
@@ -302,8 +302,8 @@ get on the terminal - we are working on that):
|
||||
b = 1
|
||||
> assert Foo().b == 2
|
||||
E assert 1 == 2
|
||||
E + where 1 = <failure_demo.Foo object at 0x1459dd0>.b
|
||||
E + where <failure_demo.Foo object at 0x1459dd0> = <class 'failure_demo.Foo'>()
|
||||
E + where 1 = <failure_demo.Foo object at 0x26f8c50>.b
|
||||
E + where <failure_demo.Foo object at 0x26f8c50> = <class 'failure_demo.Foo'>()
|
||||
|
||||
failure_demo.py:107: AssertionError
|
||||
__________________________ test_attribute_failure __________________________
|
||||
@@ -319,7 +319,7 @@ get on the terminal - we are working on that):
|
||||
failure_demo.py:116:
|
||||
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
|
||||
|
||||
self = <failure_demo.Foo object at 0x1434150>
|
||||
self = <failure_demo.Foo object at 0x26a65d0>
|
||||
|
||||
def _get_b(self):
|
||||
> raise Exception('Failed to get attrib')
|
||||
@@ -335,15 +335,15 @@ get on the terminal - we are working on that):
|
||||
b = 2
|
||||
> assert Foo().b == Bar().b
|
||||
E assert 1 == 2
|
||||
E + where 1 = <failure_demo.Foo object at 0x14590d0>.b
|
||||
E + where <failure_demo.Foo object at 0x14590d0> = <class 'failure_demo.Foo'>()
|
||||
E + and 2 = <failure_demo.Bar object at 0x1459b10>.b
|
||||
E + where <failure_demo.Bar object at 0x1459b10> = <class 'failure_demo.Bar'>()
|
||||
E + where 1 = <failure_demo.Foo object at 0x26ad050>.b
|
||||
E + where <failure_demo.Foo object at 0x26ad050> = <class 'failure_demo.Foo'>()
|
||||
E + and 2 = <failure_demo.Bar object at 0x26ad850>.b
|
||||
E + where <failure_demo.Bar object at 0x26ad850> = <class 'failure_demo.Bar'>()
|
||||
|
||||
failure_demo.py:124: AssertionError
|
||||
__________________________ TestRaises.test_raises __________________________
|
||||
|
||||
self = <failure_demo.TestRaises instance at 0x13a0d88>
|
||||
self = <failure_demo.TestRaises instance at 0x2859e18>
|
||||
|
||||
def test_raises(self):
|
||||
s = 'qwe'
|
||||
@@ -355,10 +355,10 @@ get on the terminal - we are working on that):
|
||||
> int(s)
|
||||
E ValueError: invalid literal for int() with base 10: 'qwe'
|
||||
|
||||
<0-codegen /home/hpk/p/pytest/.tox/regen/local/lib/python2.7/site-packages/_pytest/python.py:858>:1: ValueError
|
||||
<0-codegen /home/hpk/p/pytest/.tox/regen/local/lib/python2.7/site-packages/_pytest/python.py:905>:1: ValueError
|
||||
______________________ TestRaises.test_raises_doesnt _______________________
|
||||
|
||||
self = <failure_demo.TestRaises instance at 0x145fcf8>
|
||||
self = <failure_demo.TestRaises instance at 0x27013b0>
|
||||
|
||||
def test_raises_doesnt(self):
|
||||
> raises(IOError, "int('3')")
|
||||
@@ -367,7 +367,7 @@ get on the terminal - we are working on that):
|
||||
failure_demo.py:136: Failed
|
||||
__________________________ TestRaises.test_raise ___________________________
|
||||
|
||||
self = <failure_demo.TestRaises instance at 0x13a9ea8>
|
||||
self = <failure_demo.TestRaises instance at 0x271d9e0>
|
||||
|
||||
def test_raise(self):
|
||||
> raise ValueError("demo error")
|
||||
@@ -376,7 +376,7 @@ get on the terminal - we are working on that):
|
||||
failure_demo.py:139: ValueError
|
||||
________________________ TestRaises.test_tupleerror ________________________
|
||||
|
||||
self = <failure_demo.TestRaises instance at 0x13843f8>
|
||||
self = <failure_demo.TestRaises instance at 0x270b3f8>
|
||||
|
||||
def test_tupleerror(self):
|
||||
> a,b = [1]
|
||||
@@ -385,7 +385,7 @@ get on the terminal - we are working on that):
|
||||
failure_demo.py:142: ValueError
|
||||
______ TestRaises.test_reinterpret_fails_with_print_for_the_fun_of_it ______
|
||||
|
||||
self = <failure_demo.TestRaises instance at 0x14532d8>
|
||||
self = <failure_demo.TestRaises instance at 0x26ab368>
|
||||
|
||||
def test_reinterpret_fails_with_print_for_the_fun_of_it(self):
|
||||
l = [1,2,3]
|
||||
@@ -398,7 +398,7 @@ get on the terminal - we are working on that):
|
||||
l is [1, 2, 3]
|
||||
________________________ TestRaises.test_some_error ________________________
|
||||
|
||||
self = <failure_demo.TestRaises instance at 0x139d290>
|
||||
self = <failure_demo.TestRaises instance at 0x271b488>
|
||||
|
||||
def test_some_error(self):
|
||||
> if namenotexi:
|
||||
@@ -426,7 +426,7 @@ get on the terminal - we are working on that):
|
||||
<2-codegen 'abc-123' /home/hpk/p/pytest/doc/en/example/assertion/failure_demo.py:162>:2: AssertionError
|
||||
____________________ TestMoreErrors.test_complex_error _____________________
|
||||
|
||||
self = <failure_demo.TestMoreErrors instance at 0x137d758>
|
||||
self = <failure_demo.TestMoreErrors instance at 0x271da28>
|
||||
|
||||
def test_complex_error(self):
|
||||
def f():
|
||||
@@ -455,7 +455,7 @@ get on the terminal - we are working on that):
|
||||
failure_demo.py:5: AssertionError
|
||||
___________________ TestMoreErrors.test_z1_unpack_error ____________________
|
||||
|
||||
self = <failure_demo.TestMoreErrors instance at 0x13a5200>
|
||||
self = <failure_demo.TestMoreErrors instance at 0x2716950>
|
||||
|
||||
def test_z1_unpack_error(self):
|
||||
l = []
|
||||
@@ -465,7 +465,7 @@ get on the terminal - we are working on that):
|
||||
failure_demo.py:179: ValueError
|
||||
____________________ TestMoreErrors.test_z2_type_error _____________________
|
||||
|
||||
self = <failure_demo.TestMoreErrors instance at 0x1395290>
|
||||
self = <failure_demo.TestMoreErrors instance at 0x26f5e18>
|
||||
|
||||
def test_z2_type_error(self):
|
||||
l = 3
|
||||
@@ -475,19 +475,19 @@ get on the terminal - we are working on that):
|
||||
failure_demo.py:183: TypeError
|
||||
______________________ TestMoreErrors.test_startswith ______________________
|
||||
|
||||
self = <failure_demo.TestMoreErrors instance at 0x137f200>
|
||||
self = <failure_demo.TestMoreErrors instance at 0x27075f0>
|
||||
|
||||
def test_startswith(self):
|
||||
s = "123"
|
||||
g = "456"
|
||||
> assert s.startswith(g)
|
||||
E assert <built-in method startswith of str object at 0x143f288>('456')
|
||||
E + where <built-in method startswith of str object at 0x143f288> = '123'.startswith
|
||||
E assert <built-in method startswith of str object at 0x26ff8c8>('456')
|
||||
E + where <built-in method startswith of str object at 0x26ff8c8> = '123'.startswith
|
||||
|
||||
failure_demo.py:188: AssertionError
|
||||
__________________ TestMoreErrors.test_startswith_nested ___________________
|
||||
|
||||
self = <failure_demo.TestMoreErrors instance at 0x145fb00>
|
||||
self = <failure_demo.TestMoreErrors instance at 0x2707ef0>
|
||||
|
||||
def test_startswith_nested(self):
|
||||
def f():
|
||||
@@ -495,15 +495,15 @@ get on the terminal - we are working on that):
|
||||
def g():
|
||||
return "456"
|
||||
> assert f().startswith(g())
|
||||
E assert <built-in method startswith of str object at 0x143f288>('456')
|
||||
E + where <built-in method startswith of str object at 0x143f288> = '123'.startswith
|
||||
E + where '123' = <function f at 0x13abaa0>()
|
||||
E + and '456' = <function g at 0x13ab578>()
|
||||
E assert <built-in method startswith of str object at 0x26ff8c8>('456')
|
||||
E + where <built-in method startswith of str object at 0x26ff8c8> = '123'.startswith
|
||||
E + where '123' = <function f at 0x269d7d0>()
|
||||
E + and '456' = <function g at 0x2698ed8>()
|
||||
|
||||
failure_demo.py:195: AssertionError
|
||||
_____________________ TestMoreErrors.test_global_func ______________________
|
||||
|
||||
self = <failure_demo.TestMoreErrors instance at 0x139cd40>
|
||||
self = <failure_demo.TestMoreErrors instance at 0x271bef0>
|
||||
|
||||
def test_global_func(self):
|
||||
> assert isinstance(globf(42), float)
|
||||
@@ -513,18 +513,18 @@ get on the terminal - we are working on that):
|
||||
failure_demo.py:198: AssertionError
|
||||
_______________________ TestMoreErrors.test_instance _______________________
|
||||
|
||||
self = <failure_demo.TestMoreErrors instance at 0x13593b0>
|
||||
self = <failure_demo.TestMoreErrors instance at 0x271bb90>
|
||||
|
||||
def test_instance(self):
|
||||
self.x = 6*7
|
||||
> assert self.x != 42
|
||||
E assert 42 != 42
|
||||
E + where 42 = <failure_demo.TestMoreErrors instance at 0x13593b0>.x
|
||||
E + where 42 = <failure_demo.TestMoreErrors instance at 0x271bb90>.x
|
||||
|
||||
failure_demo.py:202: AssertionError
|
||||
_______________________ TestMoreErrors.test_compare ________________________
|
||||
|
||||
self = <failure_demo.TestMoreErrors instance at 0x1465d40>
|
||||
self = <failure_demo.TestMoreErrors instance at 0x2634170>
|
||||
|
||||
def test_compare(self):
|
||||
> assert globf(10) < 5
|
||||
@@ -534,7 +534,7 @@ get on the terminal - we are working on that):
|
||||
failure_demo.py:205: AssertionError
|
||||
_____________________ TestMoreErrors.test_try_finally ______________________
|
||||
|
||||
self = <failure_demo.TestMoreErrors instance at 0x1456ea8>
|
||||
self = <failure_demo.TestMoreErrors instance at 0x2717f80>
|
||||
|
||||
def test_try_finally(self):
|
||||
x = 1
|
||||
@@ -543,4 +543,4 @@ get on the terminal - we are working on that):
|
||||
E assert 1 == 0
|
||||
|
||||
failure_demo.py:210: AssertionError
|
||||
======================== 39 failed in 0.21 seconds =========================
|
||||
======================== 39 failed in 0.26 seconds =========================
|
||||
|
||||
@@ -55,6 +55,7 @@ Let's run this without supplying our new option::
|
||||
test_sample.py:6: AssertionError
|
||||
----------------------------- Captured stdout ------------------------------
|
||||
first
|
||||
1 failed in 0.01 seconds
|
||||
|
||||
And now with supplying a command line option::
|
||||
|
||||
@@ -76,6 +77,7 @@ And now with supplying a command line option::
|
||||
test_sample.py:6: AssertionError
|
||||
----------------------------- Captured stdout ------------------------------
|
||||
second
|
||||
1 failed in 0.01 seconds
|
||||
|
||||
You can see that the command line option arrived in our test. This
|
||||
completes the basic pattern. However, one often rather wants to process
|
||||
@@ -106,7 +108,7 @@ directory with the above conftest.py::
|
||||
|
||||
$ py.test
|
||||
=========================== test session starts ============================
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.3.5
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.4.2
|
||||
collected 0 items
|
||||
|
||||
============================= in 0.00 seconds =============================
|
||||
@@ -150,12 +152,12 @@ 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 linux2 -- Python 2.7.3 -- pytest-2.3.5
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.4.2
|
||||
collected 2 items
|
||||
|
||||
test_module.py .s
|
||||
========================= short test summary info ==========================
|
||||
SKIP [1] /tmp/doc-exec-278/conftest.py:9: need --runslow option to run
|
||||
SKIP [1] /tmp/doc-exec-603/conftest.py:9: need --runslow option to run
|
||||
|
||||
=================== 1 passed, 1 skipped in 0.01 seconds ====================
|
||||
|
||||
@@ -163,7 +165,7 @@ Or run it including the ``slow`` marked test::
|
||||
|
||||
$ py.test --runslow
|
||||
=========================== test session starts ============================
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.3.5
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.4.2
|
||||
collected 2 items
|
||||
|
||||
test_module.py ..
|
||||
@@ -206,6 +208,7 @@ Let's run our little function::
|
||||
E Failed: not configured: 42
|
||||
|
||||
test_checkconfig.py:8: Failed
|
||||
1 failed in 0.01 seconds
|
||||
|
||||
Detect if running from within a py.test run
|
||||
--------------------------------------------------------------
|
||||
@@ -253,7 +256,7 @@ which will add the string to the test header accordingly::
|
||||
|
||||
$ py.test
|
||||
=========================== test session starts ============================
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.3.5
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.4.2
|
||||
project deps: mylib-1.1
|
||||
collected 0 items
|
||||
|
||||
@@ -276,7 +279,7 @@ which will add info only when run with "--v"::
|
||||
|
||||
$ py.test -v
|
||||
=========================== test session starts ============================
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.3.5 -- /home/hpk/p/pytest/.tox/regen/bin/python
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.4.2 -- /home/hpk/p/pytest/.tox/regen/bin/python
|
||||
info1: did you know that ...
|
||||
did you?
|
||||
collecting ... collected 0 items
|
||||
@@ -287,7 +290,7 @@ and nothing when run plainly::
|
||||
|
||||
$ py.test
|
||||
=========================== test session starts ============================
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.3.5
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.4.2
|
||||
collected 0 items
|
||||
|
||||
============================= in 0.00 seconds =============================
|
||||
@@ -319,7 +322,7 @@ Now we can profile which test functions execute the slowest::
|
||||
|
||||
$ py.test --durations=3
|
||||
=========================== test session starts ============================
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.3.5
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.4.2
|
||||
collected 3 items
|
||||
|
||||
test_some_are_slow.py ...
|
||||
@@ -380,7 +383,7 @@ If we run this::
|
||||
|
||||
$ py.test -rx
|
||||
=========================== test session starts ============================
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.3.5
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.4.2
|
||||
collected 4 items
|
||||
|
||||
test_step.py .Fx.
|
||||
@@ -388,7 +391,7 @@ If we run this::
|
||||
================================= FAILURES =================================
|
||||
____________________ TestUserHandling.test_modification ____________________
|
||||
|
||||
self = <test_step.TestUserHandling instance at 0x282b8c0>
|
||||
self = <test_step.TestUserHandling instance at 0x1c6fb90>
|
||||
|
||||
def test_modification(self):
|
||||
> assert 0
|
||||
@@ -398,7 +401,7 @@ If we run this::
|
||||
========================= short test summary info ==========================
|
||||
XFAIL test_step.py::TestUserHandling::()::test_deletion
|
||||
reason: previous test failed (test_modification)
|
||||
============== 1 failed, 2 passed, 1 xfailed in 0.01 seconds ===============
|
||||
============== 1 failed, 2 passed, 1 xfailed in 0.02 seconds ===============
|
||||
|
||||
We'll see that ``test_deletion`` was not executed because ``test_modification``
|
||||
failed. It is reported as an "expected failure".
|
||||
@@ -450,7 +453,7 @@ We can run this::
|
||||
|
||||
$ py.test
|
||||
=========================== test session starts ============================
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.3.5
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.4.2
|
||||
collected 7 items
|
||||
|
||||
test_step.py .Fx.
|
||||
@@ -460,17 +463,17 @@ We can run this::
|
||||
|
||||
================================== ERRORS ==================================
|
||||
_______________________ ERROR at setup of test_root ________________________
|
||||
file /tmp/doc-exec-278/b/test_error.py, line 1
|
||||
file /tmp/doc-exec-603/b/test_error.py, line 1
|
||||
def test_root(db): # no db here, will error out
|
||||
fixture 'db' not found
|
||||
available fixtures: pytestconfig, recwarn, monkeypatch, capfd, capsys, tmpdir
|
||||
use 'py.test --fixtures [testpath]' for help on them.
|
||||
|
||||
/tmp/doc-exec-278/b/test_error.py:1
|
||||
/tmp/doc-exec-603/b/test_error.py:1
|
||||
================================= FAILURES =================================
|
||||
____________________ TestUserHandling.test_modification ____________________
|
||||
|
||||
self = <test_step.TestUserHandling instance at 0x26145f0>
|
||||
self = <test_step.TestUserHandling instance at 0x22f3518>
|
||||
|
||||
def test_modification(self):
|
||||
> assert 0
|
||||
@@ -479,20 +482,20 @@ We can run this::
|
||||
test_step.py:9: AssertionError
|
||||
_________________________________ test_a1 __________________________________
|
||||
|
||||
db = <conftest.DB instance at 0x26211b8>
|
||||
db = <conftest.DB instance at 0x2304248>
|
||||
|
||||
def test_a1(db):
|
||||
> assert 0, db # to show value
|
||||
E AssertionError: <conftest.DB instance at 0x26211b8>
|
||||
E AssertionError: <conftest.DB instance at 0x2304248>
|
||||
|
||||
a/test_db.py:2: AssertionError
|
||||
_________________________________ test_a2 __________________________________
|
||||
|
||||
db = <conftest.DB instance at 0x26211b8>
|
||||
db = <conftest.DB instance at 0x2304248>
|
||||
|
||||
def test_a2(db):
|
||||
> assert 0, db # to show value
|
||||
E AssertionError: <conftest.DB instance at 0x26211b8>
|
||||
E AssertionError: <conftest.DB instance at 0x2304248>
|
||||
|
||||
a/test_db2.py:2: AssertionError
|
||||
========== 3 failed, 2 passed, 1 xfailed, 1 error in 0.03 seconds ==========
|
||||
@@ -550,7 +553,7 @@ and run them::
|
||||
|
||||
$ py.test test_module.py
|
||||
=========================== test session starts ============================
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.3.5
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.4.2
|
||||
collected 2 items
|
||||
|
||||
test_module.py FF
|
||||
@@ -558,7 +561,7 @@ and run them::
|
||||
================================= FAILURES =================================
|
||||
________________________________ test_fail1 ________________________________
|
||||
|
||||
tmpdir = local('/tmp/pytest-326/test_fail10')
|
||||
tmpdir = local('/tmp/pytest-190/test_fail10')
|
||||
|
||||
def test_fail1(tmpdir):
|
||||
> assert 0
|
||||
@@ -572,12 +575,12 @@ and run them::
|
||||
E assert 0
|
||||
|
||||
test_module.py:4: AssertionError
|
||||
========================= 2 failed in 0.02 seconds =========================
|
||||
========================= 2 failed in 0.01 seconds =========================
|
||||
|
||||
you will have a "failures" file which contains the failing test ids::
|
||||
|
||||
$ cat failures
|
||||
test_module.py::test_fail1 (/tmp/pytest-326/test_fail10)
|
||||
test_module.py::test_fail1 (/tmp/pytest-190/test_fail10)
|
||||
test_module.py::test_fail2
|
||||
|
||||
Making test result information available in fixtures
|
||||
@@ -640,10 +643,12 @@ and run it::
|
||||
|
||||
$ py.test -s test_module.py
|
||||
=========================== test session starts ============================
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.3.5
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.4.2
|
||||
collected 3 items
|
||||
|
||||
test_module.py EFF
|
||||
test_module.py Esetting up a test failed! test_module.py::test_setup_fails
|
||||
Fexecuting test failed test_module.py::test_call_fails
|
||||
F
|
||||
|
||||
================================== ERRORS ==================================
|
||||
____________________ ERROR at setup of test_setup_fails ____________________
|
||||
@@ -671,9 +676,7 @@ and run it::
|
||||
E assert 0
|
||||
|
||||
test_module.py:15: AssertionError
|
||||
==================== 2 failed, 1 error in 0.01 seconds =====================
|
||||
setting up a test failed! test_module.py::test_setup_fails
|
||||
executing test failed test_module.py::test_call_fails
|
||||
==================== 2 failed, 1 error in 0.02 seconds =====================
|
||||
|
||||
You'll see that the fixture finalizers could use the precise reporting
|
||||
information.
|
||||
|
||||
@@ -61,12 +61,13 @@ will be called ahead of running any tests::
|
||||
If you run this without output capturing::
|
||||
|
||||
$ py.test -q -s test_module.py
|
||||
....
|
||||
callattr_ahead_of_alltests called
|
||||
callme called!
|
||||
callme other called
|
||||
SomeTest callme called
|
||||
test_method1 called
|
||||
test_method1 called
|
||||
test other
|
||||
test_unit1 method called
|
||||
.test_method1 called
|
||||
.test other
|
||||
.test_unit1 method called
|
||||
.
|
||||
4 passed in 0.02 seconds
|
||||
|
||||
@@ -3,9 +3,10 @@ Some Issues and Questions
|
||||
|
||||
.. note::
|
||||
|
||||
If you don't find an answer here, you may checkout
|
||||
This FAQ is here only mostly for historic reasons. Checkout
|
||||
`pytest Q&A at Stackoverflow <http://stackoverflow.com/search?q=pytest>`_
|
||||
or other :ref:`contact channels` to get help.
|
||||
for many questions and answers related to pytest and/or use
|
||||
:ref:`contact channels` to get help.
|
||||
|
||||
On naming, nosetests, licensing and magic
|
||||
------------------------------------------------
|
||||
@@ -94,12 +95,12 @@ but since many people have gotten used to the old name and there
|
||||
is another tool named "pytest" we just decided to stick with
|
||||
``py.test`` for now.
|
||||
|
||||
Function arguments, parametrized tests and setup
|
||||
pytest fixtures, parametrized tests
|
||||
-------------------------------------------------------
|
||||
|
||||
.. _funcargs: funcargs.html
|
||||
|
||||
Is using funcarg- versus xUnit setup a style question?
|
||||
Is using pytest fixtures versus xUnit setup a style question?
|
||||
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
For simple applications and for people experienced with nose_ or
|
||||
@@ -117,20 +118,6 @@ in a managed class/module/function scope.
|
||||
|
||||
.. _`why pytest_pyfuncarg__ methods?`:
|
||||
|
||||
Why the ``pytest_funcarg__*`` name for funcarg factories?
|
||||
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
We like `Convention over Configuration`_ and didn't see much point
|
||||
in allowing a more flexible or abstract mechanism. Moreover,
|
||||
it is nice to be able to search for ``pytest_funcarg__MYARG`` in
|
||||
source code and safely find all factory functions for
|
||||
the ``MYARG`` function argument.
|
||||
|
||||
.. note::
|
||||
|
||||
With pytest-2.3 you can use the :ref:`@pytest.fixture` decorator
|
||||
to mark a function as a fixture function.
|
||||
|
||||
.. _`Convention over Configuration`: http://en.wikipedia.org/wiki/Convention_over_Configuration
|
||||
|
||||
Can I yield multiple values from a fixture function function?
|
||||
@@ -139,16 +126,16 @@ Can I yield multiple values from a fixture function function?
|
||||
There are two conceptual reasons why yielding from a factory function
|
||||
is not possible:
|
||||
|
||||
* Calling factories for obtaining test function arguments
|
||||
is part of setting up and running a test. At that
|
||||
point it is not possible to add new test calls to
|
||||
the test collection anymore.
|
||||
|
||||
* If multiple factories yielded values there would
|
||||
be no natural place to determine the combination
|
||||
policy - in real-world examples some combinations
|
||||
often should not run.
|
||||
|
||||
* Calling factories for obtaining test function arguments
|
||||
is part of setting up and running a test. At that
|
||||
point it is not possible to add new test calls to
|
||||
the test collection anymore.
|
||||
|
||||
However, with pytest-2.3 you can use the :ref:`@pytest.fixture` decorator
|
||||
and specify ``params`` so that all tests depending on the factory-created
|
||||
resource will run multiple times with different parameters.
|
||||
|
||||
@@ -34,6 +34,12 @@ both styles, moving incrementally from classic to new style, as you
|
||||
prefer. You can also start out from existing :ref:`unittest.TestCase
|
||||
style <unittest.TestCase>` or :ref:`nose based <nosestyle>` projects.
|
||||
|
||||
.. note::
|
||||
|
||||
pytest-2.4 introduced an additional experimental
|
||||
:ref:`yield fixture mechanism <yieldfixture>` for easier context manager
|
||||
integration and more linear writing of teardown code.
|
||||
|
||||
.. _`funcargs`:
|
||||
.. _`funcarg mechanism`:
|
||||
.. _`fixture function`:
|
||||
@@ -70,8 +76,7 @@ marked ``smtp`` fixture function. Running the test looks like this::
|
||||
|
||||
$ py.test test_smtpsimple.py
|
||||
=========================== test session starts ============================
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.4.0.dev12
|
||||
plugins: xdist, pep8, cov, cache, capturelog, instafail
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.4.2
|
||||
collected 1 items
|
||||
|
||||
test_smtpsimple.py F
|
||||
@@ -79,7 +84,7 @@ marked ``smtp`` fixture function. Running the test looks like this::
|
||||
================================= FAILURES =================================
|
||||
________________________________ test_ehlo _________________________________
|
||||
|
||||
smtp = <smtplib.SMTP instance at 0x22530e0>
|
||||
smtp = <smtplib.SMTP instance at 0x2bb9d88>
|
||||
|
||||
def test_ehlo(smtp):
|
||||
response, msg = smtp.ehlo()
|
||||
@@ -89,7 +94,7 @@ marked ``smtp`` fixture function. Running the test looks like this::
|
||||
E assert 0
|
||||
|
||||
test_smtpsimple.py:12: AssertionError
|
||||
========================= 1 failed in 0.17 seconds =========================
|
||||
========================= 1 failed in 0.18 seconds =========================
|
||||
|
||||
In the failure traceback we see that the test function was called with a
|
||||
``smtp`` argument, the ``smtplib.SMTP()`` instance created by the fixture
|
||||
@@ -189,8 +194,7 @@ inspect what is going on and can now run the tests::
|
||||
|
||||
$ py.test test_module.py
|
||||
=========================== test session starts ============================
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.4.0.dev12
|
||||
plugins: xdist, pep8, cov, cache, capturelog, instafail
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.4.2
|
||||
collected 2 items
|
||||
|
||||
test_module.py FF
|
||||
@@ -198,7 +202,7 @@ inspect what is going on and can now run the tests::
|
||||
================================= FAILURES =================================
|
||||
________________________________ test_ehlo _________________________________
|
||||
|
||||
smtp = <smtplib.SMTP instance at 0x165fa28>
|
||||
smtp = <smtplib.SMTP instance at 0x18f2fc8>
|
||||
|
||||
def test_ehlo(smtp):
|
||||
response = smtp.ehlo()
|
||||
@@ -210,7 +214,7 @@ inspect what is going on and can now run the tests::
|
||||
test_module.py:6: AssertionError
|
||||
________________________________ test_noop _________________________________
|
||||
|
||||
smtp = <smtplib.SMTP instance at 0x165fa28>
|
||||
smtp = <smtplib.SMTP instance at 0x18f2fc8>
|
||||
|
||||
def test_noop(smtp):
|
||||
response = smtp.noop()
|
||||
@@ -219,7 +223,7 @@ inspect what is going on and can now run the tests::
|
||||
E assert 0
|
||||
|
||||
test_module.py:11: AssertionError
|
||||
========================= 2 failed in 0.18 seconds =========================
|
||||
========================= 2 failed in 0.16 seconds =========================
|
||||
|
||||
You see the two ``assert 0`` failing and more importantly you can also see
|
||||
that the same (module-scoped) ``smtp`` object was passed into the two
|
||||
@@ -265,8 +269,9 @@ the fixture in the module has finished execution.
|
||||
Let's execute it::
|
||||
|
||||
$ py.test -s -q --tb=no
|
||||
FF
|
||||
2 failed in 0.20 seconds
|
||||
FFteardown smtp
|
||||
|
||||
2 failed in 0.15 seconds
|
||||
|
||||
We see that the ``smtp`` instance is finalized after the two
|
||||
tests finished execution. Note that if we decorated our fixture
|
||||
@@ -275,9 +280,6 @@ occur around each single test. In either case the test
|
||||
module itself does not need to change or know about these details
|
||||
of fixture setup.
|
||||
|
||||
Note that pytest-2.4 introduced an experimental alternative
|
||||
:ref:`yield fixture mechanism <yieldfixture>` for easier context manager
|
||||
integration and more linear writing of teardown code.
|
||||
|
||||
.. _`request-context`:
|
||||
|
||||
@@ -310,7 +312,7 @@ again, nothing much has changed::
|
||||
|
||||
$ py.test -s -q --tb=no
|
||||
FF
|
||||
2 failed in 0.18 seconds
|
||||
2 failed in 0.16 seconds
|
||||
|
||||
Let's quickly create another test module that actually sets the
|
||||
server URL in its module namespace::
|
||||
@@ -377,7 +379,7 @@ So let's just do another run::
|
||||
================================= FAILURES =================================
|
||||
__________________________ test_ehlo[merlinux.eu] __________________________
|
||||
|
||||
smtp = <smtplib.SMTP instance at 0x28d13b0>
|
||||
smtp = <smtplib.SMTP instance at 0x2662290>
|
||||
|
||||
def test_ehlo(smtp):
|
||||
response = smtp.ehlo()
|
||||
@@ -389,7 +391,7 @@ So let's just do another run::
|
||||
test_module.py:6: AssertionError
|
||||
__________________________ test_noop[merlinux.eu] __________________________
|
||||
|
||||
smtp = <smtplib.SMTP instance at 0x28d13b0>
|
||||
smtp = <smtplib.SMTP instance at 0x2662290>
|
||||
|
||||
def test_noop(smtp):
|
||||
response = smtp.noop()
|
||||
@@ -400,7 +402,7 @@ So let's just do another run::
|
||||
test_module.py:11: AssertionError
|
||||
________________________ test_ehlo[mail.python.org] ________________________
|
||||
|
||||
smtp = <smtplib.SMTP instance at 0x28d8440>
|
||||
smtp = <smtplib.SMTP instance at 0x26c2dd0>
|
||||
|
||||
def test_ehlo(smtp):
|
||||
response = smtp.ehlo()
|
||||
@@ -411,7 +413,7 @@ So let's just do another run::
|
||||
test_module.py:5: AssertionError
|
||||
________________________ test_noop[mail.python.org] ________________________
|
||||
|
||||
smtp = <smtplib.SMTP instance at 0x28d8440>
|
||||
smtp = <smtplib.SMTP instance at 0x26c2dd0>
|
||||
|
||||
def test_noop(smtp):
|
||||
response = smtp.noop()
|
||||
@@ -420,7 +422,7 @@ So let's just do another run::
|
||||
E assert 0
|
||||
|
||||
test_module.py:11: AssertionError
|
||||
4 failed in 6.47 seconds
|
||||
4 failed in 6.32 seconds
|
||||
|
||||
We see that our two test functions each ran twice, against the different
|
||||
``smtp`` instances. Note also, that with the ``mail.python.org``
|
||||
@@ -460,15 +462,13 @@ Here we declare an ``app`` fixture which receives the previously defined
|
||||
|
||||
$ py.test -v test_appsetup.py
|
||||
=========================== test session starts ============================
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.4.0.dev12 -- /home/hpk/venv/0/bin/python
|
||||
cachedir: /tmp/doc-exec-127/.cache
|
||||
plugins: xdist, pep8, cov, cache, capturelog, instafail
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.4.2 -- /home/hpk/p/pytest/.tox/regen/bin/python
|
||||
collecting ... collected 2 items
|
||||
|
||||
test_appsetup.py:12: test_smtp_exists[mail.python.org] PASSED
|
||||
test_appsetup.py:12: test_smtp_exists[merlinux.eu] PASSED
|
||||
|
||||
========================= 2 passed in 6.07 seconds =========================
|
||||
========================= 2 passed in 5.75 seconds =========================
|
||||
|
||||
Due to the parametrization of ``smtp`` the test will run twice with two
|
||||
different ``App`` instances and respective smtp servers. There is no
|
||||
@@ -526,9 +526,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 linux2 -- Python 2.7.3 -- pytest-2.4.0.dev12 -- /home/hpk/venv/0/bin/python
|
||||
cachedir: /tmp/doc-exec-127/.cache
|
||||
plugins: xdist, pep8, cov, cache, capturelog, instafail
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.4.2 -- /home/hpk/p/pytest/.tox/regen/bin/python
|
||||
collecting ... collected 8 items
|
||||
|
||||
test_module.py:15: test_0[1] test0 1
|
||||
@@ -550,7 +548,7 @@ Let's run the tests in verbose mode and with looking at the print-output::
|
||||
test_module.py:19: test_2[2-mod2] test2 2 mod2
|
||||
PASSED
|
||||
|
||||
========================= 8 passed in 0.02 seconds =========================
|
||||
========================= 8 passed in 0.01 seconds =========================
|
||||
|
||||
You can see that the parametrized module-scoped ``modarg`` resource caused
|
||||
an ordering of test execution that lead to the fewest possible "active" resources. The finalizer for the ``mod1`` parametrized resource was executed
|
||||
@@ -606,7 +604,7 @@ to verify our fixture is activated and the tests pass::
|
||||
|
||||
$ py.test -q
|
||||
..
|
||||
2 passed in 0.02 seconds
|
||||
2 passed in 0.01 seconds
|
||||
|
||||
You can specify multiple fixtures like this::
|
||||
|
||||
@@ -677,7 +675,7 @@ If we run it, we get two passing tests::
|
||||
|
||||
$ py.test -q
|
||||
..
|
||||
2 passed in 0.02 seconds
|
||||
2 passed in 0.01 seconds
|
||||
|
||||
Here is how autouse fixtures work in other scopes:
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ Installation options::
|
||||
To check your installation has installed the correct version::
|
||||
|
||||
$ py.test --version
|
||||
This is py.test version 2.3.5, imported from /home/hpk/p/pytest/.tox/regen/local/lib/python2.7/site-packages/pytest.py
|
||||
This is py.test version 2.4.2, imported from /home/hpk/p/pytest/.tox/regen/local/lib/python2.7/site-packages/pytest.pyc
|
||||
|
||||
If you get an error checkout :ref:`installation issues`.
|
||||
|
||||
@@ -45,7 +45,7 @@ That's it. You can execute the test function now::
|
||||
|
||||
$ py.test
|
||||
=========================== test session starts ============================
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.3.5
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.4.2
|
||||
collected 1 items
|
||||
|
||||
test_sample.py F
|
||||
@@ -93,6 +93,7 @@ Running it with, this time in "quiet" reporting mode::
|
||||
|
||||
$ py.test -q test_sysexit.py
|
||||
.
|
||||
1 passed in 0.01 seconds
|
||||
|
||||
.. todo:: For further ways to assert exceptions see the `raises`
|
||||
|
||||
@@ -122,7 +123,7 @@ run the module by passing its filename::
|
||||
================================= FAILURES =================================
|
||||
____________________________ TestClass.test_two ____________________________
|
||||
|
||||
self = <test_class.TestClass instance at 0x315b488>
|
||||
self = <test_class.TestClass instance at 0x1e1f518>
|
||||
|
||||
def test_two(self):
|
||||
x = "hello"
|
||||
@@ -130,6 +131,7 @@ run the module by passing its filename::
|
||||
E assert hasattr('hello', 'check')
|
||||
|
||||
test_class.py:8: AssertionError
|
||||
1 failed, 1 passed in 0.01 seconds
|
||||
|
||||
The first test passed, the second failed. Again we can easily see
|
||||
the intermediate values used in the assertion, helping us to
|
||||
@@ -157,7 +159,7 @@ before performing the test function call. Let's just run it::
|
||||
================================= FAILURES =================================
|
||||
_____________________________ test_needsfiles ______________________________
|
||||
|
||||
tmpdir = local('/tmp/pytest-322/test_needsfiles0')
|
||||
tmpdir = local('/tmp/pytest-186/test_needsfiles0')
|
||||
|
||||
def test_needsfiles(tmpdir):
|
||||
print tmpdir
|
||||
@@ -166,7 +168,8 @@ before performing the test function call. Let's just run it::
|
||||
|
||||
test_tmpdir.py:3: AssertionError
|
||||
----------------------------- Captured stdout ------------------------------
|
||||
/tmp/pytest-322/test_needsfiles0
|
||||
/tmp/pytest-186/test_needsfiles0
|
||||
1 failed in 0.01 seconds
|
||||
|
||||
Before the test runs, a unique-per-test-invocation temporary directory
|
||||
was created. More info at :ref:`tmpdir handling`.
|
||||
|
||||
@@ -52,15 +52,14 @@ tuples so that that the ``test_eval`` function will run three times using
|
||||
them in turn::
|
||||
|
||||
$ py.test
|
||||
============================= test session starts ==============================
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.4.0.dev3
|
||||
plugins: xdist, cache, cli, pep8, xprocess, cov, capturelog, bdd-splinter, rerunfailures, instafail, localserver
|
||||
=========================== test session starts ============================
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.4.2
|
||||
collected 3 items
|
||||
|
||||
test_expectation.py ..F
|
||||
|
||||
=================================== FAILURES ===================================
|
||||
______________________________ test_eval[6*9-42] _______________________________
|
||||
================================= FAILURES =================================
|
||||
____________________________ test_eval[6*9-42] _____________________________
|
||||
|
||||
input = '6*9', expected = 42
|
||||
|
||||
@@ -75,7 +74,7 @@ them in turn::
|
||||
E + where 54 = eval('6*9')
|
||||
|
||||
test_expectation.py:8: AssertionError
|
||||
====================== 1 failed, 2 passed in 0.02 seconds ======================
|
||||
==================== 1 failed, 2 passed in 0.01 seconds ====================
|
||||
|
||||
As designed in this example, only one pair of input/output values fails
|
||||
the simple test function. And as usual with test function arguments,
|
||||
@@ -100,14 +99,13 @@ for example with the builtin ``mark.xfail``::
|
||||
Let's run this::
|
||||
|
||||
$ py.test
|
||||
============================= test session starts ==============================
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.4.0.dev3
|
||||
plugins: xdist, cache, cli, pep8, xprocess, cov, capturelog, bdd-splinter, rerunfailures, instafail, localserver
|
||||
=========================== test session starts ============================
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.4.2
|
||||
collected 3 items
|
||||
|
||||
test_expectation.py ..x
|
||||
|
||||
===================== 2 passed, 1 xfailed in 0.02 seconds ======================
|
||||
=================== 2 passed, 1 xfailed in 0.01 seconds ====================
|
||||
|
||||
The one parameter set which caused a failure previously now
|
||||
shows up as an "xfailed (expected to fail)" test.
|
||||
@@ -159,22 +157,24 @@ If we now pass two stringinput values, our test will run twice::
|
||||
|
||||
$ py.test -q --stringinput="hello" --stringinput="world" test_strings.py
|
||||
..
|
||||
2 passed in 0.01 seconds
|
||||
|
||||
Let's also run with a stringinput that will lead to a failing test::
|
||||
|
||||
$ py.test -q --stringinput="!" test_strings.py
|
||||
F
|
||||
=================================== FAILURES ===================================
|
||||
_____________________________ test_valid_string[!] _____________________________
|
||||
================================= FAILURES =================================
|
||||
___________________________ test_valid_string[!] ___________________________
|
||||
|
||||
stringinput = '!'
|
||||
|
||||
def test_valid_string(stringinput):
|
||||
> assert stringinput.isalpha()
|
||||
E assert <built-in method isalpha of str object at 0x7fd657390fd0>()
|
||||
E + where <built-in method isalpha of str object at 0x7fd657390fd0> = '!'.isalpha
|
||||
E assert <built-in method isalpha of str object at 0x2ac85b043198>()
|
||||
E + where <built-in method isalpha of str object at 0x2ac85b043198> = '!'.isalpha
|
||||
|
||||
test_strings.py:3: AssertionError
|
||||
1 failed in 0.01 seconds
|
||||
|
||||
As expected our test function fails.
|
||||
|
||||
@@ -184,8 +184,9 @@ listlist::
|
||||
|
||||
$ py.test -q -rs test_strings.py
|
||||
s
|
||||
=========================== short test summary info ============================
|
||||
SKIP [1] /home/hpk/p/pytest/_pytest/python.py:999: got empty parameter set, function test_valid_string at /tmp/doc-exec-2/test_strings.py:1
|
||||
========================= short test summary info ==========================
|
||||
SKIP [1] /home/hpk/p/pytest/.tox/regen/local/lib/python2.7/site-packages/_pytest/python.py:1024: got empty parameter set, function test_valid_string at /tmp/doc-exec-561/test_strings.py:1
|
||||
1 skipped in 0.01 seconds
|
||||
|
||||
For further examples, you might want to look at :ref:`more
|
||||
parametrization examples <paramexamples>`.
|
||||
|
||||
@@ -158,14 +158,14 @@ Running it with the report-on-xfail option gives this output::
|
||||
|
||||
example $ py.test -rx xfail_demo.py
|
||||
=========================== test session starts ============================
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.3.5
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.4.2
|
||||
collected 6 items
|
||||
|
||||
|
||||
xfail_demo.py xxxxxx
|
||||
========================= short test summary info ==========================
|
||||
XFAIL xfail_demo.py::test_hello
|
||||
XFAIL xfail_demo.py::test_hello2
|
||||
reason: [NOTRUN]
|
||||
reason: [NOTRUN]
|
||||
XFAIL xfail_demo.py::test_hello3
|
||||
condition: hasattr(os, 'sep')
|
||||
XFAIL xfail_demo.py::test_hello4
|
||||
@@ -174,7 +174,7 @@ Running it with the report-on-xfail option gives this output::
|
||||
condition: pytest.__version__[0] != "17"
|
||||
XFAIL xfail_demo.py::test_hello6
|
||||
reason: reason
|
||||
|
||||
|
||||
======================== 6 xfailed in 0.05 seconds =========================
|
||||
|
||||
.. _`skip/xfail with parametrize`:
|
||||
@@ -183,7 +183,7 @@ Skip/xfail with parametrize
|
||||
---------------------------
|
||||
|
||||
It is possible to apply markers like skip and xfail to individual
|
||||
test instances when using parametrize:
|
||||
test instances when using parametrize::
|
||||
|
||||
import pytest
|
||||
|
||||
@@ -191,7 +191,7 @@ test instances when using parametrize:
|
||||
(1, 2),
|
||||
pytest.mark.xfail((1, 0)),
|
||||
pytest.mark.xfail(reason="some bug")((1, 3)),
|
||||
(2, 3),
|
||||
(2, 3),
|
||||
(3, 4),
|
||||
(4, 5),
|
||||
pytest.mark.skipif("sys.version_info >= (3,0)")((10, 11)),
|
||||
|
||||
@@ -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 linux2 -- Python 2.7.3 -- pytest-2.3.5
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.4.2
|
||||
collected 1 items
|
||||
|
||||
test_tmpdir.py F
|
||||
@@ -37,7 +37,7 @@ Running this would result in a passed test except for the last
|
||||
================================= FAILURES =================================
|
||||
_____________________________ test_create_file _____________________________
|
||||
|
||||
tmpdir = local('/tmp/pytest-323/test_create_file0')
|
||||
tmpdir = local('/tmp/pytest-187/test_create_file0')
|
||||
|
||||
def test_create_file(tmpdir):
|
||||
p = tmpdir.mkdir("sub").join("hello.txt")
|
||||
@@ -48,7 +48,7 @@ Running this would result in a passed test except for the last
|
||||
E assert 0
|
||||
|
||||
test_tmpdir.py:7: AssertionError
|
||||
========================= 1 failed in 0.02 seconds =========================
|
||||
========================= 1 failed in 0.01 seconds =========================
|
||||
|
||||
.. _`base temporary directory`:
|
||||
|
||||
|
||||
@@ -88,7 +88,7 @@ the ``self.db`` values in the traceback::
|
||||
|
||||
$ py.test test_unittest_db.py
|
||||
=========================== test session starts ============================
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.3.5
|
||||
platform linux2 -- Python 2.7.3 -- pytest-2.4.2
|
||||
collected 2 items
|
||||
|
||||
test_unittest_db.py FF
|
||||
@@ -101,7 +101,7 @@ the ``self.db`` values in the traceback::
|
||||
def test_method1(self):
|
||||
assert hasattr(self, "db")
|
||||
> assert 0, self.db # fail for demo purposes
|
||||
E AssertionError: <conftest.DummyDB instance at 0x19fdf38>
|
||||
E AssertionError: <conftest.DummyDB instance at 0x27b2b00>
|
||||
|
||||
test_unittest_db.py:9: AssertionError
|
||||
___________________________ MyTest.test_method2 ____________________________
|
||||
@@ -110,7 +110,7 @@ the ``self.db`` values in the traceback::
|
||||
|
||||
def test_method2(self):
|
||||
> assert 0, self.db # fail for demo purposes
|
||||
E AssertionError: <conftest.DummyDB instance at 0x19fdf38>
|
||||
E AssertionError: <conftest.DummyDB instance at 0x27b2b00>
|
||||
|
||||
test_unittest_db.py:12: AssertionError
|
||||
========================= 2 failed in 0.02 seconds =========================
|
||||
@@ -160,6 +160,7 @@ Running this test module ...::
|
||||
|
||||
$ py.test -q test_unittest_cleandir.py
|
||||
.
|
||||
1 passed in 0.02 seconds
|
||||
|
||||
... gives us one passed test because the ``initdir`` fixture function
|
||||
was executed ahead of the ``test_method``.
|
||||
|
||||
@@ -188,7 +188,7 @@ Running it will show that ``MyPlugin`` was added and its
|
||||
hook was invoked::
|
||||
|
||||
$ python myinvoke.py
|
||||
|
||||
*** test run reporting finishing
|
||||
|
||||
|
||||
.. include:: links.inc
|
||||
|
||||
@@ -8,7 +8,7 @@ Fixture functions using "yield" / context manager integration
|
||||
|
||||
.. regendoc:wipe
|
||||
|
||||
pytest-2.4 allows fixture functions to seemlessly use a ``yield`` instead
|
||||
pytest-2.4 allows fixture functions to seamlessly use a ``yield`` instead
|
||||
of a ``return`` statement to provide a fixture value while otherwise
|
||||
fully supporting all other fixture features.
|
||||
|
||||
@@ -92,7 +92,7 @@ In general, the advantages of the using a ``yield`` fixture syntax are:
|
||||
|
||||
However, there are also limitations or foreseeable irritations:
|
||||
|
||||
- usually ``yield`` is typically used for producing multiple values.
|
||||
- usually ``yield`` is used for producing multiple values.
|
||||
But fixture functions can only yield exactly one value.
|
||||
Yielding a second fixture value will get you an error.
|
||||
It's possible we can evolve pytest to allow for producing
|
||||
@@ -119,13 +119,6 @@ However, there are also limitations or foreseeable irritations:
|
||||
Others can start experimenting with writing yield-style fixtures
|
||||
and possibly help evolving them further.
|
||||
|
||||
Some developers also expressed their preference for
|
||||
rather introduce a new ``@pytest.yieldfixture`` decorator
|
||||
instead of a keyword argument, or for assuming the above
|
||||
yield-semantics automatically by introspecting if a fixture
|
||||
function is a generator. Depending on more experiences and
|
||||
feedback during the 2.4 cycle, we revisit theses issues.
|
||||
|
||||
If you want to feedback or participate in the ongoing
|
||||
discussion, please join our :ref:`contact channels`.
|
||||
you are most welcome.
|
||||
|
||||
20
plugin-test.sh
Normal file
20
plugin-test.sh
Normal file
@@ -0,0 +1,20 @@
|
||||
#!/bin/bash
|
||||
|
||||
# this assumes plugins are installed as sister directories
|
||||
|
||||
set -e
|
||||
cd ../pytest-pep8
|
||||
py.test
|
||||
cd ../pytest-instafail
|
||||
py.test
|
||||
cd ../pytest-cache
|
||||
py.test
|
||||
cd ../pytest-xprocess
|
||||
py.test
|
||||
#cd ../pytest-cov
|
||||
#py.test
|
||||
cd ../pytest-capturelog
|
||||
py.test
|
||||
cd ../pytest-xdist
|
||||
py.test
|
||||
|
||||
8
setup.cfg
Normal file
8
setup.cfg
Normal file
@@ -0,0 +1,8 @@
|
||||
[build_sphinx]
|
||||
source-dir = doc/en/
|
||||
build-dir = doc/build
|
||||
all_files = 1
|
||||
|
||||
[upload_sphinx]
|
||||
upload-dir = doc/en/build/html
|
||||
|
||||
6
setup.py
6
setup.py
@@ -3,15 +3,17 @@ from setuptools import setup, Command
|
||||
|
||||
long_description = open("README.rst").read()
|
||||
def main():
|
||||
install_requires = ["py>=1.4.16"]
|
||||
install_requires = ["py>=1.4.17"]
|
||||
if sys.version_info < (2,7):
|
||||
install_requires.append("argparse")
|
||||
if sys.platform == "win32":
|
||||
install_requires.append("colorama")
|
||||
|
||||
setup(
|
||||
name='pytest',
|
||||
description='py.test: simple powerful testing with Python',
|
||||
long_description = long_description,
|
||||
version='2.4.0',
|
||||
version='2.4.2',
|
||||
url='http://pytest.org',
|
||||
license='MIT license',
|
||||
platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'],
|
||||
|
||||
@@ -504,7 +504,7 @@ class TestInvocationVariants:
|
||||
class TestDurations:
|
||||
source = """
|
||||
import time
|
||||
frag = 0.02
|
||||
frag = 0.002
|
||||
def test_something():
|
||||
pass
|
||||
def test_2():
|
||||
@@ -519,7 +519,7 @@ class TestDurations:
|
||||
testdir.makepyfile(self.source)
|
||||
result = testdir.runpytest("--durations=10")
|
||||
assert result.ret == 0
|
||||
result.stdout.fnmatch_lines([
|
||||
result.stdout.fnmatch_lines_random([
|
||||
"*durations*",
|
||||
"*call*test_3*",
|
||||
"*call*test_2*",
|
||||
@@ -530,12 +530,8 @@ class TestDurations:
|
||||
testdir.makepyfile(self.source)
|
||||
result = testdir.runpytest("--durations=2")
|
||||
assert result.ret == 0
|
||||
result.stdout.fnmatch_lines([
|
||||
"*durations*",
|
||||
"*call*test_3*",
|
||||
"*call*test_2*",
|
||||
])
|
||||
assert "test_1" not in result.stdout.str()
|
||||
lines = result.stdout.get_lines_after("*slowest*durations*")
|
||||
assert "4 passed" in lines[2]
|
||||
|
||||
def test_calls_showall(self, testdir):
|
||||
testdir.makepyfile(self.source)
|
||||
@@ -573,7 +569,7 @@ class TestDurations:
|
||||
class TestDurationWithFixture:
|
||||
source = """
|
||||
import time
|
||||
frag = 0.01
|
||||
frag = 0.001
|
||||
def setup_function(func):
|
||||
time.sleep(frag * 3)
|
||||
def test_1():
|
||||
|
||||
@@ -316,6 +316,16 @@ class TestFunction:
|
||||
reprec = testdir.inline_run()
|
||||
reprec.assertoutcome(skipped=1)
|
||||
|
||||
def test_single_tuple_unwraps_values(self, testdir):
|
||||
testdir.makepyfile("""
|
||||
import pytest
|
||||
@pytest.mark.parametrize(('arg',), [(1,)])
|
||||
def test_function(arg):
|
||||
assert arg == 1
|
||||
""")
|
||||
reprec = testdir.inline_run()
|
||||
reprec.assertoutcome(passed=1)
|
||||
|
||||
def test_issue213_parametrize_value_no_equal(self, testdir):
|
||||
testdir.makepyfile("""
|
||||
import pytest
|
||||
|
||||
@@ -566,4 +566,25 @@ def test_matchnodes_two_collections_same_file(testdir):
|
||||
])
|
||||
|
||||
|
||||
class TestNodekeywords:
|
||||
def test_no_under(self, testdir):
|
||||
modcol = testdir.getmodulecol("""
|
||||
def test_pass(): pass
|
||||
def test_fail(): assert 0
|
||||
""")
|
||||
l = list(modcol.keywords)
|
||||
assert modcol.name in l
|
||||
for x in l:
|
||||
assert not x.startswith("_")
|
||||
assert modcol.name in repr(modcol.keywords)
|
||||
|
||||
def test_issue345(self, testdir):
|
||||
testdir.makepyfile("""
|
||||
def test_should_not_be_selected():
|
||||
assert False, 'I should not have been selected to run'
|
||||
|
||||
def test___repr__():
|
||||
pass
|
||||
""")
|
||||
reprec = testdir.inline_run("-k repr")
|
||||
reprec.assertoutcome(passed=1, failed=0)
|
||||
|
||||
@@ -113,6 +113,17 @@ class TestConfigAPI:
|
||||
assert config.getoption(x) == "this"
|
||||
pytest.raises(ValueError, "config.getoption('qweqwe')")
|
||||
|
||||
@pytest.mark.skipif('sys.version_info[:2] not in [(2, 6), (2, 7)]')
|
||||
def test_config_getoption_unicode(self, testdir):
|
||||
testdir.makeconftest("""
|
||||
from __future__ import unicode_literals
|
||||
|
||||
def pytest_addoption(parser):
|
||||
parser.addoption('--hello', type='string')
|
||||
""")
|
||||
config = testdir.parseconfig('--hello=this')
|
||||
assert config.getoption('hello') == 'this'
|
||||
|
||||
def test_config_getvalueorskip(self, testdir):
|
||||
config = testdir.parseconfig()
|
||||
pytest.raises(pytest.skip.Exception,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
|
||||
import pytest
|
||||
from xml.dom import minidom
|
||||
import py, sys, os
|
||||
|
||||
@@ -427,16 +427,16 @@ def test_invalid_xml_escape():
|
||||
def test_logxml_path_expansion(tmpdir, monkeypatch):
|
||||
from _pytest.junitxml import LogXML
|
||||
|
||||
home_tilde = os.path.normpath(os.path.expanduser('~/test.xml'))
|
||||
home_tilde = py.path.local(os.path.expanduser('~')).join('test.xml')
|
||||
|
||||
xml_tilde = LogXML('~/test.xml', None)
|
||||
xml_tilde = LogXML('~%stest.xml' % tmpdir.sep, None)
|
||||
assert xml_tilde.logfile == home_tilde
|
||||
|
||||
# this is here for when $HOME is not set correct
|
||||
monkeypatch.setenv("HOME", tmpdir)
|
||||
home_var = os.path.normpath(os.path.expandvars('$HOME/test.xml'))
|
||||
|
||||
xml_var = LogXML('$HOME/test.xml', None)
|
||||
xml_var = LogXML('$HOME%stest.xml' % tmpdir.sep, None)
|
||||
assert xml_var.logfile == home_var
|
||||
|
||||
def test_logxml_changingdir(testdir):
|
||||
|
||||
@@ -180,6 +180,7 @@ def test_keyword_option_custom(spec, testdir):
|
||||
assert len(passed) == len(passed_result)
|
||||
assert list(passed) == list(passed_result)
|
||||
|
||||
|
||||
class TestFunctional:
|
||||
|
||||
def test_mark_per_function(self, testdir):
|
||||
@@ -362,7 +363,6 @@ class TestFunctional:
|
||||
deselected_tests = dlist[0].items
|
||||
assert len(deselected_tests) == 2
|
||||
|
||||
|
||||
def test_keywords_at_node_level(self, testdir):
|
||||
p = testdir.makepyfile("""
|
||||
import pytest
|
||||
@@ -383,6 +383,30 @@ class TestFunctional:
|
||||
reprec = testdir.inline_run()
|
||||
reprec.assertoutcome(passed=1)
|
||||
|
||||
def test_keyword_added_for_session(self, testdir):
|
||||
testdir.makeconftest("""
|
||||
import pytest
|
||||
def pytest_collection_modifyitems(session):
|
||||
session.add_marker("mark1")
|
||||
session.add_marker(pytest.mark.mark2)
|
||||
session.add_marker(pytest.mark.mark3)
|
||||
pytest.raises(ValueError, lambda:
|
||||
session.add_marker(10))
|
||||
""")
|
||||
testdir.makepyfile("""
|
||||
def test_some(request):
|
||||
assert "mark1" in request.keywords
|
||||
assert "mark2" in request.keywords
|
||||
assert "mark3" in request.keywords
|
||||
assert 10 not in request.keywords
|
||||
marker = request.node.get_marker("mark1")
|
||||
assert marker.name == "mark1"
|
||||
assert marker.args == ()
|
||||
assert marker.kwargs == {}
|
||||
""")
|
||||
reprec = testdir.inline_run("-m", "mark1")
|
||||
reprec.assertoutcome(passed=1)
|
||||
|
||||
class TestKeywordSelection:
|
||||
def test_select_simple(self, testdir):
|
||||
file_test = testdir.makepyfile("""
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
from __future__ import with_statement
|
||||
import sys
|
||||
import os
|
||||
import py, pytest
|
||||
from _pytest import config as parseopt
|
||||
from textwrap import dedent
|
||||
@@ -250,14 +252,16 @@ def test_addoption_parser_epilog(testdir):
|
||||
def test_argcomplete(testdir, monkeypatch):
|
||||
if not py.path.local.sysfind('bash'):
|
||||
pytest.skip("bash not available")
|
||||
import os
|
||||
script = str(testdir.tmpdir.join("test_argcomplete"))
|
||||
pytest_bin = sys.argv[0]
|
||||
if "py.test" not in os.path.basename(pytest_bin):
|
||||
pytest.skip("need to be run with py.test executable, not %s" %(pytest_bin,))
|
||||
|
||||
with open(str(script), 'w') as fp:
|
||||
# redirect output from argcomplete to stdin and stderr is not trivial
|
||||
# http://stackoverflow.com/q/12589419/1307905
|
||||
# so we use bash
|
||||
fp.write('COMP_WORDBREAKS="$COMP_WORDBREAKS" $(which py.test) '
|
||||
'8>&1 9>&2')
|
||||
fp.write('COMP_WORDBREAKS="$COMP_WORDBREAKS" %s 8>&1 9>&2' % pytest_bin)
|
||||
# alternative would be exteneded Testdir.{run(),_run(),popen()} to be able
|
||||
# to handle a keyword argument env that replaces os.environ in popen or
|
||||
# extends the copy, advantage: could not forget to restore
|
||||
|
||||
@@ -677,14 +677,6 @@ def test_fdopen_kept_alive_issue124(testdir):
|
||||
"*2 passed*"
|
||||
])
|
||||
|
||||
def test_nofd_manipulation_with_capture_disabled(testdir):
|
||||
from _pytest.terminal import pytest_configure
|
||||
config = testdir.parseconfig("--capture=no")
|
||||
stdout = sys.stdout
|
||||
pytest_configure(config)
|
||||
reporter = config.pluginmanager.getplugin('terminalreporter')
|
||||
assert reporter._tw._file == stdout
|
||||
|
||||
def test_tbstyle_native_setup_error(testdir):
|
||||
p = testdir.makepyfile("""
|
||||
import pytest
|
||||
|
||||
@@ -91,3 +91,12 @@ def test_tmpdir_always_is_realpath(testdir):
|
||||
result = testdir.runpytest("-s", p, '--basetemp=%s/bt' % linktemp)
|
||||
assert not result.ret
|
||||
|
||||
def test_tmpdir_too_long_on_parametrization(testdir):
|
||||
testdir.makepyfile("""
|
||||
import pytest
|
||||
@pytest.mark.parametrize("arg", ["1"*1000])
|
||||
def test_some(arg, tmpdir):
|
||||
tmpdir.ensure("hello")
|
||||
""")
|
||||
reprec = testdir.inline_run()
|
||||
reprec.assertoutcome(passed=1)
|
||||
|
||||
Reference in New Issue
Block a user