Δοκιμές στο track Elixir

Μάθε πώς να δοκιμάζεις τις ασκήσεις σου σε Elixir στο Exercism


Από το τερματικό, πήγαινε στον βασικό κατάλογο της άσκησης και μετά εκτέλεσε τα tests με:

$ mix test

Έτσι θα εκτελεστεί το αρχείο tests που βρίσκεται στον υποφάκελο test, ένα αρχείο που τελειώνει σε _test.exs

Εκκρεμή tests

Στις σουίτες tests των ασκήσεων εξάσκησης, όλα τα tests εκτός από το πρώτο έχουν επισημανθεί ώστε να παραλείπονται.

Μόλις καταφέρεις να περάσει ένα test, μπορείς να ενεργοποιήσεις το επόμενο σχολιάζοντας το σχετικό @tag :pending με το σύμβολο #.

Για παράδειγμα:

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

Αν θέλεις να εκτελέσεις όλα τα tests με τη μία, μπορείς να συμπεριλάβεις όλα τα tests που παραλείπονται χρησιμοποιώντας τη σημαία --include στην εντολή mix test:

$ mix test --include pending

Ή μπορείς να ενεργοποιήσεις όλα τα tests σχολιάζοντας τη γραμμή ExUnit.configure στη σουίτα tests.

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

Επιπλέον δυνατότητες tests στην Elixir

Τα ExUnit και mix test προσφέρουν αρκετούς τρόπους για ομαδοποίηση, επισήμανση και εκτέλεση tests, καθώς και διάφορους τρόπους ελέγχου της εκτέλεσης των tests, πολλοί από τους οποίους συνοψίζονται παρακάτω.

Τρόποι εκτέλεσης συγκεκριμένων tests

Τεκμηρίωση:

Εκτέλεση tests σε συγκεκριμένο αρχείο

Όλα τα tests σε ένα μόνο αρχείο μπορούν να εκτελεστούν με το mix test, προσδιορίζοντας το αρχείο:

$ mix test test/<FILE>.exs

ΣΗΜΕΙΩΣΗ: Το tagging μπορεί να επηρεάσει ποια tests εκτελούνται πραγματικά με αυτή τη μέθοδο.

Εκτέλεση μεμονωμένων tests

Μεμονωμένα tests μπορούν να εκτελεστούν αναφέροντας τον αριθμό γραμμής του test στο αρχείο:

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

Πολλαπλά tests μπορούν να εκτελεστούν δίνοντας πολλούς αριθμούς γραμμών χωρισμένους με :.

Για παράδειγμα, δίνεται ένα αρχείο με το παρακάτω περιεχόμενο με αριθμούς γραμμών:

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

Το 1ο και το 3ο test μπορούν να εκτελεστούν με:

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

ΣΗΜΕΙΩΣΗ: Όταν προσδιορίζεις tests μέσω αριθμών γραμμών, το tagging αγνοείται.

Εκτέλεση ομάδων tests

Τα tests μπορούν να ομαδοποιηθούν χρησιμοποιώντας το describe:

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

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

Όλα τα tests σε μια ομάδα μπορούν να εκτελεστούν αναφέροντας τον αριθμό γραμμής της στο αρχείο, ακριβώς όπως αναφέρεις και εκτελείς μεμονωμένα tests.

Τεκμηρίωση:

Άλλες χρήσιμες επιλογές του mix test

  • --include και --exclude - εκτελεί ή δεν εκτελεί συγκεκριμένα tests με βάση τα @tag τους
  • --failed - εκτελεί μόνο τα tests που απέτυχαν την τελευταία φορά που εκτελέστηκαν
  • --max-failures - η σουίτα σταματά να αξιολογεί tests όταν φτάσει αυτός ο αριθμός αποτυχιών
  • --seed - αρχικοποιεί τη γεννήτρια τυχαίων αριθμών που χρησιμοποιείται για την τυχαία σειρά των tests το --seed 0 απενεργοποιεί την τυχαιοποίηση, ώστε τα tests σε ένα μόνο αρχείο να εκτελούνται πάντα με τη σειρά που ορίστηκαν
  • --stale - εκτελεί μόνο τα tests που αναφέρονται σε modules που άλλαξαν από την τελευταία φορά που εκτελέστηκαν tests με --stale
  • --only task_id:1 - ή με άλλον αριθμό, στις ασκήσεις μάθησης εκτελεί μόνο τα tests που σχετίζονται με τη συγκεκριμένη εργασία

