first attempt, mark individual parametrize test instances with other marks (like xfail)
This commit is contained in:
Brianna Laugher 2013-05-17 18:46:36 +10:00
parent 5a1ce3c45c
commit 5373a63008
2 changed files with 192 additions and 2 deletions

View File

@ -4,6 +4,7 @@ import inspect
import sys
import pytest
from _pytest.main import getfslineno
from _pytest.mark import MarkDecorator, MarkInfo
from _pytest.monkeypatch import monkeypatch
from py._code.code import TerminalRepr
@ -565,11 +566,13 @@ class CallSpec2(object):
self._globalid_args = set()
self._globalparam = _notexists
self._arg2scopenum = {} # used for sorting parametrized resources
self.keywords = {}
def copy(self, metafunc):
cs = CallSpec2(self.metafunc)
cs.funcargs.update(self.funcargs)
cs.params.update(self.params)
cs.keywords.update(self.keywords)
cs._arg2scopenum.update(self._arg2scopenum)
cs._idlist = list(self._idlist)
cs._globalid = self._globalid
@ -593,7 +596,7 @@ class CallSpec2(object):
def id(self):
return "-".join(map(str, filter(None, self._idlist)))
def setmulti(self, valtype, argnames, valset, id, scopenum=0):
def setmulti(self, valtype, argnames, valset, id, keywords, scopenum=0):
for arg,val in zip(argnames, valset):
self._checkargnotcontained(arg)
getattr(self, valtype)[arg] = val
@ -605,6 +608,7 @@ class CallSpec2(object):
if val is _notexists:
self._emptyparamspecified = True
self._idlist.append(id)
self.keywords.update(keywords)
def setall(self, funcargs, id, param):
for x in funcargs:
@ -673,6 +677,18 @@ class Metafunc(FuncargnamesCompatAttr):
if not argvalues:
argvalues = [(_notexists,) * len(argnames)]
# these marks/keywords will be applied in Function init
newkeywords = {}
for i, argval in enumerate(argvalues):
newkeywords[i] = {}
if isinstance(argval, MarkDecorator):
# convert into a mark without the test content mixed in
newmark = MarkDecorator(argval.markname, argval.args[:-1], argval.kwargs)
newkeywords[i] = {newmark.markname: newmark}
argvalues = [av.args[-1] if isinstance(av, MarkDecorator) else av
for av in argvalues]
if scope is None:
scope = "subfunction"
scopenum = scopes.index(scope)
@ -691,7 +707,7 @@ class Metafunc(FuncargnamesCompatAttr):
assert len(valset) == len(argnames)
newcallspec = callspec.copy(self)
newcallspec.setmulti(valtype, argnames, valset, ids[i],
scopenum)
newkeywords[i], scopenum)
newcalls.append(newcallspec)
self._calls = newcalls
@ -908,6 +924,9 @@ class Function(FunctionMixin, pytest.Item, FuncargnamesCompatAttr):
for name, val in (py.builtin._getfuncdict(self.obj) or {}).items():
self.keywords[name] = val
if callspec:
for name, val in callspec.keywords.items():
self.keywords[name] = val
if keywords:
for name, val in keywords.items():
self.keywords[name] = val

View File

