6

我目前正在使用鼻子编写一些功能测试。我正在测试的库操纵目录结构。

为了获得可重现的结果,我存储了一个测试目录结构的模板,并在执行测试之前创建了一个副本(我在测试setup函数中执行此操作)。这确保了我在测试开始时总是有一个明确定义的状态。

现在我有两个进一步的要求:

  1. 如果测试失败,我希望它操作的目录结构不要被覆盖或删除,以便我可以分析问题。
  2. 我希望能够并行运行多个测试。

这两个要求都可以通过为每个执行的测试创建一个具有不同名称的新副本来解决。出于这个原因,我想访问setup函数中当前执行的测试的名称,以便我可以适当地命名副本。有什么办法可以做到这一点?

一个说明性的代码示例:

def setup_func(test_name):
    print "Setup of " + test_name

def teardown_func(test_name):
    print "Teardown of " + test_name

@with_setup(setup_func, teardown_func)
def test_one():
    pass

@with_setup(setup_func, teardown_func)
def test_two():
    pass

预期输出:

Setup of test_one
Teardown of test_one
Setup of test_two
Teardown of test_two

将名称作为参数注入将是最好的解决方案,但我也愿意接受其他建议。

4

3 回答 3

9

听起来像self._testMethodNameself.id ()应该适合你。这些是unittest.TestCase类的属性和方法。例如:

from django.test import TestCase


class MyTestCase(TestCase):
    def setUp(self):
        print self._testMethodName
        print self.id()

    def test_one(self):
        self.assertIsNone(1)

    def test_two(self):
        self.assertIsNone(2)

印刷:

...
AssertionError: 1 is not None
-------------------- >> begin captured stdout << ---------------------
test_one
path.MyTestCase.test_one

--------------------- >> end captured stdout << ----------------------
...
AssertionError: 2 is not None
-------------------- >> begin captured stdout << ---------------------
test_two
path.MyTestCase.test_two

--------------------- >> end captured stdout << ----------------------

另见:

希望有帮助。

于 2013-05-23T09:56:54.740 回答
2

我有一个适用于测试功能的解决方案,使用自定义装饰器:

def with_named_setup(setup=None, teardown=None):
    def wrap(f):
        return with_setup(
            lambda: setup(f.__name__) if (setup is not None) else None, 
            lambda: teardown(f.__name__) if (teardown is not None) else None)(f)
    return wrap

@with_named_setup(setup_func, teardown_func)
def test_one():
    pass

@with_named_setup(setup_func, teardown_func)
def test_two():
    pass

这重用了现有的with_setup装饰器,但将装饰函数的名称绑定到作为参数传递的setup和函数。teardown

于 2013-05-23T10:05:33.987 回答
1

如果您不想继承unittest.TestCase或使用自定义装饰器(如其他答案中所述),您可以通过挖掘调用堆栈来获取信息:

import inspect

def get_current_case():
    '''
    Get information about the currently running test case.

    Returns the fully qualified name of the current test function
    when called from within a test method, test function, setup or 
    teardown.

    Raises ``RuntimeError`` if the current test case could not be
    determined.

    Tested on Python 2.7 and 3.3 - 3.6 with nose 1.3.7.
    '''
    for frame_info in inspect.stack():
        if frame_info[1].endswith('unittest/case.py'):
            return frame_info[0].f_locals['self'].id()
    raise RuntimeError('Could not determine test case')
于 2017-05-25T16:21:10.523 回答