I got this working with nose2 using the nose2 attrib plugin for detection and some code copied from the nose1 attrib plugin that allowed me to decorate my tests.
Using the nose2 attrib plugin
You will see the nose2 attrib plugin , which allows you to define custom attributes for test functions and classes.
For this to work, you must specify the attributes of the tests after defining the test function.
class MyTestCase(unittest.TestCase): def test_function(self): self.assertEqual(1+1, 2) test_function.custom_attr1 = True test_function.custom_attr2 = ['foo', 'bar']
You can then run the filtered test suite by specifying -A or --attribute as the --attribute command line nose2 to display the attributes you need to map to your test suite. You can even use the -E or --eval-attribute command-line argument , which allows more complex Python expressions to match test attributes.
eg. nose2 -v -A custom_attr1
will run all tests that have custom_attr1 specified with the truth .
Using decorators to specify test attributes
This was not enough for me because I did not like the idea of ββdefining these attributes on tests after they were defined. I wanted to use a decorator instead, but nose2 did not have a built-in decorator for this.
I went to the source code of nose1 for my attrib plugin and copied the source for the attr function.
def attr(*args, **kwargs): """Decorator that adds attributes to classes or functions for use with the Attribute (-a) plugin. """ def wrap_ob(ob): for name in args: setattr(ob, name, True) for name, value in kwargs.iteritems(): setattr(ob, name, value) return ob return wrap_ob
I put this in the test/attrib_util.py . Now I can specify the attributes using the decorator. My source code for the test class above can be converted to (IMO) easier:
from test.attrib_util import attr class MyTestCase(unittest.TestCase): @attr('custom_attr1', custom_attr2=['foo', 'bar']) def test_function(self): self.assertEqual(1+1, 2)
You will notice that attributes can be specified as args or kwargs; all args will get the default value True .
You can also use this attr decorator in a test class or base class, and the attributes will apply to all test functions defined internally. This makes it very easy to separate the unit and functional tests.
from test.attrib_util import attr @attr('functional') class FunctionalTestCase(unittest.TestCase): pass class MyFunctionalCase(FunctionalTestCase): def test_function(self): print 'this will be considered a "functional" test function'