Compare commits

..

14 Commits
2.1.2 ... 2.1.3

Author SHA1 Message Date
holger krekel
448f1c0d9c add 2.1.3 release announce to index, add floris to thanks 2011-10-18 20:58:19 +02:00
holger krekel
346da57a8a bump to version 2.1.3, add release announce, regen docs (with make regen) 2011-10-18 20:07:45 +02:00
Floris Bruynooghe
9d92b19ed1 Mention issue #77 in changelog 2011-10-17 22:17:41 +01:00
Floris Bruynooghe
e2201fe3a9 Look up the pytest_assertrepr_compare hook for each test item
Before this was only done at the time the assertion plugin was loaded.
This lead to counter-intuitive behaviour where two subdirectories with
a pytest_assertrepr_compare hook in their conftest.py would not work,
only one would ever be used.

This defers assiging the _pytest.assertion.util._reprcompare function
until the item is loaded (pytest_runtest_setup) so that it can use the
hookrelay of the test item to find the appropriate
pytest_assertrepr_compare hook for the item.

This fixes issue #77.
2011-10-16 11:51:15 +01:00
Benjamin Peterson
45b98d6e70 cast boolean thing to int to make py3.3 happy 2011-10-14 18:08:10 -04:00
Benjamin Peterson
29b4082b00 put the explanation generating code in the conditional fail body (fixes #79) 2011-10-14 16:26:13 -04:00
Ronny Pfannschmidt
6ac638ba87 add a reportchar for reporting errors, fixes #76 2011-09-29 23:44:26 +02:00
Ronny Pfannschmidt
f2512017ea correctly handle zero length cmdline arguments 2011-09-25 23:26:49 +02:00
holger krekel
3bd3ba133f fix issue75 - test failure on jython.
also experimentally enable more tests in the jython test env.
2011-09-25 07:40:43 +02:00
holger krekel
be249dcfe5 correct base version number 2011-09-24 15:19:03 +02:00
holger krekel
45afb1b7d1 fix issue67 - junitxml now contains correct durations. thanks ronny. 2011-09-24 15:15:51 +02:00
holger krekel
922a283f99 bump version 2011-09-24 14:13:24 +02:00
holger krekel
7e857e9068 Added tag 2.1.2 for changeset 5864412c6f3c 2011-09-24 14:11:54 +02:00
Ronny Pfannschmidt
ac9192e4f8 make call durations part of the test report 2011-09-23 10:53:03 +02:00
38 changed files with 323 additions and 198 deletions

View File

@@ -42,3 +42,4 @@ c777dcad166548b7499564cb49ae5c8b4b07f935 2.0.3
49f11dbff725acdcc5fe3657cbcdf9ae04e25bbc 2.0.3
363e5a5a59c803e6bc176a6f9cc4bf1a1ca2dab0 2.0.3
e5e1746a197f0398356a43fbe2eebac9690f795d 2.1.0
5864412c6f3c903384243bd315639d101d7ebc67 2.1.2

View File

@@ -1,3 +1,12 @@
Changes between 2.1.2 and 2.1.3
----------------------------------------
- fix issue79: assertion rewriting failed on some comparisons in boolops
- correctly handle zero length arguments (a la pytest '')
- fix issue67 / junitxml now contains correct test durations, thanks ronny
- fix issue75 / skipping test failure on jython
- fix issue77 / Allow assertrepr_compare hook to apply to a subset of tests
Changes between 2.1.1 and 2.1.2
----------------------------------------

View File

@@ -7,6 +7,13 @@ tags: bug 2.4 core xdist
the protocol now - setup/teardown is called at module level.
consider making calling of setup/teardown configurable
optimizations
---------------------------------------------------------------
tags: 2.4 core
- look at ihook optimization such that all lookups for
hooks relating to the same fspath are cached.
fix start/finish partial finailization problem
---------------------------------------------------------------
tags: bug core

View File

@@ -1,2 +1,2 @@
#
__version__ = '2.1.2'
__version__ = '2.1.3'

View File

@@ -43,23 +43,10 @@ def pytest_configure(config):
mode = "reinterp"
if mode != "plain":
_load_modules(mode)
def callbinrepr(op, left, right):
hook_result = config.hook.pytest_assertrepr_compare(
config=config, op=op, left=left, right=right)
for new_expl in hook_result:
if new_expl:
res = '\n~'.join(new_expl)
if mode == "rewrite":
# The result will be fed back a python % formatting
# operation, which will fail if there are extraneous
# '%'s in the string. Escape them here.
res = res.replace("%", "%%")
return res
m = monkeypatch()
config._cleanup.append(m.undo)
m.setattr(py.builtin.builtins, 'AssertionError',
reinterpret.AssertionError)
m.setattr(util, '_reprcompare', callbinrepr)
hook = None
if mode == "rewrite":
hook = rewrite.AssertionRewritingHook()
@@ -82,6 +69,24 @@ def pytest_collection(session):
if hook is not None:
hook.set_session(session)
def pytest_runtest_setup(item):
def callbinrepr(op, left, right):
hook_result = item.ihook.pytest_assertrepr_compare(
config=item.config, op=op, left=left, right=right)
for new_expl in hook_result:
if new_expl:
res = '\n~'.join(new_expl)
if item.config.getvalue("assertmode") == "rewrite":
# The result will be fed back a python % formatting
# operation, which will fail if there are extraneous
# '%'s in the string. Escape them here.
res = res.replace("%", "%%")
return res
util._reprcompare = callbinrepr
def pytest_runtest_teardown(item):
util._reprcompare = None
def pytest_sessionfinish(session):
hook = session.config._assertstate.hook
if hook is not None:

View File

@@ -484,20 +484,20 @@ class AssertionRewriter(ast.NodeVisitor):
res_var = self.variable()
expl_list = self.assign(ast.List([], ast.Load()))
app = ast.Attribute(expl_list, "append", ast.Load())
is_or = isinstance(boolop.op, ast.Or)
is_or = int(isinstance(boolop.op, ast.Or))
body = save = self.statements
fail_save = self.on_failure
levels = len(boolop.values) - 1
self.push_format_context()
# Process each operand, short-circuting if needed.
for i, v in enumerate(boolop.values):
self.push_format_context()
res, expl = self.visit(v)
body.append(ast.Assign([ast.Name(res_var, ast.Store())], res))
if i:
fail_inner = []
self.on_failure.append(ast.If(cond, fail_inner, []))
self.on_failure = fail_inner
self.push_format_context()
res, expl = self.visit(v)
body.append(ast.Assign([ast.Name(res_var, ast.Store())], res))
expl_format = self.pop_format_context(ast.Str(expl))
call = ast.Call(app, [expl_format], [], None, None)
self.on_failure.append(ast.Expr(call))

View File

@@ -421,7 +421,7 @@ class Config(object):
def getcfg(args, inibasenames):
args = [x for x in args if str(x)[0] != "-"]
args = [x for x in args if not str(x).startswith("-")]
if not args:
args = [py.path.local()]
for arg in args:

View File

@@ -71,13 +71,12 @@ class LogXML(object):
self.test_logs = []
self.passed = self.skipped = 0
self.failed = self.errors = 0
self._durations = {}
def _opentestcase(self, report):
names = report.nodeid.split("::")
names[0] = names[0].replace("/", '.')
names = tuple(names)
d = {'time': self._durations.pop(report.nodeid, "0")}
d = {'time': getattr(report, 'duration', 0)}
names = [x.replace(".py", "") for x in names if x != "()"]
classnames = names[:-1]
if self.prefix:
@@ -176,13 +175,6 @@ class LogXML(object):
elif report.skipped:
self.append_skipped(report)
def pytest_runtest_call(self, item, __multicall__):
start = time.time()
try:
return __multicall__.execute()
finally:
self._durations[item.nodeid] = time.time() - start
def pytest_collectreport(self, report):
if not report.passed:
if report.failed:

View File

@@ -25,6 +25,7 @@ def pytest_configure(config):
_pytest_fullpath
except NameError:
_pytest_fullpath = os.path.abspath(pytest.__file__.rstrip("oc"))
_pytest_fullpath = _pytest_fullpath.replace("$py.class", ".py")
def pytest_funcarg___pytest(request):
return PytestArg(request)

View File

@@ -1,6 +1,6 @@
""" basic collect and runtest protocol implementations """
import py, sys
import py, sys, time
from py._code.code import TerminalRepr
def pytest_namespace():
@@ -95,12 +95,16 @@ class CallInfo:
#: context of invocation: one of "setup", "call",
#: "teardown", "memocollect"
self.when = when
self.start = time.time()
try:
self.result = func()
except KeyboardInterrupt:
raise
except:
self.excinfo = py.code.ExceptionInfo()
try:
self.result = func()
except KeyboardInterrupt:
raise
except:
self.excinfo = py.code.ExceptionInfo()
finally:
self.stop = time.time()
def __repr__(self):
if self.excinfo:
@@ -139,6 +143,7 @@ class BaseReport(object):
def pytest_runtest_makereport(item, call):
when = call.when
duration = call.stop-call.start
keywords = dict([(x,1) for x in item.keywords])
excinfo = call.excinfo
if not call.excinfo:
@@ -160,14 +165,15 @@ def pytest_runtest_makereport(item, call):
else: # exception in setup or teardown
longrepr = item._repr_failure_py(excinfo)
return TestReport(item.nodeid, item.location,
keywords, outcome, longrepr, when)
keywords, outcome, longrepr, when,
duration=duration)
class TestReport(BaseReport):
""" Basic test report object (also used for setup and teardown calls if
they fail).
"""
def __init__(self, nodeid, location,
keywords, outcome, longrepr, when, sections=()):
keywords, outcome, longrepr, when, sections=(), duration=0):
#: normalized collection node id
self.nodeid = nodeid
@@ -193,6 +199,9 @@ class TestReport(BaseReport):
#: marshallable
self.sections = list(sections)
#: time it took to run just the test
self.duration = duration
def __repr__(self):
return "<TestReport %r when=%r outcome=%r>" % (
self.nodeid, self.when, self.outcome)

