Spock-Test-Formulierung – BDD-Stil

Mar 19 2023
Das Spock Framework wird für Behavioral Driven Development (BDD) verwendet. BDD stellt sicher, dass Tests für Menschen lesbar sind, sodass man sie ohne unbedingtes Eintauchen in den Code einfach lesen, schreiben und verwalten kann.

Das Spock Framework wird für Behavioral Driven Development ( BDD ) verwendet. BDD stellt sicher, dass Tests für Menschen lesbar sind, sodass man sie ohne unbedingtes Eintauchen in den Code einfach lesen, schreiben und verwalten kann. Die richtige Formulierung gewährleistet auch die Wiederverwendbarkeit, da man leicht erkennen kann, wann ein Teil des Testcodes (oder Anwendungscodes) an anderer Stelle wiederverwendet werden kann. Um dies sicherzustellen, sollten Tests in Form von Softwareanforderungen in natürlichen Sätzen formuliert werden.

Eine einfache Regel, um sicherzustellen, dass Ihr Test gut geschrieben ist, lautet:

Lesen Sie die Sätze in den Blöcken laut vor, mit Kommas nach jedem Block. Wenn der Satz grammatikalisch korrekt klingt und wie eine Standardsoftwareanforderung klingt, dann ist Ihr Test korrekt.

Fallstudie

Ein Test für die Funktion getUser() in einem Benutzerdienst. (Beachten Sie die fett gedruckten Schlüsselwörter)

Testname (Anforderung):

getUser sollte einen Benutzer zurückgeben, wenn ein Benutzer in der Benutzerdatenbank vorhanden ist

Testdetails (längere natürliche Satzdefinitionsanforderung)

Vorausgesetzt , dass das Repository einen Benutzer zurückgibt und der Detaildienst Benutzerdetails zurückgibt, sollte beim Aufruf von getUser ein gültiger Benutzer zurückgegeben werden .

Nachfolgend sind die Abschnitte aufgeführt, die einen Spock-BDD-Test bilden:

Testname

Testnamen sollten als Anforderungen geschrieben werden.

Stichwort: sollte

richtig: ✅

def "getUser should return a user when a user exists in the users db"
def "when a user exists in the db, getUser should return a user"

def "getUser returns user" //this is not describing what should happen
def "getUser test"
def "when user exists in db, getUser returns user"

Vorgegebene Blöcke sollten eine Aktion zum Einrichten der für den Test erforderlichen Daten darstellen. Verwenden Sie bestimmte Blöcke nicht nur zur Definition von Variablen und nicht zur Einrichtung von Daten. Wenn die Variablen nicht in den angegebenen Blöcken verwendet werden, können sie im when-Block definiert werden.

Stichwort: Wille

richtig: ✅

given: 'repository will return a user'
User user = User.builder().id(123).build()
1 * repository.findById(id) >> user
and:  'details service will return user details'
1 * detailsService.getUserDetails(id) >> userDetails

given: 'repository returns a user' //wrong tense
User user = User.builder().id(123).build()
given: 'user object' //this is not defining any data setup. this is simply a variable.
User user = User.builder().id(123).build()

Wann Blöcke die zu testende Aktion haben sollen.

Stichwort: ist

richtig: ✅

when: 'getUser is invoked'

when: 'call getUser'

Stichwort: sollte

Dann sollten Blöcke das erwartete Ergebnis angeben

richtig: ✅

then: 'user should be returned'

then: 'reponse is correct'
then: 'user returned is correct'
then: 'assert reponse is correct'