2009-06-28 19:19:43 +08:00
|
|
|
"""
|
2009-07-28 20:26:32 +08:00
|
|
|
mark test functions with keywords that may hold values.
|
|
|
|
|
|
|
|
Marking functions and setting rich attributes
|
|
|
|
----------------------------------------------------
|
|
|
|
|
|
|
|
By default, all filename parts and class/function names of a test
|
|
|
|
function are put into the set of keywords for a given test. You can
|
|
|
|
specify additional kewords like this::
|
|
|
|
|
|
|
|
@py.test.mark.webtest
|
|
|
|
def test_send_http():
|
|
|
|
...
|
|
|
|
|
|
|
|
This will set an attribute 'webtest' on the given test function
|
|
|
|
and by default all such attributes signal keywords. You can
|
|
|
|
also set values in this attribute which you could read from
|
|
|
|
a hook in order to do something special with respect to
|
|
|
|
the test function::
|
|
|
|
|
|
|
|
@py.test.mark.timeout(seconds=5)
|
|
|
|
def test_receive():
|
|
|
|
...
|
|
|
|
|
|
|
|
This will set the "timeout" attribute with a Marker object
|
|
|
|
that has a 'seconds' attribute.
|
|
|
|
|
2009-06-28 19:19:43 +08:00
|
|
|
"""
|
|
|
|
import py
|
|
|
|
|
2009-07-18 00:07:37 +08:00
|
|
|
def pytest_namespace():
|
2009-07-28 20:26:32 +08:00
|
|
|
return {'mark': Mark()}
|
2009-06-28 19:19:43 +08:00
|
|
|
|
|
|
|
|
2009-07-28 20:26:32 +08:00
|
|
|
class Mark(object):
|
2009-06-28 19:19:43 +08:00
|
|
|
def __getattr__(self, name):
|
|
|
|
if name[0] == "_":
|
|
|
|
raise AttributeError(name)
|
2009-07-28 20:26:32 +08:00
|
|
|
return MarkerDecorator(name)
|
2009-06-28 19:19:43 +08:00
|
|
|
|
2009-07-28 20:26:32 +08:00
|
|
|
class MarkerDecorator:
|
|
|
|
""" decorator for setting function attributes. """
|
|
|
|
def __init__(self, name):
|
|
|
|
self.markname = name
|
2009-06-28 19:19:43 +08:00
|
|
|
|
2009-07-28 20:26:32 +08:00
|
|
|
def __repr__(self):
|
|
|
|
d = self.__dict__.copy()
|
|
|
|
name = d.pop('markname')
|
|
|
|
return "<MarkerDecorator %r %r>" %(name, d)
|
2009-06-28 19:19:43 +08:00
|
|
|
|
2009-07-28 20:26:32 +08:00
|
|
|
def __call__(self, *args, **kwargs):
|
|
|
|
if not args:
|
|
|
|
if hasattr(self, 'kwargs'):
|
|
|
|
raise TypeError("double mark-keywords?")
|
|
|
|
self.kwargs = kwargs.copy()
|
|
|
|
return self
|
|
|
|
else:
|
|
|
|
if not len(args) == 1 or not hasattr(args[0], 'func_dict'):
|
|
|
|
raise TypeError("need exactly one function to decorate, "
|
|
|
|
"got %r" %(args,))
|
|
|
|
func = args[0]
|
|
|
|
mh = MarkHolder(getattr(self, 'kwargs', {}))
|
|
|
|
setattr(func, self.markname, mh)
|
|
|
|
return func
|
2009-06-28 19:19:43 +08:00
|
|
|
|
2009-07-28 20:26:32 +08:00
|
|
|
class MarkHolder:
|
|
|
|
def __init__(self, kwargs):
|
|
|
|
self.__dict__.update(kwargs)
|
2009-06-28 19:19:43 +08:00
|
|
|
|
2009-07-28 20:26:32 +08:00
|
|
|
def test_pytest_mark_api():
|
|
|
|
mark = Mark()
|
|
|
|
py.test.raises(TypeError, "mark(x=3)")
|
2009-06-28 19:19:43 +08:00
|
|
|
|
2009-07-28 20:26:32 +08:00
|
|
|
def f(): pass
|
2009-06-28 19:19:43 +08:00
|
|
|
mark.hello(f)
|
2009-07-28 20:26:32 +08:00
|
|
|
assert f.hello
|
2009-06-28 19:19:43 +08:00
|
|
|
|
2009-07-28 20:26:32 +08:00
|
|
|
mark.world(x=3, y=4)(f)
|
|
|
|
assert f.world
|
|
|
|
assert f.world.x == 3
|
|
|
|
assert f.world.y == 4
|
2009-06-28 19:19:43 +08:00
|
|
|
|
2009-07-28 20:26:32 +08:00
|
|
|
py.test.raises(TypeError, "mark.some(x=3)(f=5)")
|
2009-06-28 19:19:43 +08:00
|
|
|
|
|
|
|
def test_mark_plugin(testdir):
|
|
|
|
p = testdir.makepyfile("""
|
|
|
|
import py
|
|
|
|
pytest_plugins = "keyword"
|
|
|
|
@py.test.mark.hello
|
|
|
|
def test_hello():
|
|
|
|
assert hasattr(test_hello, 'hello')
|
|
|
|
""")
|
|
|
|
result = testdir.runpytest(p)
|
|
|
|
assert result.stdout.fnmatch_lines(["*passed*"])
|