Подтвердить что ты не робот

Как я могу получить доступ к переменным, установленным в функции настройки nosetests python

Я думаю, что то, что я пытаюсь сделать, довольно просто. Я хочу инициализировать пару переменных в функции тестовой установки, а затем использовать их в тестовых функциях, которые украшены этой настройкой. Следующий тривиальный пример иллюстрирует, что я имею в виду:

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 я мог бы установить их как переменные экземпляра в тестовом классе, но я думал, что nosetests не требует, чтобы вы использовали классы. Я также рассматривал их как глобальные переменные пакета, но это не кажется ужасно хорошей практикой. Я надеюсь, что что-то очевидное мне не хватает для этого.

Заранее благодарим за помощь.

4b9b3361

Ответ 1

Как уже упоминалось в вашем вопросе, просто переключитесь на классы и используйте переменные экземпляра типа 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)

Ответ 2

Я использую custom with_setup decorator, который использует бедных mans nonlocal: 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)

Для проектов, которые только python3, я использую нелокальный, а не .extend/.update для args, kwargs.