Organisation Des Tests Haskell
J'essaie donc de suivre la structure suggérée d'un projet Haskell, et j'ai quelques problèmes à organiser mes tests.
Pour simplifier, commençons par:
src/Clue/Cards.hs # defines Clue.Cards module
testsuite/tests/Clue/Cards.hs # tests Clue.Cards module
Pour un, Je ne suis pas sûr de savoir comment nommer le module dans testsuite/tests/Clue/Cards.hs
qui contient le code de test, et pour un autre, Je ne sais pas comment compiler mon code de test afin que je puisse créer un lien vers ma source:
% ghc -c testsuite/tests/Clue/Cards.hs -L src
testsuite/tests/Clue/Cards.hs:5:0:
Failed to load interface for `Clue.Cards':
Use -v to see a list of the files searched for.
4 réponses
J'utilise moi - même l'approche adoptée par Snap Framework pour leurs suites de tests, qui se résume essentiellement à:
- Utilisation d'un test-cadre comme haskell-test-cadre ou FASS
-
Nommez les modules contenant des tests en ajoutant
.Tests
au nom du module contenant L'IUT, par exemple:module Clue.Cards where ... -- module containing IUT module Clue.Cards.Tests where ... -- module containing tests for IUT
-
En utilisant des espaces de noms séparés, vous pouvez placer vos tests dans un dossier source séparé
tests/
, vous pouvez ensuite utiliser une cabale séparée build-target (voir aussicabal test
-build-target support dans les versions cabales récentes) pour la suite de tests qui inclut le dossier source supplémentaire dans son paramètrehs-source-dirs
, par exemple:Executable clue hs-source-dirs: src ... Executable clue-testsuite hs-source-dirs: src tests ...
Cela fonctionne, car il n'y a plus de collision d'espace de noms entre les modules de votre IUT et la suite de tests.
Personnellement, je pense qu'un répertoire ./src/
supplémentaire n'a pas beaucoup de sens pour les petits projets Haskell. De grossier il y a la source, j'ai téléchargé le code source.
De toute façon (avec ou sans src), je vous suggère de refactoriser et d'avoir un répertoire Clue
et un répertoire Test
:
./Clue/Cards.hs -- module Clude.Cards where ...
./Test/Cards.hs -- module Test.Cards where ...
Cela permet le Test GHCi+.Cartes pour voir indice.Cartes sans args supplémentaires ou en utilisant cabale. Sur cette note, si vous n'utilisez pas cabal + flags pour construire éventuellement vos modules de test, vous devriez regarder en elle.
Une autre option, que j'utilise dans beaucoup de mes projets, est d'avoir:
./Some/Module/Hierarchy/File.hs
./tests/someTests.hs
Et je cabal install
Le Paquet puis exécutez le truc tests/someTests.hs
. Je suppose que ce serait ennuyeux si mes paquets étaient particulièrement volumineux et trop longs à installer.
Voici une autre façon:
Les tests unitaires de chaque module sont définis comme une hunit TestList à la fin du module, avec un schéma de nommage cohérent, tel que "tests_Path_To_Module". Je pense que cela m'aide à écrire des tests, car je n'ai pas besoin de rechercher un autre module loin dans l'arborescence source, ni de synchroniser deux hiérarchies de fichiers parallèles.
La liste de tests d'un module inclut également les tests de tous les sous-modules. Runtesttt Runner de Hunit est intégré à l'application, et accessible via une commande de test . Cela signifie qu'un utilisateur peut exécuter les tests à tout moment sans configuration spéciale. Ou si vous n'aimez pas envoyer des tests dans l'application de production, utilisez les drapeaux CPP et cabal pour les inclure uniquement dans les builds de développement ou dans un exécutable de test distinct.
Il existe également des tests fonctionnels, un ou plusieurs par fichier dans le répertoire tests/, exécutés avec shelltestrunner, et certains tests liés au processus de développement basés sur le Makefile.
Par souci d'exhaustivité, il convient de mentionner une approche très facile pour les petits projets à travers ghci -i
. Par exemple, dans votre cas,
>ghci -isrc:testsuite
ghci>:l Clue.Cards
ghci>:l tests.Clue.Cards