Организация тестов Haskell
Итак, я пытаюсь следовать предлагаемой структуре проекта Haskell и у меня возникает пара проблем с организацией моих тестов.
Для простоты начнем с:
src/Clue/Cards.hs # defines Clue.Cards module
testsuite/tests/Clue/Cards.hs # tests Clue.Cards module
Во-первых, я не уверен, что назвать модуль в testsuite/tests/Clue/Cards.hs
, который содержит тестовый код, а для другого - я не уверен, как скомпилировать мой тестовый код, чтобы я мог ссылаться на мой источник:
% 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.
Ответы
Ответ 1
Я использую подход, используемый Snap Framework для своих тестовых наборов, который в основном сводится к:
- Используйте тестовую структуру, такую как haskell-test-framework или HTF
-
Назовите модули, содержащие тесты, добавив .Tests
к имени модуля, содержащему IUT, например:
module Clue.Cards where ... -- module containing IUT
module Clue.Cards.Tests where ... -- module containing tests for IUT
-
Используя отдельные пространства имен, вы можете поместить свои тесты в отдельную папку-источник tests/
, затем вы можете использовать отдельную цель сборки Cabal (см. также поддержку cabal test
-build-target в последней версии Cabal версии) для тестового набора, который включает дополнительную папку источника в настройке hs-source-dirs
, например:
Executable clue
hs-source-dirs: src
...
Executable clue-testsuite
hs-source-dirs: src tests
...
Это работает, поскольку больше не существует конфликта пространства имен между модулями вашего IUT и тестовым набором.
Ответ 2
Лично я считаю, что дополнительный каталог ./src/
не имеет большого смысла для небольших проектов Haskell. Из грубого источника, я загрузил исходный код.
В любом случае (с или без src), я предлагаю вам рефакторинг и иметь каталог Clue
и каталог Test
:
./Clue/Cards.hs -- module Clude.Cards where ...
./Test/Cards.hs -- module Test.Cards where ...
Это позволяет GHCi + Test.Cards видеть Clue.Cards без каких-либо дополнительных аргументов или использования cabal. В этой заметке, если вы не используете флаги cabal + для необязательного создания тестовых модулей, тогда вы должны изучить его.
Другой вариант, который я использую во многих моих проектах, заключается в следующем:
./Some/Module/Hierarchy/File.hs
./tests/someTests.hs
И я cabal install
пакет, затем запустил материал tests/someTests.hs
. Я предполагаю, что это будет раздражать, если мои пакеты были особенно большими и слишком долгое время для установки.
Ответ 3
Здесь другой способ:
Каждый модуль модульных тестов определяется как hunit TestList в конце модуля, с некоторой последовательной схемой именования, такой как "tests_Path_To_Module", Я думаю, что это помогает мне писать тесты, так как мне не нужно искать еще один модуль в исходном дереве и не синхронизировать две параллельные иерархии файлов.
Список тестов модулей также включает тесты любых подмодулей. Бегун Hunit runTestTT встроен в приложение и доступен с помощью команды test. Это означает, что пользователь может запускать тесты в любое время без специальной настройки. Или, если вам не нравятся тесты на отправку в производственном приложении, используйте флажки CPP и cabal, чтобы включать их только в сборку dev или в отдельный исполняемый файл тестового бегуна.
Существуют также функциональные тесты, один или несколько файлов в каталоге tests/, который запускается с shelltestrunner и некоторые тесты, связанные с процессом dev-process, основанные на Makefile.
Ответ 4
Для полноты, стоит упомянуть очень простой подход для небольшого проекта через ghci -i
. Например, в вашем случае
>ghci -isrc:testsuite
ghci>:l Clue.Cards
ghci>:l tests.Clue.Cards