introduce a new "markers" attribute to nodes and the request object. It is
a dynamic class making holdin
This commit is contained in:
parent
646c2c6001
commit
a94bb0a8bb
|
@ -1,6 +1,9 @@
|
||||||
Changes between 2.2.4 and 2.3.0.dev
|
Changes between 2.2.4 and 2.3.0.dev
|
||||||
-----------------------------------
|
-----------------------------------
|
||||||
|
|
||||||
|
- introduce a generic "markers" object on Nodes and request objects
|
||||||
|
to allow for reading and manipulation of MarkInfo objects previously
|
||||||
|
set with calls to pytest.mark.* classes.
|
||||||
- fix issue185 monkeypatching time.time does not cause pytest to fail
|
- fix issue185 monkeypatching time.time does not cause pytest to fail
|
||||||
- fix issue172 duplicate call of pytest.setup-decoratored setup_module
|
- fix issue172 duplicate call of pytest.setup-decoratored setup_module
|
||||||
functions
|
functions
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
#
|
#
|
||||||
__version__ = '2.3.0.dev11'
|
__version__ = '2.3.0.dev12'
|
||||||
|
|
|
@ -181,14 +181,21 @@ class Node(object):
|
||||||
#: filesystem path where this node was collected from (can be None)
|
#: filesystem path where this node was collected from (can be None)
|
||||||
self.fspath = getattr(parent, 'fspath', None)
|
self.fspath = getattr(parent, 'fspath', None)
|
||||||
|
|
||||||
#: keywords on this node (node name is always contained)
|
|
||||||
self.keywords = {self.name: True}
|
|
||||||
|
|
||||||
#: fspath sensitive hook proxy used to call pytest hooks
|
#: fspath sensitive hook proxy used to call pytest hooks
|
||||||
self.ihook = self.session.gethookproxy(self.fspath)
|
self.ihook = self.session.gethookproxy(self.fspath)
|
||||||
|
|
||||||
|
bases = parent and (parent.markers,) or ()
|
||||||
|
|
||||||
|
#: marker class with markers from all scopes accessible as attributes
|
||||||
|
self.markers = type("dynmarker", bases, {self.name: True})
|
||||||
|
|
||||||
#self.extrainit()
|
#self.extrainit()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def keywords(self):
|
||||||
|
""" dictionary of Keywords / markers on this node. """
|
||||||
|
return vars(self.markers)
|
||||||
|
|
||||||
#def extrainit(self):
|
#def extrainit(self):
|
||||||
# """"extra initialization after Node is initialized. Implemented
|
# """"extra initialization after Node is initialized. Implemented
|
||||||
# by some subclasses. """
|
# by some subclasses. """
|
||||||
|
|
|
@ -859,9 +859,11 @@ class Function(FunctionMixin, pytest.Item):
|
||||||
self.obj = callobj
|
self.obj = callobj
|
||||||
startindex = int(self.cls is not None)
|
startindex = int(self.cls is not None)
|
||||||
self.funcargnames = getfuncargnames(self.obj, startindex=startindex)
|
self.funcargnames = getfuncargnames(self.obj, startindex=startindex)
|
||||||
self.keywords.update(py.builtin._getfuncdict(self.obj) or {})
|
for name, val in (py.builtin._getfuncdict(self.obj) or {}).items():
|
||||||
|
setattr(self.markers, name, val)
|
||||||
if keywords:
|
if keywords:
|
||||||
self.keywords.update(keywords)
|
for name, val in keywords.items():
|
||||||
|
setattr(self.markers, name, val)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def function(self):
|
def function(self):
|
||||||
|
@ -959,6 +961,10 @@ class FuncargRequest:
|
||||||
self.parentid = pyfuncitem.parent.nodeid
|
self.parentid = pyfuncitem.parent.nodeid
|
||||||
self._factorystack = []
|
self._factorystack = []
|
||||||
|
|
||||||
|
@property
|
||||||
|
def markers(self):
|
||||||
|
return self._getscopeitem(self.scope).markers
|
||||||
|
|
||||||
def _getfaclist(self, argname):
|
def _getfaclist(self, argname):
|
||||||
facdeflist = self._name2factory.get(argname, None)
|
facdeflist = self._name2factory.get(argname, None)
|
||||||
if facdeflist is None:
|
if facdeflist is None:
|
||||||
|
@ -1011,7 +1017,7 @@ class FuncargRequest:
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def keywords(self):
|
def keywords(self):
|
||||||
""" keywords of the test function item. """
|
""" dictionary of markers (readonly). """
|
||||||
return self._pyfuncitem.keywords
|
return self._pyfuncitem.keywords
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@ -1019,8 +1025,6 @@ class FuncargRequest:
|
||||||
""" pytest session object. """
|
""" pytest session object. """
|
||||||
return self._pyfuncitem.session
|
return self._pyfuncitem.session
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def addfinalizer(self, finalizer):
|
def addfinalizer(self, finalizer):
|
||||||
"""add finalizer/teardown function to be called after the
|
"""add finalizer/teardown function to be called after the
|
||||||
last test within the requesting test context finished
|
last test within the requesting test context finished
|
||||||
|
@ -1047,7 +1051,8 @@ class FuncargRequest:
|
||||||
"""
|
"""
|
||||||
if not isinstance(marker, py.test.mark.XYZ.__class__):
|
if not isinstance(marker, py.test.mark.XYZ.__class__):
|
||||||
raise ValueError("%r is not a py.test.mark.* object")
|
raise ValueError("%r is not a py.test.mark.* object")
|
||||||
self._pyfuncitem.keywords[marker.markname] = marker
|
setattr(self.markers, marker.markname, marker)
|
||||||
|
#self._pyfuncitem.keywords[marker.markname] = marker
|
||||||
|
|
||||||
def raiseerror(self, msg):
|
def raiseerror(self, msg):
|
||||||
""" raise a FuncargLookupError with the given message. """
|
""" raise a FuncargLookupError with the given message. """
|
||||||
|
|
|
@ -26,29 +26,29 @@ You can then restrict a test run to only run tests marked with ``webtest``::
|
||||||
|
|
||||||
$ py.test -v -m webtest
|
$ py.test -v -m webtest
|
||||||
=========================== test session starts ============================
|
=========================== test session starts ============================
|
||||||
platform linux2 -- Python 2.7.3 -- pytest-2.3.0.dev2 -- /home/hpk/venv/1/bin/python
|
platform linux2 -- Python 2.7.3 -- pytest-2.3.0.dev11 -- /home/hpk/venv/1/bin/python
|
||||||
cachedir: /home/hpk/tmp/doc-exec-305/.cache
|
cachedir: /home/hpk/tmp/doc-exec-426/.cache
|
||||||
plugins: xdist, bugzilla, cache, oejskit, pep8, cov
|
plugins: xdist, bugzilla, cache, oejskit, cli, timeout, pep8, cov
|
||||||
collecting ... collected 2 items
|
collecting ... collected 2 items
|
||||||
|
|
||||||
test_server.py:3: test_send_http PASSED
|
test_server.py:3: test_send_http PASSED
|
||||||
|
|
||||||
=================== 1 tests deselected by "-m 'webtest'" ===================
|
=================== 1 tests deselected by "-m 'webtest'" ===================
|
||||||
================== 1 passed, 1 deselected in 0.02 seconds ==================
|
================== 1 passed, 1 deselected in 0.01 seconds ==================
|
||||||
|
|
||||||
Or the inverse, running all tests except the webtest ones::
|
Or the inverse, running all tests except the webtest ones::
|
||||||
|
|
||||||
$ py.test -v -m "not webtest"
|
$ py.test -v -m "not webtest"
|
||||||
=========================== test session starts ============================
|
=========================== test session starts ============================
|
||||||
platform linux2 -- Python 2.7.3 -- pytest-2.3.0.dev2 -- /home/hpk/venv/1/bin/python
|
platform linux2 -- Python 2.7.3 -- pytest-2.3.0.dev11 -- /home/hpk/venv/1/bin/python
|
||||||
cachedir: /home/hpk/tmp/doc-exec-305/.cache
|
cachedir: /home/hpk/tmp/doc-exec-426/.cache
|
||||||
plugins: xdist, bugzilla, cache, oejskit, pep8, cov
|
plugins: xdist, bugzilla, cache, oejskit, cli, timeout, pep8, cov
|
||||||
collecting ... collected 2 items
|
collecting ... collected 2 items
|
||||||
|
|
||||||
test_server.py:6: test_something_quick PASSED
|
test_server.py:6: test_something_quick PASSED
|
||||||
|
|
||||||
================= 1 tests deselected by "-m 'not webtest'" =================
|
================= 1 tests deselected by "-m 'not webtest'" =================
|
||||||
================== 1 passed, 1 deselected in 0.02 seconds ==================
|
================== 1 passed, 1 deselected in 0.01 seconds ==================
|
||||||
|
|
||||||
Registering markers
|
Registering markers
|
||||||
-------------------------------------
|
-------------------------------------
|
||||||
|
@ -69,6 +69,8 @@ You can ask which markers exist for your test suite - the list includes our just
|
||||||
$ py.test --markers
|
$ py.test --markers
|
||||||
@pytest.mark.webtest: mark a test as a webtest.
|
@pytest.mark.webtest: mark a test as a webtest.
|
||||||
|
|
||||||
|
@pytest.mark.timeout(timeout, method=None): Set a timeout and timeout method on just one test item. The first argument, *timeout*, is the timeout in seconds while the keyword, *method*, takes the same values as the --timeout_method option.
|
||||||
|
|
||||||
@pytest.mark.skipif(*conditions): skip the given test function if evaluation of all conditions has a True value. Evaluation happens within the module global context. Example: skipif('sys.platform == "win32"') skips the test if we are on the win32 platform.
|
@pytest.mark.skipif(*conditions): skip the given test function if evaluation of all conditions has a True value. Evaluation happens within the module global context. Example: skipif('sys.platform == "win32"') skips the test if we are on the win32 platform.
|
||||||
|
|
||||||
@pytest.mark.xfail(*conditions, reason=None, run=True): mark the the test function as an expected failure. Optionally specify a reason and run=False if you don't even want to execute the test function. Any positional condition strings will be evaluated (like with skipif) and if one is False the marker will not be applied.
|
@pytest.mark.xfail(*conditions, reason=None, run=True): mark the the test function as an expected failure. Optionally specify a reason and run=False if you don't even want to execute the test function. Any positional condition strings will be evaluated (like with skipif) and if one is False the marker will not be applied.
|
||||||
|
@ -147,8 +149,8 @@ the given argument::
|
||||||
|
|
||||||
$ py.test -k send_http # running with the above defined examples
|
$ py.test -k send_http # running with the above defined examples
|
||||||
=========================== test session starts ============================
|
=========================== test session starts ============================
|
||||||
platform linux2 -- Python 2.7.3 -- pytest-2.3.0.dev2
|
platform linux2 -- Python 2.7.3 -- pytest-2.3.0.dev11
|
||||||
plugins: xdist, bugzilla, cache, oejskit, pep8, cov
|
plugins: xdist, bugzilla, cache, oejskit, cli, timeout, pep8, cov
|
||||||
collecting ... collected 4 items
|
collecting ... collected 4 items
|
||||||
|
|
||||||
test_server.py .
|
test_server.py .
|
||||||
|
@ -160,8 +162,8 @@ And you can also run all tests except the ones that match the keyword::
|
||||||
|
|
||||||
$ py.test -k-send_http
|
$ py.test -k-send_http
|
||||||
=========================== test session starts ============================
|
=========================== test session starts ============================
|
||||||
platform linux2 -- Python 2.7.3 -- pytest-2.3.0.dev2
|
platform linux2 -- Python 2.7.3 -- pytest-2.3.0.dev11
|
||||||
plugins: xdist, bugzilla, cache, oejskit, pep8, cov
|
plugins: xdist, bugzilla, cache, oejskit, cli, timeout, pep8, cov
|
||||||
collecting ... collected 4 items
|
collecting ... collected 4 items
|
||||||
|
|
||||||
test_mark_classlevel.py ..
|
test_mark_classlevel.py ..
|
||||||
|
@ -174,8 +176,8 @@ Or to only select the class::
|
||||||
|
|
||||||
$ py.test -kTestClass
|
$ py.test -kTestClass
|
||||||
=========================== test session starts ============================
|
=========================== test session starts ============================
|
||||||
platform linux2 -- Python 2.7.3 -- pytest-2.3.0.dev2
|
platform linux2 -- Python 2.7.3 -- pytest-2.3.0.dev11
|
||||||
plugins: xdist, bugzilla, cache, oejskit, pep8, cov
|
plugins: xdist, bugzilla, cache, oejskit, cli, timeout, pep8, cov
|
||||||
collecting ... collected 4 items
|
collecting ... collected 4 items
|
||||||
|
|
||||||
test_mark_classlevel.py ..
|
test_mark_classlevel.py ..
|
||||||
|
@ -208,10 +210,8 @@ specifies via named environments::
|
||||||
"env(name): mark test to run only on named environment")
|
"env(name): mark test to run only on named environment")
|
||||||
|
|
||||||
def pytest_runtest_setup(item):
|
def pytest_runtest_setup(item):
|
||||||
if not isinstance(item, pytest.Function):
|
envmarker = getattr(item.markers, 'env', None)
|
||||||
return
|
if envmarker is not None:
|
||||||
if hasattr(item.obj, 'env'):
|
|
||||||
envmarker = getattr(item.obj, 'env')
|
|
||||||
envname = envmarker.args[0]
|
envname = envmarker.args[0]
|
||||||
if envname != item.config.option.env:
|
if envname != item.config.option.env:
|
||||||
pytest.skip("test requires env %r" % envname)
|
pytest.skip("test requires env %r" % envname)
|
||||||
|
@ -230,31 +230,33 @@ the test needs::
|
||||||
|
|
||||||
$ py.test -E stage2
|
$ py.test -E stage2
|
||||||
=========================== test session starts ============================
|
=========================== test session starts ============================
|
||||||
platform linux2 -- Python 2.7.3 -- pytest-2.3.0.dev2
|
platform linux2 -- Python 2.7.3 -- pytest-2.3.0.dev11
|
||||||
plugins: xdist, bugzilla, cache, oejskit, pep8, cov
|
plugins: xdist, bugzilla, cache, oejskit, cli, timeout, pep8, cov
|
||||||
collecting ... collected 1 items
|
collecting ... collected 1 items
|
||||||
|
|
||||||
test_someenv.py s
|
test_someenv.py s
|
||||||
|
|
||||||
======================== 1 skipped in 0.02 seconds =========================
|
======================== 1 skipped in 0.01 seconds =========================
|
||||||
|
|
||||||
and here is one that specifies exactly the environment needed::
|
and here is one that specifies exactly the environment needed::
|
||||||
|
|
||||||
$ py.test -E stage1
|
$ py.test -E stage1
|
||||||
=========================== test session starts ============================
|
=========================== test session starts ============================
|
||||||
platform linux2 -- Python 2.7.3 -- pytest-2.3.0.dev2
|
platform linux2 -- Python 2.7.3 -- pytest-2.3.0.dev11
|
||||||
plugins: xdist, bugzilla, cache, oejskit, pep8, cov
|
plugins: xdist, bugzilla, cache, oejskit, cli, timeout, pep8, cov
|
||||||
collecting ... collected 1 items
|
collecting ... collected 1 items
|
||||||
|
|
||||||
test_someenv.py .
|
test_someenv.py .
|
||||||
|
|
||||||
========================= 1 passed in 0.02 seconds =========================
|
========================= 1 passed in 0.01 seconds =========================
|
||||||
|
|
||||||
The ``--markers`` option always gives you a list of available markers::
|
The ``--markers`` option always gives you a list of available markers::
|
||||||
|
|
||||||
$ py.test --markers
|
$ py.test --markers
|
||||||
@pytest.mark.env(name): mark test to run only on named environment
|
@pytest.mark.env(name): mark test to run only on named environment
|
||||||
|
|
||||||
|
@pytest.mark.timeout(timeout, method=None): Set a timeout and timeout method on just one test item. The first argument, *timeout*, is the timeout in seconds while the keyword, *method*, takes the same values as the --timeout_method option.
|
||||||
|
|
||||||
@pytest.mark.skipif(*conditions): skip the given test function if evaluation of all conditions has a True value. Evaluation happens within the module global context. Example: skipif('sys.platform == "win32"') skips the test if we are on the win32 platform.
|
@pytest.mark.skipif(*conditions): skip the given test function if evaluation of all conditions has a True value. Evaluation happens within the module global context. Example: skipif('sys.platform == "win32"') skips the test if we are on the win32 platform.
|
||||||
|
|
||||||
@pytest.mark.xfail(*conditions, reason=None, run=True): mark the the test function as an expected failure. Optionally specify a reason and run=False if you don't even want to execute the test function. Any positional condition strings will be evaluated (like with skipif) and if one is False the marker will not be applied.
|
@pytest.mark.xfail(*conditions, reason=None, run=True): mark the the test function as an expected failure. Optionally specify a reason and run=False if you don't even want to execute the test function. Any positional condition strings will be evaluated (like with skipif) and if one is False the marker will not be applied.
|
||||||
|
@ -264,7 +266,7 @@ The ``--markers`` option always gives you a list of available markers::
|
||||||
@pytest.mark.tryfirst: mark a hook implementation function such that the plugin machinery will try to call it first/as early as possible.
|
@pytest.mark.tryfirst: mark a hook implementation function such that the plugin machinery will try to call it first/as early as possible.
|
||||||
|
|
||||||
@pytest.mark.trylast: mark a hook implementation function such that the plugin machinery will try to call it last/as late as possible.
|
@pytest.mark.trylast: mark a hook implementation function such that the plugin machinery will try to call it last/as late as possible.
|
||||||
|
|
||||||
|
|
||||||
Reading markers which were set from multiple places
|
Reading markers which were set from multiple places
|
||||||
----------------------------------------------------
|
----------------------------------------------------
|
||||||
|
@ -293,7 +295,7 @@ test function. From a conftest file we can read it like this::
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
def pytest_runtest_setup(item):
|
def pytest_runtest_setup(item):
|
||||||
g = getattr(item.obj, 'glob', None)
|
g = getattr(item.markers, "glob", None)
|
||||||
if g is not None:
|
if g is not None:
|
||||||
for info in g:
|
for info in g:
|
||||||
print ("glob args=%s kwargs=%s" %(info.args, info.kwargs))
|
print ("glob args=%s kwargs=%s" %(info.args, info.kwargs))
|
||||||
|
@ -307,7 +309,7 @@ Let's run this without capturing output and see what we get::
|
||||||
glob args=('class',) kwargs={'x': 2}
|
glob args=('class',) kwargs={'x': 2}
|
||||||
glob args=('module',) kwargs={'x': 1}
|
glob args=('module',) kwargs={'x': 1}
|
||||||
.
|
.
|
||||||
1 passed in 0.02 seconds
|
1 passed in 0.01 seconds
|
||||||
|
|
||||||
marking platform specific tests with pytest
|
marking platform specific tests with pytest
|
||||||
--------------------------------------------------------------
|
--------------------------------------------------------------
|
||||||
|
@ -330,7 +332,7 @@ for your particular platform, you could use the following plugin::
|
||||||
def pytest_runtest_setup(item):
|
def pytest_runtest_setup(item):
|
||||||
if isinstance(item, item.Function):
|
if isinstance(item, item.Function):
|
||||||
plat = sys.platform
|
plat = sys.platform
|
||||||
if not hasattr(item.obj, plat):
|
if not hasattr(item.markers, plat):
|
||||||
if ALL.intersection(set(item.obj.__dict__)):
|
if ALL.intersection(set(item.obj.__dict__)):
|
||||||
pytest.skip("cannot run on platform %s" %(plat))
|
pytest.skip("cannot run on platform %s" %(plat))
|
||||||
|
|
||||||
|
@ -360,13 +362,13 @@ then you will see two test skipped and two executed tests as expected::
|
||||||
|
|
||||||
$ py.test -rs # this option reports skip reasons
|
$ py.test -rs # this option reports skip reasons
|
||||||
=========================== test session starts ============================
|
=========================== test session starts ============================
|
||||||
platform linux2 -- Python 2.7.3 -- pytest-2.3.0.dev2
|
platform linux2 -- Python 2.7.3 -- pytest-2.3.0.dev11
|
||||||
plugins: xdist, bugzilla, cache, oejskit, pep8, cov
|
plugins: xdist, bugzilla, cache, oejskit, cli, timeout, pep8, cov
|
||||||
collecting ... collected 4 items
|
collecting ... collected 4 items
|
||||||
|
|
||||||
test_plat.py s.s.
|
test_plat.py s.s.
|
||||||
========================= short test summary info ==========================
|
========================= short test summary info ==========================
|
||||||
SKIP [2] /home/hpk/tmp/doc-exec-305/conftest.py:12: cannot run on platform linux2
|
SKIP [2] /home/hpk/tmp/doc-exec-426/conftest.py:12: cannot run on platform linux2
|
||||||
|
|
||||||
=================== 2 passed, 2 skipped in 0.02 seconds ====================
|
=================== 2 passed, 2 skipped in 0.02 seconds ====================
|
||||||
|
|
||||||
|
@ -374,13 +376,13 @@ Note that if you specify a platform via the marker-command line option like this
|
||||||
|
|
||||||
$ py.test -m linux2
|
$ py.test -m linux2
|
||||||
=========================== test session starts ============================
|
=========================== test session starts ============================
|
||||||
platform linux2 -- Python 2.7.3 -- pytest-2.3.0.dev2
|
platform linux2 -- Python 2.7.3 -- pytest-2.3.0.dev11
|
||||||
plugins: xdist, bugzilla, cache, oejskit, pep8, cov
|
plugins: xdist, bugzilla, cache, oejskit, cli, timeout, pep8, cov
|
||||||
collecting ... collected 4 items
|
collecting ... collected 4 items
|
||||||
|
|
||||||
test_plat.py .
|
test_plat.py .
|
||||||
|
|
||||||
=================== 3 tests deselected by "-m 'linux2'" ====================
|
=================== 3 tests deselected by "-m 'linux2'" ====================
|
||||||
================== 1 passed, 3 deselected in 0.02 seconds ==================
|
================== 1 passed, 3 deselected in 0.01 seconds ==================
|
||||||
|
|
||||||
then the unmarked-tests will not be run. It is thus a way to restrict the run to the specific tests.
|
then the unmarked-tests will not be run. It is thus a way to restrict the run to the specific tests.
|
||||||
|
|
2
setup.py
2
setup.py
|
@ -24,7 +24,7 @@ def main():
|
||||||
name='pytest',
|
name='pytest',
|
||||||
description='py.test: simple powerful testing with Python',
|
description='py.test: simple powerful testing with Python',
|
||||||
long_description = long_description,
|
long_description = long_description,
|
||||||
version='2.3.0.dev11',
|
version='2.3.0.dev12',
|
||||||
url='http://pytest.org',
|
url='http://pytest.org',
|
||||||
license='MIT license',
|
license='MIT license',
|
||||||
platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'],
|
platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'],
|
||||||
|
|
|
@ -318,7 +318,7 @@ class TestKeywordSelection:
|
||||||
def pytest_pycollect_makeitem(__multicall__, name):
|
def pytest_pycollect_makeitem(__multicall__, name):
|
||||||
if name == "TestClass":
|
if name == "TestClass":
|
||||||
item = __multicall__.execute()
|
item = __multicall__.execute()
|
||||||
item.keywords['xxx'] = True
|
item.markers.xxx = True
|
||||||
return item
|
return item
|
||||||
""")
|
""")
|
||||||
for keyword in ('xxx', 'xxx test_2', 'TestClass', 'xxx -test_1',
|
for keyword in ('xxx', 'xxx test_2', 'TestClass', 'xxx -test_1',
|
||||||
|
|
|
@ -609,7 +609,7 @@ class TestRequest:
|
||||||
""")
|
""")
|
||||||
req = funcargs.FuncargRequest(item)
|
req = funcargs.FuncargRequest(item)
|
||||||
assert req.function == item.obj
|
assert req.function == item.obj
|
||||||
assert req.keywords is item.keywords
|
assert req.keywords == item.keywords
|
||||||
assert hasattr(req.module, 'test_func')
|
assert hasattr(req.module, 'test_func')
|
||||||
assert req.cls is None
|
assert req.cls is None
|
||||||
assert req.function.__name__ == "test_func"
|
assert req.function.__name__ == "test_func"
|
||||||
|
@ -716,24 +716,63 @@ class TestRequest:
|
||||||
req = funcargs.FuncargRequest(item)
|
req = funcargs.FuncargRequest(item)
|
||||||
assert req.fspath == modcol.fspath
|
assert req.fspath == modcol.fspath
|
||||||
|
|
||||||
def test_applymarker(testdir):
|
class TestMarking:
|
||||||
item1,item2 = testdir.getitems("""
|
def test_applymarker(self, testdir):
|
||||||
def pytest_funcarg__something(request):
|
item1,item2 = testdir.getitems("""
|
||||||
pass
|
def pytest_funcarg__something(request):
|
||||||
class TestClass:
|
|
||||||
def test_func1(self, something):
|
|
||||||
pass
|
pass
|
||||||
def test_func2(self, something):
|
class TestClass:
|
||||||
pass
|
def test_func1(self, something):
|
||||||
""")
|
pass
|
||||||
req1 = funcargs.FuncargRequest(item1)
|
def test_func2(self, something):
|
||||||
assert 'xfail' not in item1.keywords
|
pass
|
||||||
req1.applymarker(pytest.mark.xfail)
|
""")
|
||||||
assert 'xfail' in item1.keywords
|
req1 = funcargs.FuncargRequest(item1)
|
||||||
assert 'skipif' not in item1.keywords
|
assert 'xfail' not in item1.keywords
|
||||||
req1.applymarker(pytest.mark.skipif)
|
req1.applymarker(pytest.mark.xfail)
|
||||||
assert 'skipif' in item1.keywords
|
assert 'xfail' in item1.keywords
|
||||||
pytest.raises(ValueError, "req1.applymarker(42)")
|
assert 'skipif' not in item1.keywords
|
||||||
|
req1.applymarker(pytest.mark.skipif)
|
||||||
|
assert 'skipif' in item1.keywords
|
||||||
|
pytest.raises(ValueError, "req1.applymarker(42)")
|
||||||
|
|
||||||
|
def test_accessmarker_function(self, testdir):
|
||||||
|
testdir.makepyfile("""
|
||||||
|
import pytest
|
||||||
|
@pytest.factory()
|
||||||
|
def markers(request):
|
||||||
|
return request.markers
|
||||||
|
@pytest.mark.XYZ
|
||||||
|
def test_function(markers):
|
||||||
|
assert markers.XYZ is not None
|
||||||
|
assert not hasattr(markers, "abc")
|
||||||
|
""")
|
||||||
|
reprec = testdir.inline_run()
|
||||||
|
reprec.assertoutcome(passed=1)
|
||||||
|
|
||||||
|
def test_accessmarker_dynamic(self, testdir):
|
||||||
|
testdir.makeconftest("""
|
||||||
|
import pytest
|
||||||
|
@pytest.factory()
|
||||||
|
def markers(request):
|
||||||
|
return request.markers
|
||||||
|
|
||||||
|
@pytest.setup(scope="class")
|
||||||
|
def marking(request):
|
||||||
|
request.applymarker(pytest.mark.XYZ("hello"))
|
||||||
|
""")
|
||||||
|
testdir.makepyfile("""
|
||||||
|
import pytest
|
||||||
|
def test_fun1(markers):
|
||||||
|
assert markers.XYZ is not None
|
||||||
|
assert not hasattr(markers, "abc")
|
||||||
|
def test_fun2(markers):
|
||||||
|
assert markers.XYZ is not None
|
||||||
|
assert not hasattr(markers, "abc")
|
||||||
|
""")
|
||||||
|
reprec = testdir.inline_run()
|
||||||
|
reprec.assertoutcome(passed=2)
|
||||||
|
|
||||||
|
|
||||||
class TestRequestCachedSetup:
|
class TestRequestCachedSetup:
|
||||||
def test_request_cachedsetup_defaultmodule(self, testdir):
|
def test_request_cachedsetup_defaultmodule(self, testdir):
|
||||||
|
@ -2365,13 +2404,14 @@ class TestFuncargMarker:
|
||||||
reprec = testdir.inline_run("-v")
|
reprec = testdir.inline_run("-v")
|
||||||
reprec.assertoutcome(passed=6)
|
reprec.assertoutcome(passed=6)
|
||||||
|
|
||||||
@pytest.mark.parametrize(("scope", "ok", "error"),[
|
|
||||||
["session", "", "fspath class function module"],
|
|
||||||
["module", "module fspath", "cls function"],
|
|
||||||
["class", "module fspath cls", "function"],
|
|
||||||
["function", "module fspath cls function", ""]
|
|
||||||
])
|
|
||||||
class TestTestContextScopeAccess:
|
class TestTestContextScopeAccess:
|
||||||
|
pytestmark = pytest.mark.parametrize(("scope", "ok", "error"),[
|
||||||
|
["session", "", "fspath class function module"],
|
||||||
|
["module", "module fspath", "cls function"],
|
||||||
|
["class", "module fspath cls", "function"],
|
||||||
|
["function", "module fspath cls function", ""]
|
||||||
|
])
|
||||||
|
|
||||||
def test_setup(self, testdir, scope, ok, error):
|
def test_setup(self, testdir, scope, ok, error):
|
||||||
testdir.makepyfile("""
|
testdir.makepyfile("""
|
||||||
import pytest
|
import pytest
|
||||||
|
|
Loading…
Reference in New Issue