Testare nel track di Elixir

Impara a testare i tuoi esercizi di Elixir su Exercism


Dal terminale, spostati nella directory di base dell'esercizio, poi esegui i test con:

$ mix test

Verrà eseguito il file di test presente nella sottocartella test, un file che termina con _test.exs

Test in sospeso

Nelle suite di test degli esercizi di pratica, tutti i test tranne il primo sono contrassegnati per essere saltati.

Quando riesci a far passare un test, puoi riattivare il successivo trasformando in commento il relativo @tag :pending con un simbolo #.

Per esempio:

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

Se vuoi eseguire tutti i test in una volta sola, puoi includere tutti i test saltati usando il flag --include sul comando mix test:

$ mix test --include pending

Oppure puoi abilitare tutti i test trasformando in commento la riga ExUnit.configure nella suite di test.

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

Funzionalità aggiuntive per i test in Elixir

ExUnit e mix test offrono diversi metodi per raggruppare, contrassegnare ed eseguire i test, oltre a vari modi per controllarne l'esecuzione: gran parte di tutto questo è riassunta qui sotto.

Metodi per eseguire test specifici

Documentazione:

Eseguire i test in un file specifico

Tutti i test di un singolo file possono essere eseguiti con mix test specificando il file:

$ mix test test/<FILE>.exs

NOTA: tagging può influire su quali test vengono effettivamente eseguiti con questo metodo.

Eseguire singoli test

I singoli test possono essere eseguiti facendo riferimento al numero di riga del test nel file:

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

Più test possono essere eseguiti indicando più numeri di riga separati da :.

Per esempio, dato un file con il seguente contenuto con i numeri di riga:

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

Il 1º e il 3º test possono essere eseguiti con:

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

NOTA: quando si specificano i test tramite i numeri di riga, tagging viene ignorato.

Eseguire gruppi di test

I test possono essere raggruppati usando describe:

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

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

Tutti i test di un gruppo possono essere eseguiti facendo riferimento al suo numero di riga nel file, proprio come si fa per i singoli test.

Documentazione:

Altre opzioni utili di mix test

  • --include e --exclude: esegue o non esegue test specifici in base ai loro @tag
  • --failed: esegue solo i test falliti l'ultima volta
  • --max-failures: la suite smette di valutare i test quando viene raggiunto questo numero di fallimenti
  • --seed: inizializza il generatore di numeri casuali usato per randomizzare l'ordine dei test. --seed 0 disabilita la randomizzazione, così i test di un singolo file vengono sempre eseguiti nello stesso ordine in cui sono stati definiti
  • --stale: esegue solo i test che fanno riferimento a moduli cambiati dall'ultima volta in cui i test sono stati eseguiti con --stale
  • --only task_id:1, o con un altro numero: negli esercizi di apprendimento esegue solo i test associati al task specifico

Documentazione:

Typespec e Dialyzer (DIscrepancy AnalYZer for ERlang programs)

Gli esercizi di Elixir includono un file di implementazione scheletro nella sottocartella lib. Questo file delinea il modulo e le funzioni che dovrai implementare. Nella maggior parte degli esercizi, troverai i typespec sopra la dichiarazione della funzione. Questi iniziano con il tag @spec e di solito seguono il formato @spec function_name(type1, type2) :: return_type. Sono usati in Elixir e in Erlang come documentazione e insieme a uno strumento chiamato Dialyzer per trovare incongruenze di tipo e possibili bug. Per maggiori informazioni, consulta la documentazione sui typespec. Per la documentazione su Dialyzer, consulta Erlang -- dialyzer.

Facoltativamente, potresti voler controllare i tipi della tua implementazione con Dialyzer. Dovrai seguire un paio di passaggi. Per farlo, devi aggiungere la dipendenza Dialyxir al file mix.exs del tuo esercizio.

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

Poi usa i task di mix per scaricare e compilare dalla riga di comando:

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

Se è la prima volta che esegui Dialyzer, molto probabilmente non avrai un file plt. La tabella di ricerca persistente, o PLT, è usata da Dialyzer per memorizzare nella cache le informazioni sui tipi incorporati di Elixir e Erlang. Per creare un plt con valori predefiniti sensati, esegui:

$ mix dialyzer --plt

Infine, può essere eseguito con:

$ mix dialyzer

Assicurati di impostare il percorso su quello delle librerie di Elixir del tuo sistema. Per esempio, se hai installato Elixir con homebrew, probabilmente lo troverai in /usr/local/Cellar/elixir/1.3.2.

Va ribadito che eseguire Dialyzer e rimuovere tutti gli avvisi è un passaggio facoltativo quando completi un esercizio. Gli avvisi di Dialyzer possono essere difficili da decifrare. Per esempio, esamina gli avvisi per questa implementazione davvero sciocca dell'esercizio Bob.

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

  def hey(input) do
  end
end

Questo produce i seguenti avvisi.

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()

Il primo avviso significa che la funzione non restituisce il tipo corretto. L'ultimo indica che la seconda definizione della funzione non può mai essere raggiunta, perché la prima definizione della funzione corrisponde sempre.