Python и нос: какова область видимости переменных в тестовом классе?

Я запускаю тесты с носом и хотел бы использовать переменную из одного элемента тестов в другом. Для этого я создаю переменную при настройке класса. Мне кажется, что переменная копируется для каждого элемента, поэтому та, что в классе, остается фактически нетронутой. Если вместо простой переменной я использую список, я вижу поведение, которое и ожидал.

Я написал небольшой пример, мы можем наблюдать, что var1 и varg всегда показывают одно и то же значение при входе в тест:

import time
import sys
import logging

logger = logging.getLogger('008')


class Test008:
    varg = None

    @classmethod
    def setup_class(cls):
        logger.info('* setup class')
        cls.var1 = None
        cls.list1 = []

    def setup(self):
        logger.info('\r\n* setup')
        logger.info('\t var1: {}, varg: {}, list: {}'.format(
            self.var1, self.varg, self.list1))

    def teardown(self):
        logger.info('* teardown')
        logger.info('\t var1: {}, varg: {}, list: {}'.format(
            self.var1, self.varg, self.list1))

    def test_000(self):
        self.var1 = 0
        self.varg = 0
        self.list1.append(0)
        pass

    def test_001(self):
        # Here I would like to access the variables but they still show 'None'
        self.var1 = 1
        self.varg = 1
        self.list1.append(1)
        pass

    @classmethod
    def teardown_class(self):
        logger.info('* teardown class')

Результат:

nose.config: INFO: Ignoring files matching ['^\\.', '^_', '^setup\\.py$']
* setup class
008_TestVars.Test008.test_000 ... 
* setup
     var1: None, varg: None, list: []
* teardown
     var1: 0, varg: 0, list: [0]
ok

008_TestVars.Test008.test_001 ... 
* setup
     var1: None, varg: None, list: [0]
* teardown
     var1: 1, varg: 1, list: [0, 1]
ok
* teardown class

----------------------------------------------------------------------

Есть ли способ перенести значения var1 и varg из одного теста в другой?


person Pierre    schedule 17.04.2015    source источник
comment
Прежде чем я отвечу на этот вопрос, скажите мне, почему вы хотите это сделать — если вы заставляете тесты полагаться на данные из предыдущих тестов, они не являются модульными тестами (что может быть хорошо), вам, вероятно, придется запускать их в известном порядке (что пропускает некоторые из тестов обратной связи могут дать вам. Почему вы чувствуете необходимость сделать это?   -  person doctorlove    schedule 17.04.2015
comment
Спасибо за быстрый ответ. Мне нужно повторить команду с теми же параметрами, чтобы убедиться, что она отклонена во второй раз. Поэтому я пишу тест второй раз с другим условием прохождения. Эта первая команда использует текущее время для заполнения одного из отправленных параметров. При отправке команды во втором тесте я хочу точно такой же параметр.   -  person Pierre    schedule 17.04.2015


Ответы (1)


В документах четко сказано

создается тестовый пример для запуска каждого метода со свежим экземпляром тестового класса.

Если вам нужно фактическое время для установки параметра тестируемой функции, почему бы не написать тест, который устанавливает состояние, вызывает вашу функцию один раз и утверждает, что она прошла успешно, затем вызывает ее снова и утверждает, если не удается?

def test_that_two_calls_to_my_method_with_same_params_fails(self):
    var1 = 1
    varg = 1
    assert myMethod(var1, varg)
    assert myMethod(var1, varg) == False

Я думаю, что это понятнее, потому что в одном тесте все состояния собраны вместе, и тесты можно запускать в любом порядке.

Вы можете утверждать, что это так, потому что вы пытались использовать метод установки. В документах также говорится

Тестовый модуль — это модуль Python, который соответствует регулярному выражению testMatch. Тестовые модули предлагают настройку и демонтаж на уровне модулей; определите метод setup, setup_module, setUp или setUpModule для установки, teardown, teardown_module или tearDownModule для разборки.

Итак, вне вашего класса есть

def setup_module()
    #bother now I need to use global variables
    pass
person doctorlove    schedule 18.04.2015
comment
Спасибо! Я выбрал yield, а не утверждение, чтобы увидеть результаты отдельно. - person Pierre; 20.04.2015