python nosetests setting the test description

2019-05-10 03:12发布

问题:

I'm creating tests on the fly (I must) in python to run with nosetests as below:

def my_verification_method(param):
    """ description """
    assert param>0, "something bad..."

def test_apps():
    """ make tests on the fly """
    param1 = 1
    my_verification_method.__doc__ = "test with param=%i" % param1
    yield my_verification_method, param1
    param1 = 2
    my_verification_method.__doc__ = "test with param=%i" % param1
    yield my_verification_method, param1

The problem is that that nosetest prints:

make tests on the fly ... ok
make tests on the fly ... ok

which is not what I want. I want the output of nosetests say:

test with param=1 ... ok
test with param=2 ... ok

Any ideas?

回答1:

Here is how to do what you want, but it will be bypassing yield test generation. In essence, you stuff on the fly a blank unittest.TestCase using populate() method below:

from unittest import TestCase

from nose.tools import istest


def my_verification_method(param):
    """ description """
    print "this is param=", param
    assert param > 0, "something bad..."


def method_name(param):
    """ this is how you name the tests from param values """
    return "test_with_param(%i)" % param


def doc_name(param):
    """ this is how you generate doc strings from param values """
    return "test with param=%i" % param


def _create(param):
    """ Helper method to make functions on the fly """

    @istest
    def func_name(self):
        my_verification_method(param)

    return func_name


def populate(cls, params):
    """ Helper method that injects tests to the TestCase class """

    for param in params:
        _method = _create(param)
        _method.__name__ = method_name(param)
        _method.__doc__ = doc_name(param)
        setattr(cls, _method.__name__, _method)


class AppsTest(TestCase):
    """ TestCase Container """

    pass

test_params = [-1, 1, 2]
populate(AppsTest, test_params)

You should get:

$ nosetests doc_test.py -v
test with param=-1 ... FAIL
test with param=1 ... ok
test with param=2 ... ok

You will need to change method name as well as doc string in order to populate your class properly.

EDIT: func_name should have self as an argument, since it is a class method now.