View File

@@ -169,21 +169,23 @@ def pytest_terminal_summary(terminalreporter):
elif char == "X":
show_xpassed(terminalreporter, lines)
elif char in "fF":
show_failed(terminalreporter, lines)
show_simple(terminalreporter, lines, 'failed', "FAIL %s")
elif char in "sS":
show_skipped(terminalreporter, lines)
elif char == "E":
show_simple(terminalreporter, lines, 'error', "ERROR %s")
if lines:
tr._tw.sep("=", "short test summary info")
for line in lines:
tr._tw.line(line)
def show_failed(terminalreporter, lines):
def show_simple(terminalreporter, lines, stat, format):
tw = terminalreporter._tw
failed = terminalreporter.stats.get("failed")
failed = terminalreporter.stats.get(stat)
if failed:
for rep in failed:
pos = rep.nodeid
lines.append("FAIL %s" %(pos, ))
lines.append(format %(pos, ))
def show_xfailed(terminalreporter, lines):
xfailed = terminalreporter.stats.get("xfailed")

View File

@@ -15,7 +15,7 @@ def pytest_addoption(parser):
group._addoption('-r',
action="store", dest="reportchars", default=None, metavar="chars",
help="show extra test summary info as specified by chars (f)ailed, "
"(s)skipped, (x)failed, (X)passed.")
"(E)error, (s)skipped, (x)failed, (X)passed.")
group._addoption('-l', '--showlocals',
action="store_true", dest="showlocals", default=False,
help="show locals in tracebacks (disabled by default).")

View File

@@ -5,6 +5,7 @@ Release announcements
.. toctree::
:maxdepth: 2
release-2.1.3
release-2.1.2
release-2.1.1
release-2.1.0

View File

@@ -0,0 +1,32 @@
py.test 2.1.3: just some more fixes
===========================================================================
pytest-2.1.3 is a minor backward compatible maintenance release of the
popular py.test testing tool. It is commonly used for unit, functional-
and integration testing. See extensive docs with examples here:
http://pytest.org/
The release contains another fix to the perfected assertions introduced
with the 2.1 series as well as the new possibility to customize reporting
for assertion expressions on a per-directory level.
If you want to install or upgrade pytest, just type one of::
pip install -U pytest # or
easy_install -U pytest
Thanks to the bug reporters and to Ronny Pfannschmidt, Benjamin Peterson
and Floris Bruynooghe who implemented the fixes.
best,
holger krekel
Changes between 2.1.2 and 2.1.3
----------------------------------------
- fix issue79: assertion rewriting failed on some comparisons in boolops,
- correctly handle zero length arguments (a la pytest '')
- fix issue67 / junitxml now contains correct test durations
- fix issue75 / skipping test failure on jython
- fix issue77 / Allow assertrepr_compare hook to apply to a subset of tests

View File

@@ -23,7 +23,7 @@ you will see the return value of the function call::
$ py.test test_assert1.py
=========================== test session starts ============================
platform linux2 -- Python 2.7.1 -- pytest-2.1.1
platform darwin -- Python 2.7.1 -- pytest-2.1.3
collecting ... collected 1 items
test_assert1.py F
@@ -37,7 +37,7 @@ you will see the return value of the function call::
E + where 3 = f()
test_assert1.py:5: AssertionError
========================= 1 failed in 0.01 seconds =========================
========================= 1 failed in 0.03 seconds =========================
py.test has support for showing the values of the most common subexpressions
including calls, attributes, comparisons, and binary and unary
@@ -105,7 +105,7 @@ if you run this module::
$ py.test test_assert2.py
=========================== test session starts ============================
platform linux2 -- Python 2.7.1 -- pytest-2.1.1
platform darwin -- Python 2.7.1 -- pytest-2.1.3
collecting ... collected 1 items
test_assert2.py F
@@ -124,7 +124,7 @@ if you run this module::
E '5'
test_assert2.py:5: AssertionError
========================= 1 failed in 0.01 seconds =========================
========================= 1 failed in 0.02 seconds =========================
Special comparisons are done for a number of cases:
@@ -181,7 +181,7 @@ the conftest file::
E vals: 1 != 2
test_foocompare.py:8: AssertionError
1 failed in 0.01 seconds
1 failed in 0.02 seconds
.. _assert-details:
.. _`assert introspection`:

