Aby dać nieco wymyślony przykład, powiedzmy, że chcę przetestować, czy funkcja zwraca dwie liczby i że pierwsza jest mniejsza niż druga:
def test_length():
result = my_function()
assert len(result) == 2
def test_order()
a, b = my_function()
assert a < b
Tutaj, jeśli test_length
zawiedzie, to test_order
również zawiedzie. Czy najlepiej jest pisać test_length
, czy pomijać?
EDYCJA: zauważ, że w tej sytuacji oba testy są w większości niezależne od siebie, każdy może być uruchomiony w izolacji lub może być uruchomiony w odwrotnej kolejności, to nie ma znaczenia. Więc żadne z tych wcześniejszych pytań
- Jak powinienem przetestować funkcjonalność funkcji korzystającej z innych funkcji?
- Czy potrzebuję testu jednostkowego, jeśli mam już test integracyjny?
- Jak ustrukturyzować testy, w których jeden test jest konfiguracją innego testu?
- Jak zarządzać zależnością sukcesu między testami jednostkowymi
jest duplikatem powyższego.
unit-testing
Mihai
źródło
źródło
A
wywołaniaB
i wyniki zwracają ten sam wynik, powinieneś przetestować obaA
iB
”. Chodzi raczej o nakładanie się testów , a nie o testowane funkcje. (Chociaż jest to mylące, ponieważ obecnie są nazywane).lambda: type('', (), {'__len__': lambda self: 2})()
przejdzie pierwszy, ale nie drugi.Odpowiedzi:
Może być wartość, ale to trochę zapach. Albo twoje testy nie są dobrze izolowane (ponieważ
test_order
naprawdę testują dwie rzeczy) lub jesteś zbyt dogmatyczny w testowaniu (robienie dwóch testów testujących tę samą logiczną rzecz).W tym przykładzie połączę oba testy razem. Tak, oznacza to, że masz wiele twierdzeń. Szkoda Nadal testujesz jedną rzecz - wynik funkcji. Czasami w prawdziwym świecie oznacza to wykonanie dwóch kontroli.
źródło
my_function
nie zwróci dokładnie dwóch wartości, bez żadnego potwierdzenia - ponieważ przypisanie spowoduje wyjątek. Tak więc właściwie nie ma potrzeby używania wielu twierdzeń i dwóch kontroli, aby przetestować to samo.Twoje testy powinny być jednoznaczne. Nie jest do końca wywnioskowane, że jeśli długość_tekstu się nie powiedzie, test_order się nie powiedzie.
Nie jestem pewien, jak to wygląda w napisanym przez Ciebie języku Python, ale jeśli
len(result)
jest to 3, to pierwszy nie powiedzie się, ale drugi może przejść (a jeśli nie w Pythonie, to na pewno w językach takich jak JavaScript).Tak jak powiedziałeś, chcesz sprawdzić, czy funkcja zwraca dwie liczby i czy są w porządku. To dwa testy.
źródło
It's not completely inferred that if text_length fails test_order fails
- w Pythonie daje wyjątek.test_length
oznacza awariętest_order
. Fakt, że podobna para testów napisanych w Javascripcie nie zachowuje się tak samo jak te dwa testy Pythona, jest w pewnym sensie nieistotna.Jedyną wartością
test_length
tutaj jest to, że jeśli wszystko przeminie, sama jej obecność wskazuje, że „długość” została przetestowana.Tak więc naprawdę nie ma potrzeby posiadania obu tych testów. Zachowaj tylko,
test_order
ale rozważ zmianę nazwytest_length_and_order
.Nawiasem mówiąc, używam nazw, które zaczynają się
test
od nieco niezdarnego. Jestem zwolennikiem nazw testowych, które faktycznie opisują warunek, który twierdzisz.źródło
test
Brodawka jest sensowne ramy testowej Pythona. Co oczywiście nie musi zmieniać tego, czy jesteś jego fanem, ale zmienia wagę argumentu potrzebnego, aby ktoś przestał go używać ;-)test_that_
, jaktest_that_return_values_are_in_order
i tak dalej. Być może przyszła wersja środowiska testowego jakoś obejdzie ten wymóg.Te testy pozostawiłbym osobne, jeśli tak właśnie ewoluowały. Tak,
test_order
prawdopodobnie zawiedzie, gdytest_length
tak się stanie, ale na pewno wiesz, dlaczego.Zgadzam się również, że jeśli
test_order
pojawił się pierwszy i znalazłeś testowalną awarię, to wynik był prawdopodobnie nie dwóch wartości, dodając tę kontrolę jakoassert
i zmieniając nazwę testu, aby miećtest_length_and_order
sens.Gdybyście musieli również sprawdzić, czy typy zwracanych wartości są liczbami całkowitymi, uwzględnilbym to w tym teście wyników „zbiorczych”.
Ale zauważ, że teraz masz baterię testów na wynik
my_function()
. Jeśli istnieje wiele kontekstów (lub, co bardziej prawdopodobne, wiele parametrów) do przetestowania, może to być teraz podprogram do testowania wszystkich wynikówmy_function()
.Jednak kiedy piszę testy jednostkowe, zwykle testuję zbocze i złe przypadki oddzielnie od dobrego wejścia i normalnej wydajności (częściowo dlatego, że większość moich testów „jednostkowych” to często mini testy integracyjne) i często z wieloma twierdzeniami, które są tylko zepsute na osobne testy, jeśli zawiodą w sposób, w którym uważam, że chcę więcej informacji bez debugowania.
Prawdopodobnie zacznę od twoich oddzielnych testów, a następnie rozwinię
test_length
jetest_length_and_types
i pozostawiętest_order
osobne, zakładając, że to drugie jest postrzegane jako „normalne przetwarzanie”.źródło