Obecnie mam kilka testów jednostkowych, które mają wspólny zestaw testów. Oto przykład:
import unittest
class BaseTest(unittest.TestCase):
def testCommon(self):
print 'Calling BaseTest:testCommon'
value = 5
self.assertEquals(value, 5)
class SubTest1(BaseTest):
def testSub1(self):
print 'Calling SubTest1:testSub1'
sub = 3
self.assertEquals(sub, 3)
class SubTest2(BaseTest):
def testSub2(self):
print 'Calling SubTest2:testSub2'
sub = 4
self.assertEquals(sub, 4)
if __name__ == '__main__':
unittest.main()
Wynik powyższego to:
Calling BaseTest:testCommon
.Calling BaseTest:testCommon
.Calling SubTest1:testSub1
.Calling BaseTest:testCommon
.Calling SubTest2:testSub2
.
----------------------------------------------------------------------
Ran 5 tests in 0.000s
OK
Czy istnieje sposób na przepisanie powyższego, aby testCommon
nie było wywoływane pierwsze ?
EDYCJA: Zamiast uruchamiać 5 testów powyżej, chcę, aby uruchamiał tylko 4 testy, 2 z SubTest1 i kolejne 2 z SubTest2. Wygląda na to, że Python unittest samodzielnie uruchamia oryginalny BaseTest i potrzebuję mechanizmu, aby temu zapobiec.
python
unit-testing
testing
Thierry Lam
źródło
źródło
Odpowiedzi:
Użyj dziedziczenia wielokrotnego, aby Twoja klasa z typowymi testami sama nie dziedziczyła po TestCase.
źródło
setUp
itearDown
metody doCommonTests
klasy i chcesz, aby były wywoływane dla każdego testu w klasach pochodnych, musisz odwrócić kolejność klas bazowych, tak, że będzie:class SubTest1(CommonTests, unittest.TestCase)
.unittest.TestCase
iCommonTests
. Myślę, żesetUpClass
poniższa metoda jest najlepsza i jest mniej podatna na błędy ludzkie. Albo to, albo zawinięcie klasy BaseTest w klasę kontenera, która jest nieco bardziej zmyślona, ale pozwala uniknąć komunikatu o pomijaniu na wydruku przebiegu testowego.CommonTests
metody, które nie istnieją w tej klasie.Nie używaj dziedziczenia wielokrotnego, bo ugryzie Cię to później .
Zamiast tego możesz po prostu przenieść swoją klasę bazową do oddzielnego modułu lub opakować ją pustą klasą:
Wyjście:
źródło
Możesz rozwiązać ten problem za pomocą jednego polecenia:
Więc kod wyglądałby tak:
źródło
self.assert*
metody nie istnieją w standardowym obiekcie.super( BaseTest, cls ).setUpClass( )
BaseTest
można odwoływać się przez podklasysuper(self.__class__, self)
lub tylkosuper()
w podklasach, chociaż najwyraźniej nie, jeśli masz dziedziczyć konstruktory . Może jest też taka „anonimowa” alternatywa, gdy klasa bazowa musi się odwoływać (nie mam pojęcia, kiedy klasa musi odwoływać się do siebie).Odpowiedź Matthew Marshalla jest świetna, ale wymaga dziedziczenia z dwóch klas w każdym z przypadków testowych, co jest podatne na błędy. Zamiast tego używam tego (python> = 2.7):
źródło
Co próbujesz osiągnąć? Jeśli masz wspólny kod testowy (potwierdzenia, testy szablonów itp.), Umieść je w metodach, które nie są poprzedzone prefiksem,
test
więcunittest
ich nie załaduje.źródło
Odpowiedź Matthew to ta, której potrzebowałem, ponieważ wciąż jestem na 2.5. Ale od wersji 2.7 możesz używać dekoratora @ unittest.skip () na dowolnych metodach testowych, które chcesz pominąć.
http://docs.python.org/library/unittest.html#skipping-tests-and-expected-failures
Aby sprawdzić typ podstawowy, musisz zaimplementować własny dekorator pomijający. Nie korzystałem wcześniej z tej funkcji, ale na myśl możesz użyć BaseTest jako typu markera do warunkowania przeskoku:
źródło
Sposób, w jaki myślałem o rozwiązaniu tego problemu, polega na ukryciu metod testowych, jeśli używana jest klasa bazowa. Dzięki temu testy nie są pomijane, więc wyniki testów mogą być zielone zamiast żółtego w wielu narzędziach do raportowania testów.
W porównaniu z metodą mixin, idee, takie jak PyCharm, nie będą narzekać, że w klasie bazowej brakuje metod testów jednostkowych.
Jeśli klasa bazowa dziedziczy po tej klasie, będzie musiała zastąpić metody
setUpClass
itearDownClass
.źródło
Możesz dodać
__test_ = False
klasę BaseTest, ale jeśli ją dodasz, pamiętaj, że musisz dodać__test__ = True
klasy pochodne, aby móc uruchamiać testy.źródło
Inną opcją jest niewykonanie
Zamiast tego możesz użyć
Więc wykonujesz testy tylko w klasie
TestClass
źródło
unittest.main()
zbierane w domyślnym zestawie, tworzysz jawny zestaw i uruchamiasz jego testy.Zrobiłem mniej więcej to samo co @Vladim P. ( https://stackoverflow.com/a/25695512/2451329 ), ale nieco zmodyfikowałem:
i gotowe.
źródło
Począwszy od Pythona 3.2, możesz dodać test_loader do modułu, aby kontrolować, które testy (jeśli istnieją) są wyszukiwane przez mechanizm wykrywania testów.
Na przykład poniższe załadują tylko oryginalny plakat
SubTest1
iSubTest2
przypadki testowe, ignorującBase
:To powinno być możliwe do iteracyjnego
standard_tests
(aTestSuite
zawierający testy ładowarka domyślny znalezione) i skopiować wszystko, aleBase
abysuite
zamiast, ale zagnieżdżony charakterTestSuite.__iter__
powoduje, że dużo bardziej skomplikowane.źródło
Po prostu zmień nazwę metody testCommon na coś innego. Unittest (zwykle) pomija wszystko, co nie zawiera słowa „test”.
Szybko i prosto
źródło
To trochę stary wątek, ale dzisiaj natknąłem się na ten problem i pomyślałem o swoim własnym hacku. Używa dekoratora, który nadaje wartości funkcji None, gdy są dostępne za pośrednictwem klasy bazowej. Nie musisz martwić się konfiguracją i klasą konfiguracji, ponieważ jeśli klasa podstawowa nie ma testów, nie zostaną one uruchomione.
źródło
Zmień nazwę metody BaseTest na setUp:
Wynik:
Z dokumentacji :
źródło
setUp
?test...
metodę,setUp
jest wykonywana w kółko, raz na taką metodę; więc nie jest dobrym pomysłem umieszczanie tam testów!