View File

@@ -25,7 +25,7 @@ You can ask for available builtin or project-custom
$ py.test --funcargs
=========================== test session starts ============================
platform linux2 -- Python 2.7.1 -- pytest-2.1.1
platform darwin -- Python 2.7.1 -- pytest-2.1.3
collected 0 items
pytestconfig
the pytest config object with access to command line opts.
@@ -72,5 +72,7 @@ You can ask for available builtin or project-custom
See http://docs.python.org/library/warnings.html for information
on warning categories.
cov
A pytest funcarg that provides access to the underlying coverage object.
============================= in 0.00 seconds =============================

View File

@@ -64,7 +64,7 @@ of the failing function and hide the other one::
$ py.test
=========================== test session starts ============================
platform linux2 -- Python 2.7.1 -- pytest-2.1.1
platform darwin -- Python 2.7.1 -- pytest-2.1.3
collecting ... collected 2 items
test_module.py .F
@@ -78,8 +78,8 @@ of the failing function and hide the other one::
test_module.py:9: AssertionError
----------------------------- Captured stdout ------------------------------
setting up <function test_func2 at 0x24fa320>
==================== 1 failed, 1 passed in 0.01 seconds ====================
setting up <function test_func2 at 0x10130ccf8>
==================== 1 failed, 1 passed in 0.03 seconds ====================
Accessing captured output from a test function
---------------------------------------------------

View File

