2010-03-28 14 views
7

Mam problem z organizowaniem mojego testu klasy opartego na dla rodziny testów. Załóżmy na przykład, że zaimplementowałem interfejs "słownikowy" i mam do testowania 5 różnych implementacji.Przeróbki testowe ponownego użycia dla rodziny klas

Piszę jedną klasę testową, która testuje interfejs słownika. Ale jak mogę go ładnie wykorzystać, aby przetestować wszystkie moje zajęcia? Do tej pory mam brzydki:

DictType = hashtable.HashDict 

W górnej części pliku, a następnie użyć DictType w klasie testowej. Aby przetestować inną klasę, ręcznie zmieniam DictType na coś innego.

Jak można to zrobić inaczej? Nie można przekazać argumentów do klas unittest, więc czy istnieje lepszy sposób?

Odpowiedz

5

Sposób, w jaki radzę sobie ze standardem unittest, polega na podklasowaniu - przecież przesłanianie danych jest tak proste, jak nadpisywanie metod.

Tak, mam klasę bazową dla badań:

class MappingTestBase(unittest.TestCase): 
    dictype = None 
    # write all the tests using self.dictype 

i podklasy:

class HashtableTest(MappingTestBase): 
    dictype = hashtable.HashDict 

class OtherMappingTest(MappingTestBase): 
    dictype = othermodule.mappingimpl 

Tutaj podklasy musi zastąpić tylko dictype. Czasami wygodniej jest także odsłaniać MappingTestBase używając "metod haczyków". Gdy testowane typy nie mają dokładnie identycznych interfejsów we wszystkich przypadkach, można to obejść, ponieważ podklasy nadpisują metody haczykowe w razie potrzeby - jest to wzorzec projektowy "Szablon metody", zobacz np. this page który ma skomentowane i określone w czasie kolekcje kilku wykładów wideo na temat wzorców projektowych - część II dotyczy Metody Szablonów i jej wariantów przez około pierwsze 30 minut.

Oczywiście nie musisz mieć tego wszystkiego w jednym module (choć często wydaje mi się, że najłatwiej jest układać to w ten sposób, możesz także utworzyć osobny moduł testowy dla każdego testowanego typu, każdy moduł z abstrakcyjną klasą podstawową).

+0

oh, bardzo ładne, 10x alex – zaharpopov

+0

Próbuję użyć tego wzoru ale dostaję błędy (np. 'TypeError: 'Obiekt NoneType' nie jest wywoływalny), ponieważ framework' unittest' uruchamia testy w kontekście 'MappingTestBase' oraz klas pochodnych. Czy istnieje sposób, aby temu zapobiec? ? – user200783

+0

@PaulBaker, na pewno możesz zbudować zestaw testów, który chcesz uruchomić dość wyraźnie, np. Używając klasy 'TestLoader', zobacz https://docs.python.org/2/library/unittest.html#unittest.TestLoader , np. przez jego podklasę i nadpisanie 'getTestCaseNames', aby zwrócić' [] 'dla klas, których metody testowania nie chcesz uruchamiać, lub możesz udekorować wszystkie metody testowe, aby powrócić, jeśli' self.dicttype jest None '. podejścia działają dobrze. –

0

Można spojrzeć na testscenarios, która pozwala ustawić listę nazwaną scenariuszami. Następnie kod generuje wersję klasy testu dla każdej wartości/scenariusz na liście

Zobacz the example

Więc w przypadku scenariuszy byłaby lista jak [{dicttype: hashtable.HashDict}, {dicttype : otherimpl.class},] i użyj self.dicttype w kodzie testowym.

+0

oh, więc nie można tego zrobić przy standardowym unittest? bardzo rozczarowujące :-( – zaharpopov

+0

Jeszcze nie - zobacz http://www.voidspace.org.uk/python/articles/unittest2.shtml dla tego, co jest robione – Mark

Powiązane problemy