21

我认为我正在尝试做的事情相当简单。我想在测试设置函数中初始化几个变量,然后在用该设置修饰的测试函数中使用它们。以下简单示例说明了我的意思:

from nose.tools import *

def setup():
    foo = 10

def teardown():
    foo = None

@with_setup(setup, teardown)
def test_foo_value():
    assert_equal(foo, 10)

这导致:

$ nosetests tests/test_foo.py
E
======================================================================
ERROR: test_foo.test_foo_value
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/mtozzi/.virtualenvs/foo/local/lib/python2.7/site-packages/nose/case.py", line 197, in runTest
self.test(*self.arg)
  File "/home/mtozzi/code/foo/tests/test_foo.py", line 12, in test_foo_value
assert_equal(foo, 10)
NameError: global name 'foo' is not defined

----------------------------------------------------------------------
Ran 1 test in 0.006s

FAILED (errors=1)

使用旧的 unittest 风格,我可以将这些设置为测试类的实例变量,但我认为鼻子测试不需要你使用类。我还考虑将它们设置为包全局变量,但这似乎不是一个非常好的做法。我希望这样做有一些明显的我想念的东西。

4

2 回答 2

13

正如您对问题的评论已经建议的那样,只需切换到类并使用实例变量,例如self.foo. 这就是它应该做的方式。

如果您坚持不使用类,请尝试使用global变量。不过,你没有从我这里听到。

from nose.tools import *

foo = None

def setup():
    global foo  # Ugly.
    foo = 10

def teardown():
    global foo  # Ugly.
    foo = None

@with_setup(setup, teardown)
def test_foo_value():
    assert_equal(foo, 10)

第三种变体可能是为您的值使用字典。这稍微不那么难看,但非常笨拙:

from nose.tools import *

_globals = {'foo': None}

def setup():
    _globals['foo'] = 10

def teardown():
    _globals['foo'] = None

@with_setup(setup, teardown)
def test_foo_value():
    foo = _globals['foo']
    assert_equal(foo, 10)
于 2012-05-13T17:27:37.923 回答
2

我使用了一个自定义的 with_setup 装饰器,它使用了穷人的非本地:https ://gist.github.com/garyvdm/392ae20c673c7ee58d76

def setup():
    foo = 10
    return [foo], {}

def teardown(foo):
    pass

@with_setup_args(setup, teardown)
def test_foo_value(foo):
    nose.tools.assert_equal(foo, 10)

对于仅 Python 3 的项目,我使用非本地而不是 .extend/.update 作为参数,kwargs。

于 2014-05-12T19:27:43.010 回答