Nazwa testu ma znaczenie

Po nazwie powinniśmy dowiedzieć się co test robi. Dlatego dobra nazwa jest bardzo istotna. Jednak dobór właściwej wymaga praktyki. Długie nazwy typu: Given_WarunkiWstepne_When_CoSprawdzamy_Then_OczekwianyRezultat dobrze sprawdzają się przy testach integracyjnych. Krótkie nazewnictwo częściej stosuje się przy testach jednostkowych. Nadając dobre nazwy testom ułatwiamy sobie pracę. Jest prościej wrócić do kontekstu zadania po przerwie w programowaniu. W przypadku nieprzechodzenia testów jesteśmy w stanie prościej zidentyfikować na jaką część kodu wpłynęły najnowsze zmiany.

Spotkałem różne style nazewnictwa testów oto niektóre z nich:

  • CoSorawdzamy_OczekiwanyRezultat
  • NazwaMetody_CoSprawdzamy_OczekwianyRezultat
  • NazwaMetody_OczekiwanyRezultat_CoSprawdzamy
  • Should_OczekiwanyRezultat_When_CoSprawdzamy
  • FunkcjaDoPrzetestowania (np. IsNotAccesDeniedIfAgeOfUserLessThan18)
  • When_CoSprawdzamy_Then_NazwaMetody_Should_OczekiwanyRezultat
  • When_CoSprawdzamy_Expect_OczekiwanyRezultat
  • Given_WarunkiWstepne_When_CoSprawdzamy_Then_OczekwianyRezultat

Oczywiście te style nazewnictwa nie muszą zawierać „_”:

  • CoSorawdzamyOczekiwanyRezultat
  • NazwaMetodyCoSprawdzamyOczekwianyRezultat
  • NazwaMetodyOczekiwanyRezultatCoSprawdzamy
  • ShouldOczekiwanyRezultatWhenCoSprawdzamy
  • WhenCoSprawdzamyThenNazwaMetodyShouldOczekiwanyRezultat
  • WhenCoSprawdzamyExpectOczekiwanyRezultat
  • GivenWarunkiWstepneWhenCoSprawdzamyThenOczekwianyRezultat

Jak widać są od siebie znacząco różne.

Jaki styl nazewnictwa wybrać?

Najlepiej omówić z całą drużyną jakie nazewnictwo testów będzie obowiązywało w systemie. Jeżeli zespół nie jest jeszcze doświadczony w pisaniu testów automatycznych to polecam poeksperymentować z nazewnictwem i po pewnym czasie określić, który styl lub style najbardziej wam odpowiadają.

 

Budowa testu

Bardzo popularną koncepcją budowy testu jest Arrange-Act-Assert znany też jako Given-When-Then. Opracował ją Bill Wake. Zakłada ona podział struktury testu w następujący sposób:

  • Arrange tworzymy założenia wstępne naszego testu. Inicjalizujemy niezbędne obiekty, mocki potrzebne do wykonania testu.
  • Act uruchamia nam testowaną funkcjonalność.
  • Assert odpowiada za sprawdzenie warunków określających powodzenie testu.

 

Rys. 1. Podział testu Arrange-Act-Assert

Nie zawsze potrzebujemy części Arrange. Jednak w niektórych przypadkach podział testu na trzy fragmenty jest niewystarczający. Dzieje się tak w przypadku, gdy przeprowadzamy testy integracyjne. Potrzebna jest nam jeszcze dodatkowa faza testu, pozwalająca „posprzątać” testowe dane. Używamy wtedy wzorca Four-Phase test. Dzieli on test na następujące fazy:

  • Setup tworzymy założenia wstępne. Inicjalizujemy niezbędne obiekty, mocki potrzebne do wykonania testu.
  • Excercise w tej fazie wchodzimy w interakcje z SUT
  • Verify faza ta odpowiada za weryfikacje warunków określających powodzenie testu.
  • Teardown w ostatniej fazie przywracamy środowisko testowe do stanu w którym się znajdowało przed uruchomieniem testu.

Rys. 2. Podział testu Four-Phase

Wzorzec Four-Phase test jest bardzo zbliżony do Arrange-Act-Asseert. Mają one na celu zwiększenie czytelności testu. Dzięki ich zastosowaniu możemy łatwo rozpoznać co robi dany fragment kodu.

 

Źródła:

  • Tim Ottinger, Jeff Langr, Agile in a Flash: Speed-Learning Agile Software Development, Pragmatic Programers, LLC 2011
  • Gerard Meszaros, xUnit Test Patterns: Refactoring Test Code, Addison-Wesley Professional, 2007
  • Roy Osherove, Testy jednostkowe. Świat niezawodnych aplikacji. Wydanie II, Helion, 2014