为[@ unittest.skipIf decorator]条件获取过时的值

时间:2012-05-09 21:35:25

标签: python unit-testing decorator

我刚遇到@unittest.skipIf(expression)的问题。好吧,问题是如果我在开始测试之前在声明器中使用变量并赋值,并且在测试期间更改了此变量的值,则效果使得decorator包含旧值。例如:

class Settings(object):
    flag=False
class TestCase(object):

    # during the test variable is changed (in this module or another)
    Settings.flag=True

    @unittest.skipIf(Settings.flag==True)
    def test_something(self):
        ...

Settings.flag的值可以在另一个模块或此模块中更改(这无关紧要)。在这两种情况下,在调用Setting.flag==True期间条件test_something仍然采用'False'值,尽管它已经更改为'True'值。这很奇怪,我承认我不明白这种机制是如何运作的。似乎在测试期间无法更改此装饰器中使用的值。也许还有一些其他有趣的方法可以在特定条件下跳过测试,这可能会在测试期间发生变化。有没有人知道如何处理这个问题?

1 个答案:

答案 0 :(得分:1)

是的,这是预期的行为。调用函数时会计算函数参数。装饰器是在定义装饰函数时调用的函数。因此,在定义修饰函数时测试标志。装饰者无法知道测试甚至是什么;它只会看到TrueFalse(或更可能是真实性或虚假性),因此无法将条件存储起来以供日后评估。

要使skipIf()能够正常工作,就需要使用函数(例如lambda: Settings.flag==True)而不是布尔值。然后,当实际调用修饰函数时,它将能够在以后评估此条件。但实际上并没有这样做。 (不过,这可能是一个很容易添加的增强功能。)

您可以通过在导入Settings.flag的值之后不导入包含单元测试的模块来解决此问题。这将推迟测试函数的定义(以及装饰)直到那时,装饰器将能够访问所需的标志值。不知道你的代码是如何构建的,我不知道这对你来说是否实用。

此外,有些事情看起来很可疑Settings.flag==True ......不能完全把手指放在上面......; - )