@@ -44,9 +44,10 @@ then you can just invoke ``py.test`` without command line options::
$ py.test
=========================== test session starts ============================
platform linux2 -- Python 2.7.1 -- pytest-2.1.1
platform darwin -- Python 2.7.1 -- pytest-2.1.3
collecting ... collected 1 items
mymodule.py .
========================= 1 passed in 0.02 seconds =========================
========================= 1 passed in 0.06 seconds =========================
[?1034h

View File

@@ -49,7 +49,7 @@ You can now run the test::
$ py.test test_sample.py
=========================== test session starts ============================
platform linux2 -- Python 2.7.1 -- pytest-2.1.1
platform darwin -- Python 2.7.1 -- pytest-2.1.3
collecting ... collected 1 items
test_sample.py F
@@ -57,7 +57,7 @@ You can now run the test::
================================= FAILURES =================================
_______________________________ test_answer ________________________________
mysetup = <conftest.MySetup instance at 0x1d345f0>
mysetup = <conftest.MySetup instance at 0x1013145a8>
def test_answer(mysetup):
app = mysetup.myapp()
@@ -66,7 +66,7 @@ You can now run the test::
E assert 54 == 42
test_sample.py:4: AssertionError
========================= 1 failed in 0.01 seconds =========================
========================= 1 failed in 0.02 seconds =========================
This means that our ``mysetup`` object was successfully instantiated
and ``mysetup.app()`` returned an initialized ``MyApp`` instance.
@@ -122,14 +122,14 @@ Running it yields::
$ py.test test_ssh.py -rs
=========================== test session starts ============================
platform linux2 -- Python 2.7.1 -- pytest-2.1.1
platform darwin -- Python 2.7.1 -- pytest-2.1.3
collecting ... collected 1 items
test_ssh.py s
========================= short test summary info ==========================
SKIP [1] /tmp/doc-exec-296/conftest.py:22: specify ssh host with --ssh
SKIP [1] /Users/hpk/tmp/doc-exec-167/conftest.py:22: specify ssh host with --ssh
======================== 1 skipped in 0.01 seconds =========================
======================== 1 skipped in 0.02 seconds =========================
If you specify a command line option like ``py.test --ssh=python.org`` the test will execute as expected.

View File

@@ -27,7 +27,7 @@ now execute the test specification::
nonpython $ py.test test_simple.yml
=========================== test session starts ============================
platform linux2 -- Python 2.7.1 -- pytest-2.1.1
platform darwin -- Python 2.7.1 -- pytest-2.1.3
collecting ... 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.07 seconds ====================
==================== 1 failed, 1 passed in 0.09 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 @@ reporting in ``verbose`` mode::
nonpython $ py.test -v
=========================== test session starts ============================
platform linux2 -- Python 2.7.1 -- pytest-2.1.1 -- /home/hpk/venv/0/bin/python
platform darwin -- Python 2.7.1 -- pytest-2.1.3 -- /Users/hpk/venv/0/bin/python
collecting ... collected 2 items
test_simple.yml:1: usecase: ok PASSED
@@ -67,17 +67,17 @@ reporting in ``verbose`` mode::
usecase execution failed
spec failed: 'some': 'other'
no further details known at this point.
==================== 1 failed, 1 passed in 0.06 seconds ====================
==================== 1 failed, 1 passed in 0.09 seconds ====================
While developing your custom test collection and execution it's also
interesting to just look at the collection tree::
nonpython $ py.test --collectonly
=========================== test session starts ============================
platform linux2 -- Python 2.7.1 -- pytest-2.1.1
platform darwin -- Python 2.7.1 -- pytest-2.1.3
collecting ... collected 2 items
<YamlFile 'test_simple.yml'>
<YamlItem 'ok'>
<YamlItem 'hello'>
============================= in 0.06 seconds =============================
============================= in 0.08 seconds =============================

View File

@@ -44,7 +44,7 @@ This means that we only run 2 tests if we do not pass ``--all``::
$ py.test -q test_compute.py
collecting ... collected 2 items
..
2 passed in 0.01 seconds
2 passed in 0.02 seconds
We run only two computations, so we see two dots.
let's run the full monty::
@@ -62,7 +62,7 @@ let's run the full monty::
E assert 4 < 4
test_compute.py:3: AssertionError
1 failed, 4 passed in 0.01 seconds
1 failed, 4 passed in 0.03 seconds
As expected when running the full range of ``param1`` values
we'll get an error on the last one.
@@ -114,13 +114,13 @@ Let's first see how it looks like at collection time::
$ py.test test_backends.py --collectonly
=========================== test session starts ============================
platform linux2 -- Python 2.7.1 -- pytest-2.1.1
platform darwin -- Python 2.7.1 -- pytest-2.1.3
collecting ... collected 2 items
<Module 'test_backends.py'>
<Function 'test_db_initialized[0]'>
<Function 'test_db_initialized[1]'>
============================= in 0.00 seconds =============================
============================= in 0.01 seconds =============================
And then when we run the test::
@@ -130,7 +130,7 @@ And then when we run the test::
================================= FAILURES =================================
__________________________ test_db_initialized[1] __________________________
db = <conftest.DB2 instance at 0x17829e0>
db = <conftest.DB2 instance at 0x101316b90>
def test_db_initialized(db):
# a dummy test
@@ -139,7 +139,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
1 failed, 1 passed in 0.02 seconds
Now you see that one invocation of the test passes and another fails,
as it to be expected.
@@ -184,7 +184,7 @@ the respective settings::
================================= FAILURES =================================
__________________________ test_db_initialized[1] __________________________
db = <conftest.DB2 instance at 0x2acf4d0>
db = <conftest.DB2 instance at 0x10131c488>
def test_db_initialized(db):
# a dummy test
@@ -195,7 +195,7 @@ the respective settings::
test_backends.py:6: Failed
_________________________ TestClass.test_equals[0] _________________________
self = <test_parametrize.TestClass instance at 0x2ad2830>, a = 1, b = 2
self = <test_parametrize.TestClass instance at 0x101322170>, a = 1, b = 2
def test_equals(self, a, b):
> assert a == b
@@ -204,14 +204,14 @@ the respective settings::
test_parametrize.py:17: AssertionError
______________________ TestClass.test_zerodivision[1] ______________________
self = <test_parametrize.TestClass instance at 0x2ad8830>, a = 3, b = 2
self = <test_parametrize.TestClass instance at 0x1013228c0>, a = 3, b = 2
def test_zerodivision(self, a, b):
> pytest.raises(ZeroDivisionError, "a/b")
E Failed: DID NOT RAISE
test_parametrize.py:20: Failed
3 failed, 3 passed in 0.02 seconds
3 failed, 3 passed in 0.05 seconds
Parametrizing test methods through a decorator
--------------------------------------------------------------
@@ -252,7 +252,7 @@ Running it gives similar results as before::
================================= FAILURES =================================
_________________________ TestClass.test_equals[0] _________________________
self = <test_parametrize2.TestClass instance at 0x1ef2170>, a = 1, b = 2
self = <test_parametrize2.TestClass instance at 0x10130ac20>, a = 1, b = 2
@params([dict(a=1, b=2), dict(a=3, b=3), ])
def test_equals(self, a, b):
@@ -262,7 +262,7 @@ Running it gives similar results as before::
test_parametrize2.py:19: AssertionError
______________________ TestClass.test_zerodivision[1] ______________________
self = <test_parametrize2.TestClass instance at 0x20e4248>, a = 3, b = 2
self = <test_parametrize2.TestClass instance at 0x10131c878>, a = 3, b = 2
@params([dict(a=1, b=0), dict(a=3, b=2)])
def test_zerodivision(self, a, b):
@@ -270,7 +270,7 @@ Running it gives similar results as before::
E Failed: DID NOT RAISE
test_parametrize2.py:23: Failed
2 failed, 2 passed in 0.02 seconds
2 failed, 2 passed in 0.04 seconds
Checking serialization between Python interpreters
--------------------------------------------------------------
@@ -290,5 +290,5 @@ Running it (with Python-2.4 through to Python2.7 installed)::
. $ py.test -q multipython.py
collecting ... collected 75 items
....s....s....s....ssssss....s....s....s....ssssss....s....s....s....ssssss
48 passed, 27 skipped in 2.48 seconds
ssssss...ss...ss...ssssssssssss...ss...ss...ssssssssssss...ss...ss...ssssss
27 passed, 48 skipped in 3.04 seconds

View File

@@ -43,7 +43,7 @@ then the test collection looks like this::
$ py.test --collectonly
=========================== test session starts ============================
platform linux2 -- Python 2.7.1 -- pytest-2.1.1
platform darwin -- Python 2.7.1 -- pytest-2.1.3
collecting ... collected 2 items
<Module 'check_myapp.py'>
<Class 'CheckMyApp'>
@@ -51,7 +51,7 @@ then the test collection looks like this::
<Function 'check_simple'>
<Function 'check_complex'>
============================= in 0.01 seconds =============================
============================= in 0.02 seconds =============================
Interpreting cmdline arguments as Python packages
-----------------------------------------------------
@@ -82,7 +82,7 @@ You can always peek at the collection tree without running tests like this::
. $ py.test --collectonly pythoncollection.py
=========================== test session starts ============================
platform linux2 -- Python 2.7.1 -- pytest-2.1.1
platform darwin -- Python 2.7.1 -- pytest-2.1.3
collecting ... collected 3 items
<Module 'pythoncollection.py'>
<Function 'test_function'>

View File

@@ -13,7 +13,7 @@ get on the terminal - we are working on that):
assertion $ py.test failure_demo.py
=========================== test session starts ============================
platform linux2 -- Python 2.7.1 -- pytest-2.1.1
platform darwin -- Python 2.7.1 -- pytest-2.1.3
collecting ... 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 0x1b79310>
self = <failure_demo.TestFailing object at 0x10134bc50>
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 0x1c57488>()
E + and 43 = <function g at 0x1c57500>()
E + where 42 = <function f at 0x101322320>()
E + and 43 = <function g at 0x101322398>()
failure_demo.py:28: AssertionError
____________________ TestFailing.test_simple_multiline _____________________
self = <failure_demo.TestFailing object at 0x1b79850>
self = <failure_demo.TestFailing object at 0x10134b150>
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 0x1b79290>
self = <failure_demo.TestFailing object at 0x10134b710>
def test_not(self):
def f():
return 42
> assert not f()
E assert not 42
E + where 42 = <function f at 0x1c57500>()
E + where 42 = <function f at 0x101322398>()
failure_demo.py:38: AssertionError
_________________ TestSpecialisedExplanations.test_eq_text _________________
self = <failure_demo.TestSpecialisedExplanations object at 0x1b79f90>
self = <failure_demo.TestSpecialisedExplanations object at 0x10134be10>
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 0x1b7af50>
self = <failure_demo.TestSpecialisedExplanations object at 0x101347110>
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 0x1b7af90>
self = <failure_demo.TestSpecialisedExplanations object at 0x101343d50>
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 0x1b79d10>
self = <failure_demo.TestSpecialisedExplanations object at 0x10134b210>
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 0x1b7a490>
self = <failure_demo.TestSpecialisedExplanations object at 0x101343d90>
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 0x1b7ac90>
self = <failure_demo.TestSpecialisedExplanations object at 0x101343dd0>
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 0x1b79cd0>
self = <failure_demo.TestSpecialisedExplanations object at 0x101343b90>
def test_eq_list_long(self):
a = [0]*100 + [1] + [3]*100
@@ -178,7 +178,7 @@ get on the terminal - we are working on that):
failure_demo.py:66: AssertionError
_________________ TestSpecialisedExplanations.test_eq_dict _________________
self = <failure_demo.TestSpecialisedExplanations object at 0x1b75e90>
self = <failure_demo.TestSpecialisedExplanations object at 0x101343210>
def test_eq_dict(self):
> assert {'a': 0, 'b': 1} == {'a': 0, 'b': 2}
@@ -191,7 +191,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 0x1b75c10>
self = <failure_demo.TestSpecialisedExplanations object at 0x101343990>
def test_eq_set(self):
> assert set([0, 10, 11, 12]) == set([0, 20, 21])
@@ -207,7 +207,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 0x1b79590>
self = <failure_demo.TestSpecialisedExplanations object at 0x101343590>
def test_eq_longer_list(self):
> assert [1,2] == [1,2,3]
@@ -217,7 +217,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 0x1b7a8d0>
self = <failure_demo.TestSpecialisedExplanations object at 0x101343e50>
def test_in_list(self):
> assert 1 in [0, 2, 3, 4, 5]
@@ -226,7 +226,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 0x1b75410>
self = <failure_demo.TestSpecialisedExplanations object at 0x10133bb10>
def test_not_in_text_multiline(self):
text = 'some multiline\ntext\nwhich\nincludes foo\nand a\ntail'
@@ -244,7 +244,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 0x1b75c90>
self = <failure_demo.TestSpecialisedExplanations object at 0x10133b990>
def test_not_in_text_single(self):
text = 'single foo line'
@@ -257,7 +257,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 0x1b75dd0>
self = <failure_demo.TestSpecialisedExplanations object at 0x10133bbd0>
def test_not_in_text_single_long(self):
text = 'head ' * 50 + 'foo ' + 'tail ' * 20
@@ -270,7 +270,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 0x1b751d0>
self = <failure_demo.TestSpecialisedExplanations object at 0x101343510>
def test_not_in_text_single_long_term(self):
text = 'head ' * 50 + 'f'*70 + 'tail ' * 20
@@ -289,7 +289,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 0x1b75310>.b
E + where 1 = <failure_demo.Foo object at 0x10133b390>.b
failure_demo.py:101: AssertionError
_________________________ test_attribute_instance __________________________
@@ -299,8 +299,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 0x1b75bd0>.b
E + where <failure_demo.Foo object at 0x1b75bd0> = <class 'failure_demo.Foo'>()
E + where 1 = <failure_demo.Foo object at 0x10133b250>.b
E + where <failure_demo.Foo object at 0x10133b250> = <class 'failure_demo.Foo'>()
failure_demo.py:107: AssertionError
__________________________ test_attribute_failure __________________________
@@ -316,7 +316,7 @@ get on the terminal - we are working on that):
failure_demo.py:116:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <failure_demo.Foo object at 0x1c6ee50>
self = <failure_demo.Foo object at 0x10133bd50>
def _get_b(self):
> raise Exception('Failed to get attrib')
@@ -332,15 +332,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 0x1b7a750>.b
E + where <failure_demo.Foo object at 0x1b7a750> = <class 'failure_demo.Foo'>()
E + and 2 = <failure_demo.Bar object at 0x1c6e310>.b
E + where <failure_demo.Bar object at 0x1c6e310> = <class 'failure_demo.Bar'>()
E + where 1 = <failure_demo.Foo object at 0x10133bb50>.b
E + where <failure_demo.Foo object at 0x10133bb50> = <class 'failure_demo.Foo'>()
E + and 2 = <failure_demo.Bar object at 0x10133b1d0>.b
E + where <failure_demo.Bar object at 0x10133b1d0> = <class 'failure_demo.Bar'>()
failure_demo.py:124: AssertionError
__________________________ TestRaises.test_raises __________________________
self = <failure_demo.TestRaises instance at 0x1b92878>
self = <failure_demo.TestRaises instance at 0x1013697e8>
def test_raises(self):
s = 'qwe'
@@ -352,10 +352,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/_pytest/python.py:833>:1: ValueError
<0-codegen /Users/hpk/p/pytest/_pytest/python.py:833>:1: ValueError
______________________ TestRaises.test_raises_doesnt _______________________
self = <failure_demo.TestRaises instance at 0x1c63248>
self = <failure_demo.TestRaises instance at 0x101372a70>
def test_raises_doesnt(self):
> raises(IOError, "int('3')")
@@ -364,7 +364,7 @@ get on the terminal - we are working on that):
failure_demo.py:136: Failed
__________________________ TestRaises.test_raise ___________________________
self = <failure_demo.TestRaises instance at 0x1b97560>
self = <failure_demo.TestRaises instance at 0x10136a908>
def test_raise(self):
> raise ValueError("demo error")
@@ -373,7 +373,7 @@ get on the terminal - we are working on that):
failure_demo.py:139: ValueError
________________________ TestRaises.test_tupleerror ________________________
self = <failure_demo.TestRaises instance at 0x1b8e0e0>
self = <failure_demo.TestRaises instance at 0x10136c710>
def test_tupleerror(self):
> a,b = [1]
@@ -382,7 +382,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 0x1b8edd0>
self = <failure_demo.TestRaises instance at 0x101365488>
def test_reinterpret_fails_with_print_for_the_fun_of_it(self):
l = [1,2,3]
@@ -395,7 +395,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 0x1b88bd8>
self = <failure_demo.TestRaises instance at 0x101367248>
def test_some_error(self):
> if namenotexi:
@@ -420,10 +420,10 @@ get on the terminal - we are working on that):
> assert 1 == 0
E assert 1 == 0
<2-codegen 'abc-123' /home/hpk/p/pytest/doc/example/assertion/failure_demo.py:162>:2: AssertionError
<2-codegen 'abc-123' /Users/hpk/p/pytest/doc/example/assertion/failure_demo.py:162>:2: AssertionError
____________________ TestMoreErrors.test_complex_error _____________________
self = <failure_demo.TestMoreErrors instance at 0x1b8e248>
self = <failure_demo.TestMoreErrors instance at 0x101380f38>
def test_complex_error(self):
def f():
@@ -452,7 +452,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 0x1b97050>
self = <failure_demo.TestMoreErrors instance at 0x101367f80>
def test_z1_unpack_error(self):
l = []
@@ -462,7 +462,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 0x1b8bd88>
self = <failure_demo.TestMoreErrors instance at 0x101363dd0>
def test_z2_type_error(self):
l = 3
@@ -472,19 +472,19 @@ get on the terminal - we are working on that):
failure_demo.py:183: TypeError
______________________ TestMoreErrors.test_startswith ______________________
self = <failure_demo.TestMoreErrors instance at 0x1b8ab90>
self = <failure_demo.TestMoreErrors instance at 0x101364bd8>
def test_startswith(self):
s = "123"
g = "456"
> assert s.startswith(g)
E assert <built-in method startswith of str object at 0x1b68508>('456')
E + where <built-in method startswith of str object at 0x1b68508> = '123'.startswith
E assert <built-in method startswith of str object at 0x1013524e0>('456')
E + where <built-in method startswith of str object at 0x1013524e0> = '123'.startswith
failure_demo.py:188: AssertionError
__________________ TestMoreErrors.test_startswith_nested ___________________
self = <failure_demo.TestMoreErrors instance at 0x1b878c0>
self = <failure_demo.TestMoreErrors instance at 0x101363fc8>
def test_startswith_nested(self):
def f():
@@ -492,15 +492,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 0x1b68508>('456')
E + where <built-in method startswith of str object at 0x1b68508> = '123'.startswith
E + where '123' = <function f at 0x1b96848>()
E + and '456' = <function g at 0x1b968c0>()
E assert <built-in method startswith of str object at 0x1013524e0>('456')
E + where <built-in method startswith of str object at 0x1013524e0> = '123'.startswith
E + where '123' = <function f at 0x10132c500>()
E + and '456' = <function g at 0x10132c8c0>()
failure_demo.py:195: AssertionError
_____________________ TestMoreErrors.test_global_func ______________________
self = <failure_demo.TestMoreErrors instance at 0x1b8a320>
self = <failure_demo.TestMoreErrors instance at 0x1013696c8>
def test_global_func(self):
> assert isinstance(globf(42), float)
@@ -510,18 +510,18 @@ get on the terminal - we are working on that):
failure_demo.py:198: AssertionError
_______________________ TestMoreErrors.test_instance _______________________
self = <failure_demo.TestMoreErrors instance at 0x1b8b0e0>
self = <failure_demo.TestMoreErrors instance at 0x1013671b8>
def test_instance(self):
self.x = 6*7
> assert self.x != 42
E assert 42 != 42
E + where 42 = <failure_demo.TestMoreErrors instance at 0x1b8b0e0>.x
E + where 42 = <failure_demo.TestMoreErrors instance at 0x1013671b8>.x
failure_demo.py:202: AssertionError
_______________________ TestMoreErrors.test_compare ________________________
self = <failure_demo.TestMoreErrors instance at 0x1b97998>
self = <failure_demo.TestMoreErrors instance at 0x101366560>
def test_compare(self):
> assert globf(10) < 5
@@ -531,7 +531,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 0x1b807e8>
self = <failure_demo.TestMoreErrors instance at 0x1013613b0>
def test_try_finally(self):
x = 1
@@ -540,4 +540,4 @@ get on the terminal - we are working on that):
E assert 1 == 0
failure_demo.py:210: AssertionError
======================== 39 failed in 0.20 seconds =========================
======================== 39 failed in 0.39 seconds =========================

