Ich teste die Integration eines Systems, indem ich nur die öffentlichen APIs verwende. Ich habe einen Test, der ungefähr so aussieht:
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...
Grundsätzlich versuche ich, den gesamten "Fluss" einer einzelnen Transaktion zu testen. Jeder Schritt im Ablauf hängt davon ab, ob der vorherige Schritt erfolgreich ist. Da ich mich auf die externe API beschränke, kann ich nicht einfach Werte in die Datenbank stecken.
Also, entweder habe ich eine wirklich lange Testmethode, die A macht; behaupten; B; behaupten; C; behaupten ... ", oder ich teile es in separate Testmethoden auf, wobei jede Testmethode die Ergebnisse des vorherigen Tests benötigt, bevor sie ihre Sache tun kann:
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.
Ich denke das riecht. Gibt es eine bessere Möglichkeit, diese Tests zu schreiben?
Ich würde den Testcode vom Setup-Code trennen. Vielleicht:
Denken Sie daran, alle Zufallsinformationen , die erzeugt wird , muss in der Behauptung , falls einbezogen werden es nicht, sonst wird Ihr Test nicht reproduzierbar sein kann. Ich könnte sogar den verwendeten Zufallssamen aufzeichnen. Wenn ein zufälliger Fall fehlschlägt, fügen Sie diese spezifische Eingabe als hartcodierten Test hinzu, um eine Regression zu verhindern.
quelle
Nicht viel besser, aber Sie können zumindest den Setup-Code vom Asserting-Code trennen. Schreiben Sie eine separate Methode, die die gesamte Geschichte Schritt für Schritt erzählt, und legen Sie mithilfe eines Parameters fest, wie viele Schritte ausgeführt werden sollen. Dann kann jeder Test so etwas wie
simulate 4
oder sagensimulate 10
und dann behaupten, was immer er testet.quelle
Nun, ich könnte die Python-Syntax hier nicht durch "Luftkodierung" erhalten, aber ich denke, Sie haben die Idee: Sie können eine allgemeine Funktion wie diese implementieren:
Damit können Sie Ihre Tests wie folgt schreiben:
Natürlich ist es fraglich, ob der Lesbarkeitsverlust dieses Ansatzes es wert ist, ihn zu verwenden, aber er reduziert den Code des Boilerplates ein wenig.
quelle