2014-12-17 10 views
8

Piszę TestCase w Pythonie przy użyciu unittest, który wygląda mniej więcej tak:Jak mogę udekorować metodę unittest Pythona, aby pominąć, jeśli wcześniej oceniona właściwość nie jest prawdziwa?

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 

Jednak nie wydaje się działać, zakładam bo @skipIf nie można używać self poza ciałem deklaracji funkcji . Wiem, że mogę sprawdzić wartość self.isOnline w funkcji test_xyz i zamiast tego użyć skipTest, ale jest to mniej eleganckie. Czy są jakieś inne opcje?

+5

Używanie 'skipTest' wewnątrz nie jest _to złe. – dursk

Odpowiedz

4

Można napisać własny dekorator do którego podać nazwę z 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 

Następnie w swojej klasie byś zdefiniować metodę testową tak:

@skipIfTrue('isOnline') 
def test_thing(self): 
    print("A test") 

Decyduje, czy to jest lepsze, niż samo sprawdzenie metody zależy od sytuacji. Jeśli robisz to przy użyciu wielu metod, może to być lepsze niż zapisywanie każdego z nich. Z drugiej strony, jeśli to robisz, możesz je pogrupować i wykonać jedną kontrolę, aby pominąć cały pakiet.

+0

Dzięki. Myślę, że jest to nieco bardziej eleganckie niż inne rozwiązanie tutaj, więc zaznaczenie tego jest akceptowane. Oba są jednak dobre. –

+0

To świetnie, dzięki! – Ofer

3

Jeśli można przejść test isOnline poza metodę setUp, to jest to rozwiązanie:

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 

Inną (bardziej elegancki opcja) będzie wówczas:

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 

Jednak jeśli ten ISN możliwe, że nie ma bardziej eleganckiego rozwiązania, niż jakoś wykorzystać skipTest().

i skipUnless są oceniane w czasie deklaracji zajęć (ustawiają w metodzie atrybut __unittest_skip__, aby wskazać, że nie powinien być uruchamiany, co jest później analizowane przed rozpoczęciem testu). Twoja metoda setUp nie została jeszcze uruchomiona w tym momencie.

+0

Dzięki, dobra sugestia! –

0

Dodałbym do odpowiedzi przez BrenBarn że jeśli używasz nosetests że trzeba ozdobić funkcję wrapper z @wraps. Bez tego funkcja testowa mogłaby technicznie być wrapper i nie zostanie wywołana przez nosetests, ponieważ domyślnie metody testowe muszą zaczynać się od test_.

from unittest2.compatibility import wraps 

def skipIfTrue(flag): 
    def deco(f): 
     @wraps(f) 
     def wrapper(self, *args, **kwargs): 
      if getattr(self, flag): 
       self.skipTest() 
      else: 
       f(self, *args, **kwargs) 
     return wrapper 
    return deco 
Powiązane problemy