View File

@@ -53,7 +53,7 @@ Let's run this without supplying our new command line option::
test_sample.py:6: AssertionError
----------------------------- Captured stdout ------------------------------
first
1 failed in 0.01 seconds
1 failed in 0.02 seconds
And now with supplying a command line option::
@@ -76,7 +76,7 @@ And now with supplying a command line option::
test_sample.py:6: AssertionError
----------------------------- Captured stdout ------------------------------
second
1 failed in 0.01 seconds
1 failed in 0.02 seconds
Ok, this completes the basic pattern. However, one often rather
wants to process command line options outside of the test and
@@ -109,13 +109,13 @@ directory with the above conftest.py::
$ py.test
=========================== test session starts ============================
platform linux2 -- Python 2.7.1 -- pytest-2.1.1
gw0 I / gw1 I
gw0 [0] / gw1 [0]
platform darwin -- Python 2.7.1 -- pytest-2.1.3
gw0 I
gw0 [0]
scheduling tests via LoadScheduling
============================= in 0.26 seconds =============================
============================= in 0.48 seconds =============================
.. _`excontrolskip`:
@@ -156,25 +156,25 @@ 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.1 -- pytest-2.1.1
platform darwin -- Python 2.7.1 -- pytest-2.1.3
collecting ... collected 2 items
test_module.py .s
========================= short test summary info ==========================
SKIP [1] /tmp/doc-exec-301/conftest.py:9: need --runslow option to run
SKIP [1] /Users/hpk/tmp/doc-exec-172/conftest.py:9: need --runslow option to run
=================== 1 passed, 1 skipped in 0.01 seconds ====================
=================== 1 passed, 1 skipped in 0.02 seconds ====================
Or run it including the ``slow`` marked test::
$ py.test --runslow
=========================== test session starts ============================
platform linux2 -- Python 2.7.1 -- pytest-2.1.1
platform darwin -- Python 2.7.1 -- pytest-2.1.3
collecting ... collected 2 items
test_module.py ..
========================= 2 passed in 0.01 seconds =========================
========================= 2 passed in 0.02 seconds =========================
Writing well integrated assertion helpers
--------------------------------------------------
@@ -213,7 +213,7 @@ Let's run our little function::
E Failed: not configured: 42
test_checkconfig.py:8: Failed
1 failed in 0.01 seconds
1 failed in 0.02 seconds
Detect if running from within a py.test run
--------------------------------------------------------------
@@ -261,7 +261,7 @@ which will add the string to the test header accordingly::
$ py.test
=========================== test session starts ============================
platform linux2 -- Python 2.7.1 -- pytest-2.1.1
platform darwin -- Python 2.7.1 -- pytest-2.1.3
project deps: mylib-1.1
collecting ... collected 0 items
@@ -284,7 +284,7 @@ which will add info only when run with "--v"::
$ py.test -v
=========================== test session starts ============================
platform linux2 -- Python 2.7.1 -- pytest-2.1.1 -- /home/hpk/venv/0/bin/python
platform darwin -- Python 2.7.1 -- pytest-2.1.3 -- /Users/hpk/venv/0/bin/python
info1: did you know that ...
did you?
collecting ... collected 0 items
@@ -295,7 +295,7 @@ and nothing when run plainly::
$ py.test
=========================== test session starts ============================
platform linux2 -- Python 2.7.1 -- pytest-2.1.1
platform darwin -- Python 2.7.1 -- pytest-2.1.3
collecting ... collected 0 items
============================= in 0.00 seconds =============================

