Je viens de commencer un nouveau projet Haskell et je voulais mettre en place un bon workflow de test depuis le début. Il semble que Haskell possède de nombreux outils de test excellents et uniques et de nombreuses façons de les intégrer.
J'ai étudié:
Qui semblent tous très bien fonctionner dans leur domaine, mais je suis à la recherche d'une approche globale des tests et je me demandais ce qui avait bien fonctionné pour d'autres personnes.
Obtenir des tests unitaires, une couverture de code et des benchmarks corrects consiste principalement à choisir les bons outils.
Je vais utiliser comme exemple en cours d'exécution un package que je viens de commencer à activer avec des tests unitaires, une couverture de code et des tests de performance:
http://github.com/ekmett/speculation
Vous pouvez intégrer vos tests et vos benchmarks directement dans votre fichier cabale en ajoutant des sections pour eux, et en les masquant derrière des drapeaux afin qu'ils ne le rendent pas possible pour que chaque utilisateur de votre bibliothèque ait accès (et souhaite utiliser pour lui-même) ) la version exacte des outils de test que vous avez choisis.
http://github.com/ekmett/speculation/blob/master/speculation.cabal
Ensuite, vous pouvez expliquer à cabal comment exécuter votre suite de tests. Comme le test de la cabale n'existe pas encore - nous avons un étudiant qui y travaille pour l'été de code de cette année! - le meilleur mécanisme que nous avons est Voici comment utiliser le mécanisme de crochet utilisateur de Cabal. Cela signifie passer à une construction `` personnalisée '' avec cabale et mettre en place un testHook. Un exemple de testHook qui exécute un programme de test écrit avec test-framework, puis applique hpc au profil, se trouve ici:
http://github.com/ekmett/speculation/blob/master/Setup.lhs
Et vous pouvez ensuite utiliser test-framework pour regrouper les tests QuickCheck et HUnit dans un seul programme:
http://github.com/ekmett/speculation/blob/master/Test.hs
Le fichier cabal là-bas est prudent d'activer -fhpc pour activer les tests de couverture de code, puis le testHook dans Setup.lhs exécute manuellement hpc et écrit sa sortie dans votre répertoire dist.
Pour l'analyse comparative, l'histoire est un peu plus manuelle, il n'y a pas d'option de "référence cabale". Vous pouvez câbler vos benchmarks dans votre hook de test, mais j'aime les exécuter à la main, car Criterion a tellement d'options de rapports graphiques. Vous pouvez ajouter vos repères au fichier cabale comme indiqué ci-dessus, leur donner des drapeaux de compilation séparés, les cacher derrière un drapeau cabale, puis utiliser Criterion pour faire tout le gros du travail:
http://github.com/ekmett/speculation/blob/master/Benchmark.hs
Vous pouvez ensuite exécuter vos benchmarks à partir de la ligne de commande et obtenir des fenêtres KDE contextuelles avec des résultats de benchmark, etc.
Étant donné que dans la pratique, vous vivez de toute façon dans la cabale tout en développant du code Haskell, il est très logique d'intégrer votre chaîne d'outils à celle-ci.
Edit : Le support du test Cabal existe maintenant. Voir http://www.haskell.org/cabal/release/cabal-latest/doc/users-guide/developing-packages.html#test-suites
L'approche est préconisée dans RWH ch 11 et dans XMonad est approximativement:
Une fois que vos principaux invariants sont établis via QuickCheck, vous pouvez commencer la refactorisation, en déplaçant ces tests en invariants de type.
Des pratiques pour soutenir vos efforts:
Le package de framework de test est vraiment génial. Vous pouvez facilement intégrer des tests HUnit et QuickCheck et obtenir des exécutables qui exécutent uniquement des suites spécifiées, basées sur des indicateurs de ligne de commande, avec plusieurs cibles de sortie.
Les tests et le profilage sont cependant des bêtes différentes. Pour le profilage, je mettrais en place un exécutable distinct qui met l'accent uniquement sur la section que vous souhaitez profiler, et en examinant attentivement les résultats des profils et des exécutions (avec -prof-auto-all pour la compilation et + RTS -p pour un runtime drapeau).
Pour les tests, je me fie aux propriétés HUnit et QuickCheck et j'utilise Haskell Test Framework pour collecter automatiquement tous les tests unitaires et toutes les propriétés QuickCheck.
Avertissement: je suis le principal développeur de Haskell Test Framework.