2011-01-14 3 views
24

Итак, я пытаюсь следить за suggested structure of a Haskell project, и у меня возникают проблемы с организацией моих тестов.Организация тестов 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. 

ответ

26

Я использую сам подход, принятый Snap Framework для их тест-комплекты, которые в основном сводятся к:

  1. Используйте тест-основы, такие как haskell-test-framework или HTF
  2. Имя модули, содержащие тесты по добавление .Tests к-имя модуля, содержащего ИТУ, например:

    module Clue.Cards where ... -- module containing IUT 
    
    module Clue.Cards.Tests where ... -- module containing tests for IUT 
    
  3. При использовании отдельных пространств имен, вы можете поместить свои тесты в отдельную папку-источник tests/, затем вы можете использовать отдельную цель сборки Cabal (см. также cabal test -build-target support в последних версиях Cabal) для тестового набора, который включает дополнительную исходную папку в своем hs-source-dirs установка, например:

    Executable clue 
        hs-source-dirs: src 
        ... 
    
    Executable clue-testsuite 
        hs-source-dirs: src tests 
        ... 
    

    Это работает, так как нет никакого столкновения имен между модулями в вашем ИТ и тест-люксе больше.

+1

+1 для упоминания оснастки-рамки, которая очень хорошо организована в этом отношении. –

+0

Прохладный. Я использую этот проект как способ изучить экосистему Haskell (я не думаю, что кто-то испытывает зуд для реализации правил Clue/Cluedo), и я еще не занимался кабкой, так что это хороший удар в штаны. Я выясню, как использовать кабалу, а затем обходите кругом к тестированию. – rampion

+1

, возможно, также заслуживает внимания в проекте snap-framework: у них есть свои тестовые наборы, объединенные с hudson, публикация результатов тестов и отчетов о покрытии (см. Http://buildbot.snapframework.com/) – hvr

3

Лично я считаю, что дополнительная ./src/ каталог не имеет большого смысла для небольших проектов Haskell. Из грубого источника, я загрузил исходный код.

В любом случае (с или без ЦСИ), я хотел бы предложить вам реорганизовать и есть 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 материал. Думаю, это было бы досадно, если бы мои пакеты были особенно большими и слишком долгое время для установки.

+4

Я думаю, что дополнительный 'src' каталог всегда имеет смысл, потому что он имеет право, что на самом деле содержится в иерархии исходного кода: источники Haskell! Это особенно полезно, когда ваше приложение содержит в себе другие вещи, такие как скрипты, файлы конфигурации и, возможно, другие источники, отличные от Haskell. – fatuhoku

3

Вот еще один способ:

модульные тесты каждого модуля определяются как hunit TestList at the end of the module, с некоторой последовательной схемы именования, такие как «tests_Path_To_Module». Я думаю, что это помогает мне писать тесты, так как мне не нужно искать еще один модуль в исходном дереве и не синхронизировать две параллельные иерархии файлов.

В тестовом списке модуля также содержатся тесты любых подмодулей.Бегун RunTestTT от Hunit встроен в приложение и доступен через test command. Это означает, что пользователь может запускать тесты в любое время без специальной настройки. Если вам не нравятся тесты на доставку в производственном приложении, используйте флаги CPP и cabal, чтобы включать их только в сборку dev или в отдельный исполняемый файл тестового бегуна.

Есть также функциональные тесты, один или несколько файлов в каталоге tests/, запустите с shelltestrunner и некоторые тесты, связанные с процессом, основанные на Makefile.

+3

Я не рекомендую вводить тесты в ваши модули реализации. Вы должны иметь возможность компилировать свои производственные модули без зависимости от среды тестирования. (_xUnit Patterns_ вызывает этот запах «Зависимость тестирования в производстве»). Использование флагов CPP для их извлечения не является реальным решением. В любом случае это нарушает принцип единой ответственности. –

1

Для полноты картины стоит упомянуть очень простой подход для небольшого проекта через ghci -i. Например, в вашем случае,

>ghci -isrc:testsuite 
ghci>:l Clue.Cards 
ghci>:l tests.Clue.Cards 
Смежные вопросы