View File

@@ -61,7 +61,7 @@ Running the test looks like this::
$ py.test test_simplefactory.py
=========================== test session starts ============================
platform linux2 -- Python 2.7.1 -- pytest-2.1.1
platform darwin -- Python 2.7.1 -- pytest-2.1.3
collecting ... collected 1 items
test_simplefactory.py F
@@ -76,7 +76,7 @@ Running the test looks like this::
E assert 42 == 17
test_simplefactory.py:5: AssertionError
========================= 1 failed in 0.01 seconds =========================
========================= 1 failed in 0.02 seconds =========================
This means that indeed the test function was called with a ``myfuncarg``
argument value of ``42`` and the assert fails. Here is how py.test
@@ -167,7 +167,7 @@ Running this::
$ py.test test_example.py
=========================== test session starts ============================
platform linux2 -- Python 2.7.1 -- pytest-2.1.1
platform darwin -- Python 2.7.1 -- pytest-2.1.3
collecting ... collected 10 items
test_example.py .........F
@@ -182,7 +182,7 @@ Running this::
E assert 9 < 9
test_example.py:7: AssertionError
==================== 1 failed, 9 passed in 0.02 seconds ====================
==================== 1 failed, 9 passed in 0.04 seconds ====================
Note that the ``pytest_generate_tests(metafunc)`` hook is called during
the test collection phase which is separate from the actual test running.
@@ -190,7 +190,7 @@ Let's just look at what is collected::
$ py.test --collectonly test_example.py
=========================== test session starts ============================
platform linux2 -- Python 2.7.1 -- pytest-2.1.1
platform darwin -- Python 2.7.1 -- pytest-2.1.3
collecting ... collected 10 items
<Module 'test_example.py'>
<Function 'test_func[0]'>
@@ -204,19 +204,37 @@ Let's just look at what is collected::
<Function 'test_func[8]'>
<Function 'test_func[9]'>
============================= in 0.00 seconds =============================
============================= in 0.01 seconds =============================
If you want to select only the run with the value ``7`` you could do::
$ py.test -v -k 7 test_example.py # or -k test_func[7]
=========================== test session starts ============================
platform linux2 -- Python 2.7.1 -- pytest-2.1.1 -- /home/hpk/venv/0/bin/python
platform darwin -- Python 2.7.1 -- pytest-2.1.3 -- /Users/hpk/venv/0/bin/python
collecting ... collected 10 items
test_example.py:6: test_func[0] PASSED
test_example.py:6: test_func[1] PASSED
test_example.py:6: test_func[2] PASSED
test_example.py:6: test_func[3] PASSED
test_example.py:6: test_func[4] PASSED
test_example.py:6: test_func[5] PASSED
test_example.py:6: test_func[6] PASSED
test_example.py:6: test_func[7] PASSED
test_example.py:6: test_func[8] PASSED
test_example.py:6: test_func[9] FAILED
======================== 9 tests deselected by '7' =========================
================== 1 passed, 9 deselected in 0.01 seconds ==================
================================= FAILURES =================================
_______________________________ test_func[9] _______________________________
numiter = 9
def test_func(numiter):
> assert numiter < 9
E assert 9 < 9
test_example.py:7: AssertionError
==================== 1 failed, 9 passed in 0.05 seconds ====================
You might want to look at :ref:`more parametrization examples <paramexamples>`.