@ -577,4 +577,175 @@ class TestMetafuncFunctional:
"*3 passed*"
])
@pytest.mark.issue308
def test_mark_on_individual_parametrize_instance(self, testdir):
s = """
import pytest
@pytest.mark.foo
@pytest.mark.parametrize(("input", "expected"), [
(1, 2),
pytest.mark.bar((1, 3)),
(2, 3),
])
def test_increment(input, expected):
assert input + 1 == expected
"""
items = testdir.getitems(s)
assert len(items) == 3
for item in items:
assert 'foo' in item.keywords
assert 'bar' not in items[0].keywords
assert 'bar' in items[1].keywords
assert 'bar' not in items[2].keywords
@pytest.mark.issue308
def test_select_individual_parametrize_instance_based_on_mark(self, testdir):
s = """
import pytest
@pytest.mark.parametrize(("input", "expected"), [
(1, 2),
pytest.mark.foo((2, 3)),
(3, 4),
])
def test_increment(input, expected):
assert input + 1 == expected
"""
testdir.makepyfile(s)
rec = testdir.inline_run("-m", 'foo')
passed, skipped, fail = rec.listoutcomes()
assert len(passed) == 1
assert len(skipped) == 0
assert len(fail) == 0
@pytest.mark.xfail("is this important to support??")
@pytest.mark.issue308
def test_nested_marks_on_individual_parametrize_instance(self, testdir):
s = """
import pytest
@pytest.mark.parametrize(("input", "expected"), [
(1, 2),
pytest.mark.foo(pytest.mark.bar((1, 3))),
(2, 3),
])
def test_increment(input, expected):
assert input + 1 == expected
"""
items = testdir.getitems(s)
assert len(items) == 3
for mark in ['foo', 'bar']:
assert mark not in items[0].keywords
assert mark in items[1].keywords
assert mark not in items[2].keywords
@pytest.mark.xfail(reason="is this important to support??")
@pytest.mark.issue308
def test_nested_marks_on_individual_parametrize_instance(self, testdir):
s = """
import pytest
mastermark = pytest.mark.foo(pytest.mark.bar)
@pytest.mark.parametrize(("input", "expected"), [
(1, 2),
mastermark((1, 3)),
(2, 3),
])
def test_increment(input, expected):
assert input + 1 == expected
"""
items = testdir.getitems(s)
assert len(items) == 3
for mark in ['foo', 'bar']:
assert mark not in items[0].keywords
assert mark in items[1].keywords
assert mark not in items[2].keywords
@pytest.mark.issue308
def test_simple_xfail_on_individual_parametrize_instance(self, testdir):
s = """
import pytest
@pytest.mark.parametrize(("input", "expected"), [
(1, 2),
pytest.mark.xfail((1, 3)),
(2, 3),
])
def test_increment(input, expected):
assert input + 1 == expected
"""
testdir.makepyfile(s)
reprec = testdir.inline_run()
# xfail is skip??
reprec.assertoutcome(passed=2, skipped=1)
@pytest.mark.issue308
def test_xfail_with_arg_on_individual_parametrize_instance(self, testdir):
s = """
import pytest
@pytest.mark.parametrize(("input", "expected"), [
(1, 2),
pytest.mark.xfail("sys.version > 0")((1, 3)),
(2, 3),
])
def test_increment(input, expected):
assert input + 1 == expected
"""
testdir.makepyfile(s)
reprec = testdir.inline_run()
reprec.assertoutcome(passed=2, skipped=1)
@pytest.mark.issue308
def test_xfail_with_kwarg_on_individual_parametrize_instance(self, testdir):
s = """
import pytest
@pytest.mark.parametrize(("input", "expected"), [
(1, 2),
pytest.mark.xfail(reason="some bug")((1, 3)),
(2, 3),
])
def test_increment(input, expected):
assert input + 1 == expected
"""
testdir.makepyfile(s)
reprec = testdir.inline_run()
reprec.assertoutcome(passed=2, skipped=1)
@pytest.mark.issue308
def test_xfail_with_arg_and_kwarg_on_individual_parametrize_instance(self, testdir):
s = """
import pytest
@pytest.mark.parametrize(("input", "expected"), [
(1, 2),
pytest.mark.xfail("sys.version > 0", reason="some bug")((1, 3)),
(2, 3),
])
def test_increment(input, expected):
assert input + 1 == expected
"""
testdir.makepyfile(s)
reprec = testdir.inline_run()
reprec.assertoutcome(passed=2, skipped=1)
@pytest.mark.issue308
def test_xfail_is_xpass_on_individual_parametrize_instance(self, testdir):
s = """
import pytest
@pytest.mark.parametrize(("input", "expected"), [
(1, 2),
pytest.mark.xfail("sys.version > 0", reason="some bug")((2, 3)),
(3, 4),
])
def test_increment(input, expected):
assert input + 1 == expected
"""
testdir.makepyfile(s)
reprec = testdir.inline_run()
# xpass is fail, obviously :)
reprec.assertoutcome(passed=2, failed=1)