Testowanie z framework’iem Spock

Coś mnie podkusiło… i jest Spock

Od jakiegoś czasu pracuje w projektach gdzie używa się spock’a. Czym jest nadmieniony spock? Nie jest to legendarny  pierwszy oficer gwiezdnej floty, ani nazwa związana z jakimiś tajemniczymi mocami. Spock jest framework’iem do testów w Javie. Dlaczego nie oswojony i szeroko używany JUnit? Głównie przez przejrzystość z jaką pisze się testy w spock’u, a także ze względu na jego możliwości. Mianowicie, nie trzeba dodatkowych zależności w postaci biblioteki obsługującej tzw. mock’owanie. Dodatkowo spock ma zaimplementowaną semantykę BDD i pozwala na dobre opisywanie etapów testowania.

Spock proszony na mostek!

Spok’a trzeba doinstalować do używanych bibliotek. Poniżej przedstawiam setup projektu zarządzanego maven (plik pom.xml)

….
   <build>
       <plugins>
           <plugin>
               <groupId>org.codehaus.gmavenplus</groupId>
               <artifactId>gmavenplus-plugin</artifactId>
               <version>1.5</version>
               <executions>
                   <execution>
                       <goals>
                           <goal>testCompile</goal>
                       </goals>
                   </execution>
               </executions>
           </plugin>
           <plugin>
               <artifactId>maven-surefire-plugin</artifactId>
               <configuration>
                   <useFile>false</useFile>
                   <includes>
                       <include>** / *Spec.java</include>
                   </includes>
               </configuration>
           </plugin>
       </plugins>
   </build>

   <dependencies>
       <dependency>
           <groupId>org.spockframework</groupId>
           <artifactId>spock-core</artifactId>
           <version>2.0-M4-groovy-3.0</version>
           <scope>test</scope>
       </dependency>
       <dependency>
           <groupId>org.spockframework</groupId>
           <artifactId>spock-junit4</artifactId>
           <version>2.0-M4-groovy-3.0</version>
       </dependency>
   </dependencies>
….

Po doinstalowaniu zależności jak i opisaniem procesu budowania narzędzia spock możemy przystąpić do pisania testów.

I gdzie ta Java??

Spok jest oparty o groovy, język podobnie jak Java używający JVM. Dzięki temu można skutecznie używać groovy’ego w obszarze aplikacji zbudowanej w Javie.

Aby skutecznie pracować, nie trzeba uczyć się całej semantyki języka groovy. Wystarczy poznać kilka różnic.

  • słowo kluczowe “def” – pozwala na definiowanie zarówno zmiennych, stałych jak i funkcji. Nie musimy przy tym podawać typu, jeżeli nie chcemy np.:

def number = 10def car = new Car(….)

Każdy test napisany w spock’u zaczyna się od frazy “def”:

def "should calculate correct number"() {
     //body testu
}


  • nie używamy średników na końcu linii kodu (tak jak to jest w Javie)

Java

int number = 10;

Groovy:

def number = 10

  • lista w Groovy’em jest oznaczona tak jak tablica w Javie

Groovy:
[objekt, objekt], [ ] itp

Java:
List<Object> emptyList()

Struktura testu w Spock’u

Każda klasa testu w spock’u rozszerza klasę Specification. Następnie każdy test zaczyna się od słowa kluczowego def, opisu i nawiasu wraz z blokiem kodu będącym jego ciałem.

Wewnątrz ciała definiujemy elementy testu w odpowiednich blokach. 

given: tutaj wpisujemy wartości będące danymi wejściowymi do testu

when: tutaj wykonuje się operacja uruchomienia testowanej funkcjonalnosci

then: w ostatnim bloku ustawiamy asercję.

Przykład:

class CalcSpec extends Specification {

   def "should calculate correct number"() {
       given:
           def number = 10
       when:
           def result = number * 2
       then:
           result == 20
   }
}

Spock: Tutaj źle zrobiłeś!!!

Spock jest przeze mnie cenionym narzędziem jeszcze z jednego powodu.
To, w jak przejrzysty sposób informuje o błędzie, pozwala natychmiast zrozumieć istotę problemu.

W powyższym przykładzie zmieniłem asercję result == 20 na result == 12 (oczywiście błędną). W rezultacie w konsoli otrzymałem następującą informację:

result == 12
|      |
20     false

at CalcSpec.should calculate correct number(CalcSpec.groovy:11)

Pięknie, prawda??

Zmienne warunki mi nie straszne

Spock daje świetne możliwości, gdy chcemy testować zmieniający się parametr w obrębie tej samej funkcjonalności. Nie musimy tworzyć kilku nowych testów, wystarczy napisać jeden i go sparametryzować. Do tego celu użyjemy jeszcze jednego elementu w ciele testu i jest nim blok where:. Następujące po sobie parametry rozdzielamy znakiem |. Kolejne przypadki testowe uruchamiane są z parametrami znajdującymi się w jednym wierszu, linii bloku where

def "should calculate correct number"() {
   given:
       def number = 10
   when:
       def result = number * multiplier // parametr
   then:
       result == expectedResult // parametr
   where:
       multiplier | expectedResult
       2             | 20
       3             | 30
       1             | 10
}

Zakończenie

To niezbędne podstawy prostego testowania w framework’u spock. Mam nadzieję, że Cię zachęciłem do używania tego narzędzia lub chociaż do jego przetestowania
w Twoim projekcie. Jeżeli chcesz zgłębić temat i zdobyć większą ilość wiedzy na temat spocka zachęcam do odwiedzenia strony domowej tego framework’a.

Zapraszam do komentowania. Do zobaczenia w kolejnym wpisie.

2 myśli na temat “Testowanie z framework’iem Spock

    • admin Odpowiedz

      Hej Mariusz, dzięki wielkie za komentarz. Spock jest naprawdę wygodnym i prostym w użyciu narzędziem. Oczywiście wymaga chwili przyzwyczajenia do zasad pracy z nim. Odwdzięcza się przejrzystością oraz łatwością z jaką można pisać testy. Osobiście w tej chwili pracuje nad sporym projektem, który cały obtestowany jest właśnie spock’iem.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *