Testuję integrację systemu, używając tylko publicznych interfejsów API. Mam test, który wygląda mniej więcej tak:
def testAllTheThings():
email = create_random_email()
password = create_random_password()
ok = account_signup(email, password)
assert ok
url = wait_for_confirmation_email()
assert url
ok = account_verify(url)
assert ok
token = get_auth_token(email, password)
a = do_A(token)
assert a
b = do_B(token, a)
assert b
c = do_C(token, b)
# ...and so on...
Zasadniczo próbuję przetestować cały „przepływ” pojedynczej transakcji. Każdy krok w przepływie zależy od powodzenia poprzedniego kroku. Ponieważ ograniczam się do zewnętrznego interfejsu API, nie mogę po prostu wprowadzać wartości do bazy danych.
Tak więc albo mam jedną naprawdę długą metodę testową, która wykonuje `A; zapewniać; B; zapewniać; DO; asert ... ”, lub podzielę to na osobne metody testowe, gdzie każda metoda testowa potrzebuje wyników z poprzedniego testu, zanim będzie w stanie wykonać swoje zadanie:
def testAccountSignup():
# etc.
return email, password
def testAuthToken():
email, password = testAccountSignup()
token = get_auth_token(email, password)
assert token
return token
def testA():
token = testAuthToken()
a = do_A(token)
# etc.
Myślę, że to pachnie. Czy istnieje lepszy sposób na napisanie tych testów?
Oddzieliłbym kod testowy od kodu instalacyjnego. Być może:
Pamiętaj, że wszystkie generowane losowe informacje muszą być uwzględnione w twierdzeniu na wypadek, gdyby zakończyły się niepowodzeniem, w przeciwnym razie test może nie być odtwarzalny. Mogę nawet zapisać losowe użyte ziarno. Również za każdym razem, gdy przypadek nie powiedzie się, dodaj to konkretne wejście jako test zakodowany na stałe, aby zapobiec regresji.
źródło
Nie wiele lepiej, ale możesz przynajmniej oddzielić kod instalacyjny od kodu potwierdzającego. Napisz oddzielną metodę, która opowiada całą historię krok po kroku, i weź parametr kontrolujący, ile kroków powinna ona podjąć. Następnie każdy test może powiedzieć coś podobnego
simulate 4
lub,simulate 10
a następnie potwierdzić wszystko, co testuje.źródło
Cóż, może nie rozumiem tutaj składni Pythona przez „kodowanie powietrzne”, ale myślę, że masz pomysł: możesz zaimplementować taką ogólną funkcję:
co pozwoli Ci napisać swoje testy w ten sposób:
Oczywiście można dyskutować, czy warto skorzystać z utraty czytelności tego podejścia, ale nieco zmniejsza on kod płyty zbiorczej.
źródło