Τεκμηρίωση:

Typespecs και Dialyzer (DIscrepancy AnalYZer for ERlang programs)

Οι ασκήσεις της Elixir περιλαμβάνουν έναν σκελετό αρχείου υλοποίησης στον υποφάκελο lib. Αυτό το αρχείο περιγράφει το module και τις συναρτήσεις που καλείσαι να υλοποιήσεις. Στις περισσότερες ασκήσεις, θα βρεις typespecs πάνω από τη δήλωση της συνάρτησης. Αυτά ξεκινούν με την ετικέτα @spec και συνήθως ακολουθούν τη μορφή @spec function_name(type1, type2) :: return_type. Χρησιμοποιούνται στην Elixir και την Erlang ως τεκμηρίωση και σε συνδυασμό με ένα εργαλείο που λέγεται Dialyzer, για να εντοπίζονται ασυνέπειες τύπων και πιθανά bugs. Για περισσότερες πληροφορίες, δες την τεκμηρίωση των typespecs. Για τεκμηρίωση σχετικά με το Dialyzer, δες το Erlang -- dialyzer.

Προαιρετικά, μπορεί να θέλεις να ελέγξεις τους τύπους της υλοποίησής σου με το Dialyzer. Θα χρειαστεί να κάνεις μερικά βήματα. Για να το κάνεις αυτό, πρέπει να προσθέσεις την εξάρτηση Dialyxir στο αρχείο mix.exs της άσκησής σου.

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

Στη συνέχεια, χρησιμοποίησε τα mix tasks για να τα κατεβάσεις και να τα μεταγλωττίσεις από τη γραμμή εντολών:

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

Αν αυτή είναι η πρώτη φορά που τρέχεις το Dialyzer, πιθανότατα δεν θα έχεις αρχείο plt. Ο persistent lookup table, ή PLT, χρησιμοποιείται από το Dialyzer για να αποθηκεύει προσωρινά πληροφορίες για τους ενσωματωμένους τύπους της Elixir και της Erlang. Για να δημιουργήσεις ένα plt με λογικές προεπιλογές, τρέξε:

$ mix dialyzer --plt

Τέλος, μπορεί να εκτελεστεί με:

$ mix dialyzer

Φρόντισε να αλλάξεις τη διαδρομή ώστε να δείχνει στη διαδρομή των βιβλιοθηκών της Elixir στο σύστημά σου. Για παράδειγμα, αν εγκατέστησες την Elixir με το homebrew, πιθανότατα θα τη βρεις στο /usr/local/Cellar/elixir/1.3.2.

Αξίζει να επαναλάβουμε ότι η εκτέλεση του Dialyzer και η εξάλειψη όλων των προειδοποιήσεων είναι προαιρετικό βήμα όταν ολοκληρώνεις μια άσκηση. Οι προειδοποιήσεις του Dialyzer μπορεί να είναι δύσκολο να αποκωδικοποιηθούν. Για παράδειγμα, εξέτασε τις προειδοποιήσεις για αυτή την πολύ ανόητη υλοποίηση της άσκησης Bob.

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

  def hey(input) do
  end
end

Αυτό παράγει τις ακόλουθες προειδοποιήσεις.

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

Η πρώτη προειδοποίηση σημαίνει ότι η συνάρτηση δεν επιστρέφει τον σωστό τύπο. Η τελευταία δείχνει ότι ο δεύτερος ορισμός της συνάρτησης δεν μπορεί ποτέ να φτάσει, επειδή ο πρώτος ορισμός ταιριάζει πάντα.