Apprends à tester tes exercices Elixir sur Exercism
Depuis le terminal, place-toi dans le répertoire de base de l'exercice, puis exécute les tests avec :
$ mix test
Cette commande exécute le fichier de test situé dans le sous-dossier test, un fichier qui se termine par _test.exs
Dans les suites de tests des exercices d'entraînement, tous les tests sauf le premier sont marqués pour être ignorés.
Une fois qu'un test passe, tu peux réactiver le suivant en
commentant le @tag :pending correspondant avec un symbole #.
Par exemple :
# @tag :pending
test "shouting" do
assert Bob.hey("WATCH OUT!") == "Whoa, chill out!"
end
Si tu veux exécuter tous les tests d'un coup, tu peux inclure tous les tests
ignorés grâce à l'option --include de la commande mix test :
$ mix test --include pending
Ou bien tu peux activer tous les tests en commentant la ligne
ExUnit.configure de la suite de tests.
# ExUnit.configure exclude: :pending, trace: true
ExUnit et mix test proposent pas mal de méthodes pour regrouper, étiqueter et exécuter
des tests, ainsi que diverses façons de contrôler l'exécution des tests ; une bonne partie
est résumée ci-dessous.
Documentation :
Tous les tests d'un même fichier peuvent être exécutés avec mix test en précisant le fichier :
$ mix test test/<FILE>.exs
REMARQUE :
taggingpeut influencer les tests qui sont réellement exécutés avec cette méthode.
Un test isolé peut être exécuté en indiquant son numéro de ligne dans le fichier :
$ mix test test/<FILE>.exs:LINENUM
Plusieurs tests peuvent être exécutés en donnant plusieurs numéros de ligne séparés par :.
Par exemple, pour un fichier dont le contenu est le suivant, avec les numéros de ligne :
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
On peut exécuter le 1er et le 3e test avec :
$ mix test test/FILE.exs:1:24
REMARQUE : lorsqu'on indique des tests par leur numéro de ligne,
taggingest ignoré.
Les tests peuvent être regroupés avec describe :
describe "short test group description" do
test "test description" do
# test implementation
end
test "another test description" do
# test implementation
end
end
Tous les tests d'un groupe peuvent être exécutés en indiquant le numéro de ligne du groupe dans le fichier, exactement comme pour un test isolé.
Documentation :
mix test
--include et --exclude : exécutent ou non certains tests selon leurs @tag
--failed : n'exécute que les tests qui ont échoué lors de leur dernière exécution--max-failures : la suite arrête d'évaluer les tests lorsque ce nombre d'échecs
est atteint--seed : initialise le générateur de nombres aléatoires utilisé pour mélanger l'ordre des tests
--seed 0 désactive ce mélange, si bien que les tests d'un même fichier sont toujours exécutés
dans l'ordre dans lequel ils ont été définis--stale : n'exécute que les tests qui font référence à des modules modifiés depuis la dernière
fois que les tests ont été lancés avec --stale
--only task_id:1 : ou avec un autre numéro ; sur les exercices d'apprentissage, n'exécute que les tests associés à la tâche indiquéeDocumentation :
Les exercices Elixir contiennent un fichier d'implémentation squelette dans le sous-dossier
lib. Ce fichier décrit le module et les fonctions que tu es censé implémenter. Dans la
plupart des exercices, tu trouveras des typespecs au-dessus de la déclaration de fonction.
Elles commencent par l'attribut @spec et suivent généralement le format
@spec function_name(type1, type2) :: return_type. En Elixir et en Erlang, elles servent de
documentation et, associées à un outil appelé Dialyzer, à repérer les incohérences de types
et les bugs potentiels. Pour plus d'informations, consulte la documentation sur les typespecs. Pour
la documentation de Dialyzer, consulte Erlang -- dialyzer.
Tu peux aussi, si tu le souhaites, vérifier
les types de ton implémentation avec Dialyzer. Cela demande quelques
étapes. Pour ce faire, tu dois ajouter la dépendance Dialyxir
au fichier mix.exs de ton exercice.
defp deps do
# Add this:
[{:dialyxir, "~> 0.4", only: [:dev]}]
end
Ensuite, utilise les tâches mix pour récupérer et compiler depuis la ligne de commande :
$ mix deps.get
...
$ mix deps.compile
...
Si c'est la première fois que tu utilises Dialyzer,
tu n'as très probablement pas de fichier plt. La table de correspondance persistante
(persistent lookup table, ou PLT) sert à Dialyzer pour mettre en cache des informations sur
les types intégrés d'Elixir et d'Erlang. Pour créer un plt avec des valeurs par défaut
raisonnables, lance :
$ mix dialyzer --plt
Enfin, tu peux le lancer avec :
$ mix dialyzer
Pense à adapter le chemin à celui des bibliothèques Elixir sur ton système. Par
exemple, si tu as installé Elixir avec homebrew, tu le trouveras probablement sous
/usr/local/Cellar/elixir/1.3.2.
Rappelons que lancer Dialyzer et supprimer tous les avertissements
est une étape facultative pour terminer un exercice. Les avertissements de Dialyzer peuvent
être difficiles à déchiffrer. Regarde par exemple les avertissements de cette
implémentation vraiment ridicule de l'exercice Bob.
defmodule Bob do
@spec hey(input :: String.t()) :: String.t()
def hey(input) do
1
end
def hey(input) do
end
end
Cela produit les avertissements suivants.
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()
Le premier avertissement signifie que la fonction ne renvoie pas le bon type. Le dernier indique que la seconde définition de fonction ne sera jamais atteinte, car la première définition de fonction correspond toujours.