poniedziałek, 25 czerwca 2012

Organizacja Matcherów w testach

Bardzo krótkie wprowadzenie

Do niedawna sądziłem, że pojęcie "matchera" jest wszystkim znane ale przy okazji niedawnej prezentacji o testach mutacyjnych na naszym kochanym łódzkim JUGu okazało się, że część osób ta wiedza ominęła. W skrócie: standardowo w Junit można było napisać coś takiego :

assertEquals(resultDomainObject.getProstawaratosc1,prostawartosc)
assertEquals(resultDomainObject.getProstawaratosc2,prostawartosc)
assertEquals(resultDomainObject.getProstawaratosc3,prostawartosc)
assertEquals(resultDomainObject.getProstawaratosc4,prostawartosc)


Dzięki matcherom możemy przygotować sobie mechanizm do ładnego i zrozumiałego przedstawiania asercji.

assertThatIn(resultDomainObject).thereIsExpectedState().andSomeSomethingElseFulFillsCondition(condition)


Do wyboru z tego co wiem mamy dwie biblioteki:

Organizacja matcherów, która się nie sprawdziła

Początkowo wrzucaliśmy matchery obok testów co okazało się katastrofalnym pomysłem, gdyż nie dość, iż niejednokrotnie pisaliśmy te same matchery po dwa razy to tak naprawdę trudno było kontrolować co już zostało napisane a co jeszcze czeka na wyrzeźbienie.


Wyglądało to tak:
  • paczka1
    • test11
    • test12
    • matcher1
  • paczka2
    • test21
    • test22
    • matcher2


Organizacja matcherów, która może się sprawdzić

Zamiast doklejać matchery do testów dajmy im ich własne pakiety ładnie poukładane według funkcjonalności.
  • testy
    • paczkatestow1
    • paczkatestow2
    • paczkatestow3
  • matchery
    • funkcjonalnosc1
      • konkretnyMatcher1
        konkretnyMatcher2
    • funkcjonalnosc2
      • konkretnyMatcher3
        konkretnyMatcher4
    • Wspolne cegielki
      • cegielkaMatcher1
        cegielkaMatcher2
Na poniższym rysunku widzimy, że dana funkcjonalności ma swój własny i niepowtarzalny matcher, który jest zbudowany na bazie wspólnych, cegiełkowych matcherów :



Czy to dobre rozwiązanie? Czas pokaże.

Konkretny przykład

Poniższy rysunek przedstawia konkretną organizację matcherów w paczkach:



Wykorzystanie matchera wyższego poziomu w teście wygląda tak :

 

 assertThatOnBillingPageRepresentedBy(resultPage).inFirstRow().hasValue("NLD").inCountryCell();



Zaś zastosowanie matchera cegiełkowego do sprawdzania wartości w komórce tabeli wygląda tak: :

 

  assertThatInTableRowHtml(choosenRow).inCellNumber(CELL_NUMBER_OF_CITY).hasValue(expectedValueInCell);



I na końcu jest standard z FESTa :

 

 assertThat(cellText).isEqualTo(value);

4 komentarze:

  1. Przydał by się konkretny przykład.

    OdpowiedzUsuń
  2. Spoko, wrzucę jakiś kod po obiedzie

    OdpowiedzUsuń
  3. Fajnie, że wrzuciłeś baner mobilization na stronkę

    OdpowiedzUsuń
  4. Ok, dodałem przykład także cała koncepcja powinna być łatwiejsza do zrozumienia.

    @Mario - baner ładnie zlewa się z polami marichuany w tle.

    OdpowiedzUsuń