Tesztelés az Elixir-kurzuson

Tanuld meg, hogyan tesztelheted az Elixir-feladataidat az Exercism-ön


A terminálból válts a feladat alapkönyvtárába, majd futtasd a teszteket a következővel:

$ mix test

Ez lefuttatja a test almappában található tesztfájlt, amelynek a neve _test.exs-re végződik.

Függőben lévő tesztek

A gyakorlófeladatok tesztcsomagjaiban az első kivételével minden tesztet megjelöltek, hogy kimaradjanak a futtatásból.

Amint egy teszt sikeresen lefut, a következőt úgy kapcsolhatod vissza, hogy a megfelelő @tag :pending sort kikommentezed egy # jellel.

Például:

# @tag :pending
test "shouting" do
  assert Bob.hey("WATCH OUT!") == "Whoa, chill out!"
end

Ha egyszerre szeretnéd futtatni az összes tesztet, a mix test parancs --include kapcsolójával bevonhatod az összes kihagyott tesztet:

$ mix test --include pending

Vagy engedélyezheted az összes tesztet úgy, hogy kikommentezed a tesztcsomag ExUnit.configure sorát.

# ExUnit.configure exclude: :pending, trace: true

További tesztelési lehetőségek az Elixirben

Az ExUnit és a mix test jó néhány módot kínál a tesztek csoportosítására, megjelölésére és futtatására, valamint a tesztfuttatás vezérlésére; ezek nagy részét az alábbiakban foglaljuk össze.

Módszerek adott tesztek futtatására

Dokumentáció:

Tesztek futtatása egy adott fájlban

Egy fájl összes tesztjét futtathatod a mix test segítségével, ha megadod a fájlt:

$ mix test test/<FILE>.exs

MEGJEGYZÉS: a tagging hatással lehet arra, hogy ezzel a módszerrel valójában mely tesztek futnak le.

Egyes tesztek futtatása

Az egyes teszteket úgy futtathatod, hogy a fájlban a teszt sorszámára hivatkozol:

$ mix test test/<FILE>.exs:LINENUM

Több tesztet is futtathatsz, ha több sorszámot adsz meg :-tal elválasztva.

Például vegyük a következő tartalmú fájlt a sorszámokkal:

test "Test 1" do           # 1
  # test implementation    # 2-6
end                        # 7
                           # 8
test "Test 2" do           # 9
  # test implementation    # 10-21
end                        # 22
                           # 23
test "Test 3" do           # 24
  # test implementation    # 25-35
end                        # 36

Az 1. és a 3. teszt futtatható így:

$ mix test test/FILE.exs:1:24

MEGJEGYZÉS: Ha sorszámokkal adod meg a teszteket, a tagging figyelmen kívül marad.

Tesztcsoportok futtatása

A teszteket a describe használatával csoportosíthatod:

describe "short test group description" do
  test "test description" do
    # test implementation
  end

  test "another test description" do
    # test implementation
  end
end

Egy csoport összes tesztjét ugyanúgy futtathatod, mint az egyes teszteket: a fájlban a csoport sorszámára hivatkozol.

Dokumentáció:

Egyéb hasznos mix test opciók

  • --include és --exclude - az @tag-jeik alapján futtatja vagy nem futtatja az adott teszteket
  • --failed - csak azokat a teszteket futtatja, amelyek legutóbb sikertelenek voltak
  • --max-failures - a tesztcsomag leállítja a tesztek kiértékelését, amikor eléri ezt a számú teszthibát
  • --seed - beállítja a tesztek sorrendjének véletlenszerűsítéséhez használt véletlenszám-generátort A --seed 0 kikapcsolja a véletlenszerűsítést, így egy fájl tesztjei mindig abban a sorrendben futnak le, ahogy definiáltad őket
  • --stale - csak azokat a teszteket futtatja, amelyek olyan modulokra hivatkoznak, amelyek azóta megváltoztak, hogy legutóbb --stale kapcsolóval futtattad a teszteket
  • --only task_id:1 - vagy más számmal: a tanulófeladatoknál csak az adott részfeladathoz tartozó teszteket futtatja

Dokumentáció:

Typespecs és a Dialyzer (DIscrepancy AnalYZer for ERlang programs)

Az Elixir-feladatokhoz tartozik egy vázlatos implementációs fájl a lib almappában. Ez a fájl felvázolja azt a modult és azokat a függvényeket, amelyeket meg kell valósítanod. A legtöbb feladatban a függvénydefiníció fölött typespec-eket találsz. Ezek a @spec címkével kezdődnek, és általában a @spec function_name(type1, type2) :: return_type formátumot követik. Az Elixirben és az Erlangban dokumentációként használják őket, valamint a Dialyzer nevű eszközzel együtt típusbeli ellentmondások és lehetséges hibák felkutatására. További információért lásd a typespec-dokumentációt. A Dialyzer dokumentációját itt találod: Erlang -- dialyzer.

Ha szeretnéd, a Dialyzerrel ellenőrizheted az implementációd típusait is. Ehhez néhány lépést kell megtenned. Először hozzá kell adnod a Dialyxir függőséget a feladatod mix.exs fájljához.

defp deps do
  # Add this:
  [{:dialyxir, "~> 0.4", only: [:dev]}]
end

Ezután a parancssorból mix taskokkal letöltheted és lefordíthatod:

$ mix deps.get
...
$ mix deps.compile
...

Ha most futtatod először a Dialyzert, valószínűleg még nincs plt fájlod. A perzisztens keresőtáblát (persistent lookup table, PLT) a Dialyzer arra használja, hogy gyorsítótárazza a beépített Elixir- és Erlang-típusokra vonatkozó információkat. Ha értelmes alapbeállításokkal szeretnél létrehozni egy plt-t, futtasd:

$ mix dialyzer --plt

Végül így futtathatod:

$ mix dialyzer

Ügyelj rá, hogy az útvonalat a saját rendszered Elixir-könyvtárainak útvonalára módosítsd. Ha például Homebrew-val telepítetted az Elixirt, valószínűleg a /usr/local/Cellar/elixir/1.3.2 alatt találod.

Ismételten érdemes hangsúlyozni, hogy a Dialyzer futtatása és az összes figyelmeztetés megszüntetése választható lépés egy feladat megoldásakor. A Dialyzer figyelmeztetéseit nehéz lehet megfejteni. Vizsgáld meg például a Bob feladat alábbi, nagyon ostoba implementációjához tartozó figyelmeztetéseket.

defmodule Bob do
  @spec hey(input :: String.t()) :: String.t()
  def hey(input) do
    1
  end

  def hey(input) do
  end
end

Ez a következő figyelmeztetéseket eredményezi.

bob.exs:2: Invalid type specification for function 'Elixir.Bob':hey/1. The success typing is (_) -> 1
bob.exs:7: The variable _input@1 can never match since previous clauses completely covered the type any()

Az első figyelmeztetés azt jelenti, hogy a függvény nem a megfelelő típust adja vissza. Az utolsó pedig arra utal, hogy a második függvénydefiníció soha nem érhető el, mert az első függvénydefiníció mindig illeszkedik.