问题
Nose has a bug - test names created by generators are not cached, so the error looks like it happened in the last test, not the actual test where it failed. I got around it following the solution in the bug report discussion, but it only works for names shown on stdout, not in the XML report (--with-xunit)
from functools import partial, update_wrapper
def testGenerator():
for i in range(10):
func = partial(test)
# make decorator with_setup() work again
update_wrapper(func, test)
func.description = "nice test name %s" % i
yield func
def test():
pass
The output of nose is as expected, something like
nice test name 0 ... ok
nice test name 1 ... ok
nice test name 2 ... ok
...
But the test names in XML are just 'testGenerator'.
...<testcase classname="example" name="testGenerator" time="0.000" />...
How can I change this so that the personalized test names are shown on both stdout and XML output?
I'm using nosetests version 1.1.2 and Python 2.6.6
回答1:
You can change the way that Nose names tests by adding a plugin that implements describeTest
from nose.plugins import Plugin
class CustomName(Plugin):
"Change the printed description/name of the test."
def describeTest(self, test):
return "%s:%s" % (test.test.__module__, test.test.description)
You will then have to install this plugin, and enable it in the Nose invocation.
回答2:
You can add the following line.
testGenerator.__name__ = "nice test name %s" % i
Example:
from functools import partial, update_wrapper
def testGenerator():
for i in range(10):
func = partial(test)
# make decorator with_setup() work again
update_wrapper(func, test)
func.description = "nice test name %s" % i
testGenerator.__name__ = "nice test name %s" % i
yield func
def test():
pass
This will result in the names you want.
<testsuite name="nosetests" tests="11" errors="0" failures="0" skip="0"><testcase classname="sample" name="nice test name 0" time="0.000" />
回答3:
As Ananth mentions, you can use this.
testGenerator.__name__
You can also use this instead
testGenerator.compat_func_name
If your test class has arguments, I'd recommend currying them, as well as currying with_setup. Using lambda saves on the import, and I think it's a little cleaner. For example,
from nose.tools import with_setup
def testGenerator():
for i in range(10):
func = with_setup(set_up, tear_down)(lambda: test(i))
func.description = "nice test name %s" % i
testGenerator.compat_func_name = func.description
yield func
def test(i):
pass
def set_up():
pass
def tear_down():
pass
回答4:
If using nose and Eclipe's PyUnit:
import nose
class Test(object):
CURRENT_TEST_NAME = None
def test_generator(self):
def the_test(*args,**kwargs):
pass
for i in range(10):
# Set test name
Test.CURRENT_TEST_NAME = "TestGenerated_%i"%i
the_test.description = Test.CURRENT_TEST_NAME
# Yield generated test
yield the_test,i
# Set the name of each test generated
test_generator.address = lambda arg=None:(__file__, Test, Test.CURRENT_TEST_NAME)
which will cause the name to show up nicely in PyUnit as well.
来源:https://stackoverflow.com/questions/11189699/change-names-of-tests-created-by-nose-test-generators