How can I decorate a Python unittest method to skip if a property I've previously evaluated isn't True?
You could write your own decorator to which you pass the name of the flag:
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
Then in your class you would define the test method like this:
@skipIfTrue('isOnline')
def test_thing(self):
print("A test")
Whether this is better than just checking in the method depends on the situation. If you are doing this with many methods, it could be better than writing the check in every one. On the other hand, if you're doing that, you might want to group them together and do one check to skip the entire suite.
If you can move the isOnline
test outside of your setUp
method, then that's a solution:
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
Another (more elegant option) would then be:
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
However if this isn't possible for you, then there isn't a more elegant solution than to somehow use skipTest()
.
skipIf
and skipUnless
are evaluated at class declaration time (they set a __unittest_skip__
attribute on your method to indicate it shouldn't run, which is later looked at prior to running the test). Your setUp
method just hasn't run yet at that point.