Czym właściwie jest Spock?

Artykuł ten jest wstępem do większej serii.

Wyobraźcie sobie świat, gdzie dokumentacja i kod to jedno. Gdzie wymagania biznesu są kompilowane i jesteś pewny, że są spełnione. Świat, w którym kod piszesz jak tekst i nie musisz go odkodowywać. No właśnie! Piękna idea. Narzędzie, które wam dzisiaj przedstawię, bardzo przybliża nas do niej.
Przed wami - Mr. Spock!


Od jakiegoś czasu używam do swoich testów Spocka. Postanowiłem się z wami podzielić swoimi przemyśleniami na jego temat.

Czym jest Spock?

Spock jest to framework testowania oraz specyfikacji dla Javy i Grooviego. Używa on runnera Junit’a, więc jest kompatybilny z wieloma fajnymi narzędziami CI oraz IDE.

Po co się go uczyć?

Spock jest to świetnie napisane narzędzie, którego celem jest zastosowanie BDD w nieco inny sposób, niż dotychczasowe rozwiązania nam oferowały. Dzięki Spockowi możemy pisać specyfikacje w kodzie i mieć tylko jedno miejsce do utrzymania go.

Jakie ma zalety?

Spock (dzięki użyciu Grooviego) usuwa dużo narzutów Javy. Umożliwia to pisanie kodu bardziej czytelnego. Ponieważ pamiętajmy — częściej czytamy kod, niż go piszemy.

Jak wygląda przykładowy test?

class SomeGreatFeatureSpec extends Specification{  //1
   
   def "should add two numbers correctly"(){ //2 
      expect:       //3
         2+3 == 5   //4
   }
}
  1. Każda klasa testowa musi rozszerzać klasę Specification.
  2. Metody w Spocku mogą być definiowane jako zwykłe Stringi. Dzięki temu raporty są o wiele bardziej czytelne.
  3. Cykl życia spocka składa się z wielu labelek. Jedną z nich jest expect.
  4. W spocku nie musisz robić assertów znanych nam z Javy. Wystarczy, że wyrażenie można ewaluować do booleana.
Jak widzicie, nie musimy użerać się z problemami „Kebab case czy snake case?” – po prostu użyjmy stringa jako nazwy metody. Kolejnym świetnym feature’em spocka jest możliwość pisania assertów bez dodatkowych narzędzi. Wystarczy, że kompilator zrozumie wyrażenie i uzna je za boolean. A to dopiero wierzchołek góry lodowej, który pozwoliłem sobie ujawnić. Im wejdziemy dalej, tym będzie ciekawiej.

Ale jak zacząć?

Wystarczy jedna dependencja w pomie, abyś pisał testy w spocku.

<dependency>
    <
groupId>org.spockframework</groupId>
    <
artifactId>spock-core</artifactId>
    <
version>1.1-groovy-2.4</version>
    <
scope>test</scope>
</
dependency>
Oczywiście należy również pamiętać o konfiguracji mavena (założyłem, że korzystamy z niego), aby odpalał pliki testowe. Poniższy plugin wrzucony do poma odpali pliki Spocka oraz Javy do testów.

<plugin>
    <
groupId>org.apache.maven.plugins</groupId>
    <
artifactId>maven-surefire-plugin</artifactId>
    <
version>2.18.1</version>
    <
configuration>
        <
includes>
            <
include>**/*Tests.java</include>
            <
include>**/*Spec.java</include>
        </
includes>
    </
configuration>
</
plugin>

Terminologia

Aby zrozumieć, jak działa Spock i dlaczego tak działa, musimy najpierw zrozumieć terminologię.
Spock pozwala nam napisać specyfikację, która opisuje jakieś feature’y części systemu. Częścią systemu, która może nas interesować, może być klasa lub też cała aplikacja. W dokumentacji Spocka można spotkać się z określeniem system under specification (SUS), która opisuje właśnie tą testowaną część systemu. Opis danego feature zaczyna się od pewnego stanu SUS i połączonych z nim systemów/modułów/portów. Taki snapshot stanu systemu nazywa się feature fixture.

Jak nazwać klasę testującą?

Często spotykałem się z podejściem, aby pisać *Spec. Dokumentacja Spocka nie narzuca tego podejścia nigdzie:
For example, CustomerSpec, H264VideoPlayback, and ASpaceshipAttackedFromTwoSides are all reasonable names for a specification.
Oczywiście założenie *Spec jest wzięte z konfiguracji mavena.

Co się stanie jak zepsuje test?

Wyobraźmy sobie sytuację, że programista piszący dany test, przespał spotkanie z biznesem i napisał taki test.

class SomeGreatFeatureSpec extends Specification{  
   
   def "should add two numbers correctly"(){ 
      expect:       
         2+3 == 6   
   }
}

Gdy odpalimy test, na monitorze pojawi się komunikat:


Czy ktoś z was tęskni za assertami z junita? No właśnie.

Ten artykuł ma rozbudzić w Tobie, drogi czytelniku, chęć nauki Spocka. W kolejnych artykułach będziemy wchodzić coraz to głębiej w dokumentację i zobaczymy, jak dobrym narzędziem jest Spock.


Live long and prosper!

Komentarze

  1. Dzięki! Przeczytałem z zainteresowaniem. Porównałem ze swoim tekstem, czy nie robię większych błędów i chyba nie (jakby co, wyprowadź mnie z błędu).

    Czekam na dalszy ciąg!

    OdpowiedzUsuń
  2. Dodaj w pom plugin gmavenplus-plugin bo nie zadziała

    OdpowiedzUsuń
    Odpowiedzi
    1. I tak i nie.

      Sprawdziłem to co napisałeś i rzeczywiście np. w spring bootowych aplikacjach poniżej 2.0 wymagany jest ten plugin i również jest wymagana dependencja groovy-all.

      W czystym projekcie maven'owym(przed chwilą stworzonym przez intellij) dependencje z tekstu wystarczą aby paczka się zbudowała.

      Napisz mi proszę dla jakiego projektu spotkałeś się z wymogiem gmavenplus ponieważ to może być ciekawy case, który ominąłem.

      Pozdrawiam,

      Usuń

Prześlij komentarz