[pypy-svn] r74641 - pypy/branch/py131/py/_plugin
hpk at codespeak.net
hpk at codespeak.net
Fri May 21 18:10:50 CEST 2010
Author: hpk
Date: Fri May 21 18:10:48 2010
New Revision: 74641
Modified:
pypy/branch/py131/py/_plugin/pytest_mark.py
pypy/branch/py131/py/_plugin/pytest_skipping.py
Log:
update to py-trunk 1.3.1a1 - fixing skipping/xfailing if specified
multiple times
Modified: pypy/branch/py131/py/_plugin/pytest_mark.py
==============================================================================
--- pypy/branch/py131/py/_plugin/pytest_mark.py (original)
+++ pypy/branch/py131/py/_plugin/pytest_mark.py Fri May 21 18:10:48 2010
@@ -34,38 +34,43 @@
.. _`scoped-marking`:
-Marking classes or modules
+Marking whole classes or modules
----------------------------------------------------
-To mark all methods of a class set a ``pytestmark`` attribute like this::
+If you are programming with Python2.6 you may use ``py.test.mark`` decorators
+with classes to apply markers to all its test methods::
+
+ @py.test.mark.webtest
+ class TestClass:
+ def test_startup(self):
+ ...
+
+This is equivalent to directly applying the decorator to the
+``test_startup`` function.
+
+To remain compatible with Python2.5 you can instead set a
+``pytestmark`` attribute on a TestClass like this::
import py
class TestClass:
pytestmark = py.test.mark.webtest
-You can re-use the same markers that you would use for decorating
-a function - in fact this marker decorator will be applied
-to all test methods of the class.
+or if you need to use multiple markers::
+
+ import py
+
+ class TestClass:
+ pytestmark = [py.test.mark.webtest, pytest.mark.slowtest]
You can also set a module level marker::
import py
pytestmark = py.test.mark.webtest
-in which case then the marker decorator will be applied to all functions and
+in which case then it will be applied to all functions and
methods defined in the module.
-The order in which marker functions are called is this::
-
- per-function (upon import of module already)
- per-class
- per-module
-
-Later called markers may overwrite previous key-value settings.
-Positional arguments are all appended to the same 'args' list
-of the Marker object.
-
Using "-k MARKNAME" to select tests
----------------------------------------------------
@@ -105,15 +110,23 @@
""" if passed a single callable argument: decorate it with mark info.
otherwise add *args/**kwargs in-place to mark information. """
if args:
- if len(args) == 1 and hasattr(args[0], '__call__'):
- func = args[0]
- holder = getattr(func, self.markname, None)
- if holder is None:
- holder = MarkInfo(self.markname, self.args, self.kwargs)
- setattr(func, self.markname, holder)
+ func = args[0]
+ if len(args) == 1 and hasattr(func, '__call__') or \
+ hasattr(func, '__bases__'):
+ if hasattr(func, '__bases__'):
+ l = func.__dict__.setdefault("pytestmark", [])
+ if not isinstance(l, list):
+ func.pytestmark = [l, self]
+ else:
+ l.append(self)
else:
- holder.kwargs.update(self.kwargs)
- holder.args.extend(self.args)
+ holder = getattr(func, self.markname, None)
+ if holder is None:
+ holder = MarkInfo(self.markname, self.args, self.kwargs)
+ setattr(func, self.markname, holder)
+ else:
+ holder.kwargs.update(self.kwargs)
+ holder.args.extend(self.args)
return func
else:
self.args.extend(args)
@@ -147,6 +160,10 @@
func = getattr(func, 'im_func', func) # py2
for parent in [x for x in (mod, cls) if x]:
marker = getattr(parent.obj, 'pytestmark', None)
- if isinstance(marker, MarkDecorator):
- marker(func)
+ if marker is not None:
+ if not isinstance(marker, list):
+ marker = [marker]
+ for mark in marker:
+ if isinstance(mark, MarkDecorator):
+ mark(func)
return item
Modified: pypy/branch/py131/py/_plugin/pytest_skipping.py
==============================================================================
--- pypy/branch/py131/py/_plugin/pytest_skipping.py (original)
+++ pypy/branch/py131/py/_plugin/pytest_skipping.py Fri May 21 18:10:48 2010
@@ -60,6 +60,19 @@
#
The ``pytestmark`` decorator will be applied to each test function.
+If your code targets python2.6 or above you can equivalently use
+the skipif decorator on classes::
+
+ @py.test.mark.skipif("sys.platform == 'win32'")
+ class TestPosixCalls:
+
+ def test_function(self):
+ # will not be setup or run under 'win32' platform
+ #
+
+It is fine in general to apply multiple "skipif" decorators
+on a single function - this means that if any of the conditions
+apply the function will be skipped.
.. _`whole class- or module level`: mark.html#scoped-marking
@@ -144,17 +157,20 @@
def istrue(self):
if self.holder:
d = {'os': py.std.os, 'sys': py.std.sys, 'config': self.item.config}
- self.result = True
- for expr in self.holder.args:
- self.expr = expr
- if isinstance(expr, str):
- result = cached_eval(self.item.config, expr, d)
- else:
- result = expr
- if not result:
- self.result = False
+ if self.holder.args:
+ self.result = False
+ for expr in self.holder.args:
self.expr = expr
- break
+ if isinstance(expr, str):
+ result = cached_eval(self.item.config, expr, d)
+ else:
+ result = expr
+ if result:
+ self.result = True
+ self.expr = expr
+ break
+ else:
+ self.result = True
return getattr(self, 'result', False)
def get(self, attr, default=None):
More information about the Pypy-commit
mailing list