Dobra, wracamy do testowania! :) oj jak dobrze. Dziś trochę o konfiguracji – czyli co możemy zrobić z tymi testami i do jakich potrzeb możemy je nagiąć jeżeli trzeba :)
Konfiguracja
ExUnit przypomina mi trochę nUnit dając możliwość określenia dwóch metod setup
jak i metody tear down – on_exit
. Z dwóch dostępnych metod setup
jedna jest wykonywana raz na wszystkie testy w danym module, druga co każde wykonanie testu. Dzięki czemu możemy skonfigurować testy lub przekazać zunifikowane wartości do wszystkich testów.
Metody setup
Obydwie metody setup mają takie same przeciążenia:
- Mogą nie przyjmować żadnego parametru
- Przyjmują parametr
context
- Mogą w prosty sposób delegować wykonanie do innej metody
Trzy przypadki:
setup do end setup context do end setup: my_setup defp my_setup do end
Także parametry zwracane są takie same w obu przypadkach:
{:ok, [ lista_keywords ]}
Gdzie lista keywords jest opcjonalna, ale wszystko to co zostanie w niej zwrócone zostanie dodane do context. Czyli:
{:ok, [my_num: [1,2,3]]}
Doda do context klucz :my_num
który zwróci nam listę [1,2,3]
.
Jednak, lista keywords jest opcjonalna i równie dobrze, możemy zwrócić z metod :ok
. Pozostawienie metod setup bez zwracania niczego, lub zwrócenie czegoś innego niż :ok
czy lista keywords spowoduje automatyczny fail wszystkich testów. Więc jak już korzystacie z uprzejmości metod setup, to pamiętajcie o tym małym fakcie.
Jak możemy skorzystać z danych kontekstowych?
Do każdej metody test, przekazywany jest context jeżeli tego chcemy. Każdy test możemy napisać tak:
test "NAME" do assert true end
Jak i:
test "NAME", context do assert true end
Do context zaś dopieramy się tak jak do listy słów kluczowych:
context[:one] context[:two]
on_exit
on_exit
umożliwia nam czyszczenie czegokolwiek co chcemy wyczyścić w po każdym teście lub po wszystkich testach. Jest on definiowany jako callback w metodzie setup
lub setup_all
i jest on zawsze wykonany niezależnie od tego czy metody setup
się wywalają.
setup do on_exit fn -> IO.puts "setup_on_exit" end end setup_all do on_exit fn -> IO.puts "setup_on_exit" end end
Grupowanie testów i filtrowanie
describe
Testy, możemy pogrupować sobie w logiczną całość za pomocą bloku describe
który wygląda mniej więcej tak:
describe "moje super testy" do test "moj super test 1" do end test "moj super test 2" do end end
Oprócz wizualnego podziału umożliwia nam posiadanie odrębnych metod setup
. Dodatkowo może być wykorzystane w trakcie uruchamiania testów do ich filtrowania. Na przykład możemy odpalić tylko testy z danego describe
:
mix test --only describe:"NAME"
Tagowanie metod
Inna forma targetowania testów lub ich grupowania to tagowanie. Każdy test może zawierać tag
– tak to takie key, value. Zarówno umożliwia nam filtrowanie, jak i dodaje dane wartości do context
:
@tag key: 1 test "setup" do end
Teraz nasz kontekst będzie zawierał klucz :key
o wartości 1
i będziemy mogli to wykorzystać w testach albo w setup. Ale też możemy to filtrować:
mix test --include key:1
Tagowanie modułów
Możemy też grupować cały moduł pod @moduletag
. Działa to dosłownie tak samo jak w przypadku tagów dla testów, tylko, że zamiast być określane co metodę, jest raz, per cały defmodule
.
Tagowanie modułów ma mniejszy priorytet niż tagowanie metod. Czyli jeżeli ten sam klucz zostanie użyty to wartość jego z poziomu metody będzie miała pierwszeństwo.
Parametry wywołania
Oprócz już wspomnianych opcji --include
i --only
mamy jeszcze opcję --exclude
, kóra umożliwa nam wyłączenie pewnych testów z wykonania.
Dokładnie mówiąc, jeżeli robimy opcję --only
to wykonujemy polecenie:
mix test --include ONLY --exclude test
Gdzie ONLY
to tag/fitlr który chcemy by był wykonany.
Odpal tylko te testy które się zmieniły
Osobny punkt, bo jest to dość ważna opcja. Kiedy piszemy duże aplikacje testów możemy mieć setki albo tysiące. Jeżeli za każdym razem byśmy odpalali wszystkie testy to prędzej czy później moglibyśmy pewnie iść na kawę.
Dlatego też mix
wprowadził opcję --stale
, która generuje za pierwszym razem manifest dzięki któremu później mix
patrzy czy ma wykonać test czy też nie. Jedyny minus tego, wystarczy dodać spację do pliku i już ponownie testy zostaną wykonane.
Ale opcja jest, i to się liczy :)
Podsumowanie
Czy to wszystko? Nie! mix test
umożliwia nam podłączenie code coverage, ma kilka ciekawych opcji przy przechwytywaniu logów i testowaniu czy logi zostały zapisane tak jak chcieliśmy. Ogólnie API jest pokaźne i można się z nim zapoznać tutaj.