View File

@@ -22,9 +22,10 @@ Installation options::
To check your installation has installed the correct version::
$ py.test --version
This is py.test version 2.1.1, imported from /home/hpk/p/pytest/pytest.py
This is py.test version 2.1.3, imported from /Users/hpk/p/pytest/pytest.pyc
setuptools registered plugins:
pytest-xdist-1.6 at /home/hpk/p/pytest-xdist/xdist/plugin.pyc
pytest-cov-1.4 at /Users/hpk/venv/0/lib/python2.7/site-packages/pytest_cov.pyc
pytest-xdist-1.6 at /Users/hpk/venv/0/lib/python2.7/site-packages/xdist/plugin.pyc
If you get an error checkout :ref:`installation issues`.
@@ -46,7 +47,7 @@ That's it. You can execute the test function now::
$ py.test
=========================== test session starts ============================
platform linux2 -- Python 2.7.1 -- pytest-2.1.1
platform darwin -- Python 2.7.1 -- pytest-2.1.3
collecting ... collected 1 items
test_sample.py F
@@ -60,7 +61,7 @@ That's it. You can execute the test function now::
E + where 4 = func(3)
test_sample.py:5: AssertionError
========================= 1 failed in 0.01 seconds =========================
========================= 1 failed in 0.02 seconds =========================
py.test found the ``test_answer`` function by following :ref:`standard test discovery rules <test discovery>`, basically detecting the ``test_`` prefixes. We got a failure report because our little ``func(3)`` call did not return ``5``.
@@ -95,7 +96,7 @@ Running it with, this time in "quiet" reporting mode::
$ py.test -q test_sysexit.py
collecting ... collected 1 items
.
1 passed in 0.00 seconds
1 passed in 0.01 seconds
.. todo:: For further ways to assert exceptions see the `raises`
@@ -126,7 +127,7 @@ run the module by passing its filename::
================================= FAILURES =================================
____________________________ TestClass.test_two ____________________________
self = <test_class.TestClass instance at 0x2037908>
self = <test_class.TestClass instance at 0x1013167a0>
def test_two(self):
x = "hello"
@@ -134,7 +135,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
1 failed, 1 passed in 0.03 seconds
The first test passed, the second failed. Again we can easily see
the intermediate values used in the assertion, helping us to
@@ -163,7 +164,7 @@ before performing the test function call. Let's just run it::
================================= FAILURES =================================
_____________________________ test_needsfiles ______________________________
tmpdir = local('/tmp/pytest-60/test_needsfiles0')
tmpdir = local('/Users/hpk/tmp/pytest-93/test_needsfiles0')
def test_needsfiles(tmpdir):
print tmpdir
@@ -172,8 +173,8 @@ before performing the test function call. Let's just run it::
test_tmpdir.py:3: AssertionError
----------------------------- Captured stdout ------------------------------
/tmp/pytest-60/test_needsfiles0
1 failed in 0.02 seconds
/Users/hpk/tmp/pytest-93/test_needsfiles0
1 failed in 0.04 seconds
Before the test runs, a unique-per-test-invocation temporary directory
was created. More info at :ref:`tmpdir handling`.

View File

@@ -88,35 +88,35 @@ You can use the ``-k`` command line option to select tests::
$ py.test -k webtest # running with the above defined examples yields
=========================== test session starts ============================
platform linux2 -- Python 2.7.1 -- pytest-2.1.1
platform darwin -- Python 2.7.1 -- pytest-2.1.3
collecting ... collected 4 items
test_mark.py ..
test_mark_classlevel.py ..
========================= 4 passed in 0.01 seconds =========================
========================= 4 passed in 0.03 seconds =========================
And you can also run all tests except the ones that match the keyword::
$ py.test -k-webtest
=========================== test session starts ============================
platform linux2 -- Python 2.7.1 -- pytest-2.1.1
platform darwin -- Python 2.7.1 -- pytest-2.1.3
collecting ... collected 4 items
===================== 4 tests deselected by '-webtest' =====================
======================= 4 deselected in 0.01 seconds =======================
======================= 4 deselected in 0.02 seconds =======================
Or to only select the class::
$ py.test -kTestClass
=========================== test session starts ============================
platform linux2 -- Python 2.7.1 -- pytest-2.1.1
platform darwin -- Python 2.7.1 -- pytest-2.1.3
collecting ... collected 4 items
test_mark_classlevel.py ..
==================== 2 tests deselected by 'TestClass' =====================
================== 2 passed, 2 deselected in 0.01 seconds ==================
================== 2 passed, 2 deselected in 0.02 seconds ==================
API reference for mark related objects
------------------------------------------------

View File

@@ -39,7 +39,7 @@ will be undone.
.. background check:
$ py.test
=========================== test session starts ============================
platform linux2 -- Python 2.7.1 -- pytest-2.1.1
platform darwin -- Python 2.7.1 -- pytest-2.1.3
collecting ... collected 0 items
============================= in 0.00 seconds =============================

View File

