如果我之前评估的属性不是True,我如何装饰Python unittest方法?

And*_*ier 13 python unit-testing

我正在使用unittest在Python中编写一个TestCase ,看起来像这样:

class MyTestCase(unittest.TestCase):
  def setUp(self):
    # ... check if I'm online - might result in True or False
    self.isOnline = True

  @unittest.skipIf(not self.isOnline, "Not online")
  def test_xyz(self):
    # do a test that relies on being online
Run Code Online (Sandbox Code Playgroud)

但是,这似乎@skipIf没有用,我假设因为不能self在函数声明体外使用.我知道我可以检查函数self.isOnline内部的值而不是test_xyz使用skipTest,但这不太优雅.还有其他选择吗?

Bre*_*arn 13

您可以编写自己的装饰器,并将标志名称传递给它:

def skipIfTrue(flag):
    def deco(f):
        def wrapper(self, *args, **kwargs):
            if getattr(self, flag):
                self.skipTest()
            else:
                f(self, *args, **kwargs)
        return wrapper
    return deco
Run Code Online (Sandbox Code Playgroud)

然后在你的课上你将定义测试方法,如下所示:

@skipIfTrue('isOnline')
def test_thing(self):
    print("A test")
Run Code Online (Sandbox Code Playgroud)

这是否比仅仅检查方法更好取决于具体情况.如果您使用多种方法执行此操作,则可能比在每个方法中编写检查更好.另一方面,如果您这样做,您可能希望将它们组合在一起并进行一次检查以跳过整个套件.


Tho*_*zco 5

如果您可以将isOnline测试移出setUp方法之外,那么这是一个解决方案:

IS_ONLINE = i_am_online()

class MyTestCase(unittest.TestCase):
  @unittest.skipUnless(IS_ONLINE, "Not online")
  def test_xyz(self):
    # do a test that relies on being online
Run Code Online (Sandbox Code Playgroud)

另一个(更优雅的选择)将是:

import unittest

def skipWhenOffline():
    if not i_am_online():
         return unittest.skip("Not online")
    return unittest._id

class MyTestCase(unittest.TestCase):
  @unittest.skipWhenOffline()
  def test_xyz(self):
    # do a test that relies on being online
Run Code Online (Sandbox Code Playgroud)

但是,如果您无法做到这一点,那么没有比使用更加优雅的解决方案了skipTest()

skipIfskipUnless在类声明时进行评估(它们__unittest_skip__在您的方法上设置了一个属性以指示它不应该运行,稍后将在运行测试之前进行查看)。您的setUp方法当时还没有运行。