Append the nose @attr to the test name

2019-03-30 17:30发布

问题:

I am able to setup nose tests to run with the @attr tag. I am now interested in know if I can append to the end of the test name, the @attr tag? What we are trying to do is add a tag if our tests run into an issue and we write up a defect for it, we would then put the defect number as an @attr tag. Then when we run we could easily identify which tests have open defects against them.

Just wondering if this is even possible, and where to go to see how to set it up?

EDIT RESULTS RUNNING WITH ANSWER:

Test Results:

So I sort of know what is going on, if I have the @fancyattr() at the class level it picks it up and changes the name of the class. When I put the @fancyattr() at the test level it is not changing the name of the test, which is what I need for it to do.

For example - Changes the name of the class:

@dms_attr('DMSTEST')
@attr('smoke_login', 'smoketest', priority=1)
class TestLogins(BaseSmoke):

"""
Just logs into the system and then logs off
"""

def setUp(self):
    BaseSmoke.setUp(self)

def test_login(self):
    print u"I can login -- taking a nap now"
    sleep(5)
    print u"Getting off now"

def tearDown(self):
    BaseSmoke.tearDown(self)

This is what I need and it isn't working:

@attr('smoke_login', 'smoketest', priority=1)
class TestLogins(BaseSmoke):

    """
    Just logs into the system and then logs off
    """

    def setUp(self):
        BaseSmoke.setUp(self)

    @dms_attr('DMSTEST')  
    def test_login(self):
        print u"I can login -- taking a nap now"
        sleep(5)
        print u"Getting off now"

    def tearDown(self):
        BaseSmoke.tearDown(self)

Updated screenshot with what I am seeing with __doc__:

回答1:

Here is how to do it with args type attributes:

rename_test.py:

import unittest 
from nose.tools import set_trace

def fancy_attr(*args, **kwargs):
    """Decorator that adds attributes to classes or functions
    for use with the Attribute (-a) plugin. It also renames functions!
    """
    def wrap_ob(ob):
        for name in args:
            setattr(ob, name, True)
            #using __doc__ instead of __name__ works for class methods tests
            ob.__doc__ = '_'.join([ob.__name__, name])
            #ob.__name__ = '_'.join([ob.__name__, name])

        return ob

    return wrap_ob


class TestLogins(unittest.TestCase):
    @fancy_attr('slow')
    def test_method():
        assert True


@fancy_attr('slow')
def test_func():
    assert True

Running test:

$ nosetests rename_test.py -v
test_method_slow ... ok
test_func_slow ... ok

----------------------------------------------------------------------
Ran 2 tests in 0.003s

OK

EDIT: For xunit reporting to work, test renaming should take place before running the test. You can do it on import, here is untested hack showing how to do it:

rename_test.py:

import unittest 

def fancy_attr(*args, **kwargs):
    """Decorator that adds attributes to classes or functions
    for use with the Attribute (-a) plugin. It also renames functions!
    """
    def wrap_ob(ob):
        for name in args:
            setattr(ob, name, True)
            ob.__doc__ = '_'.join([ob.__name__, name])

        return ob

    return wrap_ob


class TestLogins(unittest.TestCase):
    @fancy_attr('slow')
    def test_method(self):
        assert True


def make_name(orig, attrib):
    return '_'.join([orig, attrib])

def rename(cls):
    methods = []
    for key in cls.__dict__:
        method = getattr(cls, key)
        if method:
            if hasattr(cls.__dict__[key], '__dict__'):
                if 'slow' in cls.__dict__[key].__dict__:
                    methods.append(key)

    print methods

    for method in methods:
        setattr(cls, make_name(method, 'slow'),  cls.__dict__[key])
        delattr(cls, method)


rename(TestLogins)

@fancy_attr('slow')
def test_func():
    assert True