@@ -46,7 +46,7 @@ Some organisations using py.test
* `Some Mozilla QA people <http://www.theautomatedtester.co.uk/blog/2011/pytest_and_xdist_plugin.html>`_ use pytest to distribute their Selenium tests
* `Tandberg <http://www.tandberg.com/>`_
* `Shootq <http://web.shootq.com/>`_
* `Stups department of Heinrich Heine University Düsseldorf <http://www.stups.uni-duesseldorf.de/projects.php>`_
* `Stups department of Heinrich Heine University Duesseldorf <http://www.stups.uni-duesseldorf.de/projects.php>`_
* `cellzome <http://www.cellzome.com/>`_
* `Open End, Gothenborg <http://www.openend.se>`_
* `Laboraratory of Bioinformatics, Warsaw <http://genesilico.pl/>`_

View File

@@ -130,7 +130,7 @@ 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.1 -- pytest-2.1.1
platform darwin -- Python 2.7.1 -- pytest-2.1.3
collecting ... collected 6 items
xfail_demo.py xxxxxx
@@ -147,7 +147,7 @@ Running it with the report-on-xfail option gives this output::
XFAIL xfail_demo.py::test_hello6
reason: reason
======================== 6 xfailed in 0.03 seconds =========================
======================== 6 xfailed in 0.11 seconds =========================
.. _`evaluation of skipif/xfail conditions`:

View File

@@ -28,7 +28,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.1 -- pytest-2.1.1
platform darwin -- Python 2.7.1 -- pytest-2.1.3
collecting ... collected 1 items
test_tmpdir.py F
@@ -36,7 +36,7 @@ Running this would result in a passed test except for the last
================================= FAILURES =================================
_____________________________ test_create_file _____________________________
tmpdir = local('/tmp/pytest-61/test_create_file0')
tmpdir = local('/Users/hpk/tmp/pytest-94/test_create_file0')
def test_create_file(tmpdir):
p = tmpdir.mkdir("sub").join("hello.txt")
@@ -47,7 +47,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.03 seconds =========================
========================= 1 failed in 0.05 seconds =========================
.. _`base temporary directory`:

View File

@@ -24,7 +24,7 @@ Running it yields::
$ py.test test_unittest.py
=========================== test session starts ============================
platform linux2 -- Python 2.7.1 -- pytest-2.1.1
platform darwin -- Python 2.7.1 -- pytest-2.1.3
collecting ... collected 1 items
test_unittest.py F
@@ -42,7 +42,7 @@ Running it yields::
test_unittest.py:8: AssertionError
----------------------------- Captured stdout ------------------------------
hello
========================= 1 failed in 0.02 seconds =========================
========================= 1 failed in 0.04 seconds =========================
.. _`unittest.py style`: http://docs.python.org/library/unittest.html

View File

@@ -24,7 +24,7 @@ def main():
name='pytest',
description='py.test: simple powerful testing with Python',
long_description = long_description,
version='2.1.2',
version='2.1.3',
url='http://pytest.org',
license='MIT license',
platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'],

View File

@@ -40,15 +40,6 @@ class TestBinReprIntegration:
assert hook.left == [0, 1]
assert hook.right == [0, 2]
def test_configure_unconfigure(self, testdir, hook):
assert hook == util._reprcompare
config = testdir.parseconfig()
plugin.pytest_configure(config)
assert hook != util._reprcompare
from _pytest.config import pytest_unconfigure
pytest_unconfigure(config)
assert hook == util._reprcompare
def callequal(left, right):
return plugin.pytest_assertrepr_compare('==', left, right)
@@ -167,6 +158,28 @@ def test_sequence_comparison_uses_repr(testdir):
"*E*'y'*",
])
@needsnewassert
def test_assertrepr_loaded_per_dir(testdir):
testdir.makepyfile(test_base=['def test_base(): assert 1 == 2'])
a = testdir.mkdir('a')
a_test = a.join('test_a.py')
a_test.write('def test_a(): assert 1 == 2')
a_conftest = a.join('conftest.py')
a_conftest.write('def pytest_assertrepr_compare(): return ["summary a"]')
b = testdir.mkdir('b')
b_test = b.join('test_b.py')
b_test.write('def test_b(): assert 1 == 2')
b_conftest = b.join('conftest.py')
b_conftest.write('def pytest_assertrepr_compare(): return ["summary b"]')
result = testdir.runpytest()
result.stdout.fnmatch_lines([
'*def test_base():*',
'*E*assert 1 == 2*',
'*def test_a():*',
'*E*assert summary a*',
'*def test_b():*',
'*E*assert summary b*'])
def test_assertion_options(testdir):
testdir.makepyfile("""

View File

@@ -144,6 +144,14 @@ class TestAssertionRewrite:
def f():
assert False or x()
assert getmsg(f, {"x" : x}) == "assert (False or x())"
def f():
assert 1 in {} and 2 in {}
assert getmsg(f) == "assert (1 in {})"
def f():
x = 1
y = 2
assert x in {1 : None} and y in {}
assert getmsg(f) == "assert (1 in {1: None} and 2 in {})"
def f():
f = True
g = False

View File

@@ -16,6 +16,9 @@ class TestParseIni:
config._preparse([sub])
assert config.inicfg['name'] == 'value'
def test_getcfg_empty_path(self, tmpdir):
cfg = getcfg([''], ['setup.cfg']) #happens on py.test ""
def test_append_parse_args(self, tmpdir):
tmpdir.join("setup.cfg").write(py.code.Source("""
[pytest]

View File

@@ -1,4 +1,5 @@
import pytest
import sys
from _pytest.skipping import MarkEvaluator, folded_skips
from _pytest.skipping import pytest_runtest_setup
@@ -471,6 +472,21 @@ def test_reportchars(testdir):
"SKIP*four*",
])
def test_reportchars_error(testdir):
testdir.makepyfile(
conftest="""
def pytest_runtest_teardown():
assert 0
""",
test_simple="""
def test_foo():
pass
""")
result = testdir.runpytest('-rE')
result.stdout.fnmatch_lines([
'ERROR*test_foo*',
])
@pytest.mark.xfail("hasattr(sys, 'pypy_version_info')")
def test_errors_in_xfail_skip_expressions(testdir):
testdir.makepyfile("""
@@ -486,6 +502,10 @@ def test_errors_in_xfail_skip_expressions(testdir):
pass
""")
result = testdir.runpytest()
markline = " ^"
if sys.platform.startswith("java"):
# XXX report this to java
markline = "*" + markline[8:]
result.stdout.fnmatch_lines([
"*ERROR*test_nameerror*",
"*evaluating*skipif*expression*",
@@ -493,7 +513,7 @@ def test_errors_in_xfail_skip_expressions(testdir):
"*ERROR*test_syntax*",
"*evaluating*xfail*expression*",
" syntax error",
" ^",
markline,
"SyntaxError: invalid syntax",
"*1 pass*2 error*",
])

View File

@@ -66,7 +66,7 @@ deps=py>=1.4.0
[testenv:jython]
changedir=testing
commands=
{envpython} {envbindir}/py.test-jython --no-tools-on-path \
{envpython} {envbindir}/py.test-jython \
-rfsxX --junitxml={envlogdir}/junit-{envname}2.xml []
[pytest]