Создание полного стека Haskell с тестами

Я новичок в Haskell и пытаюсь структурировать тестируемую программу. Я решил использовать HUnit и Cabal.

Из того, что я видел, хорошо структурированный проект выглядит следующим образом:

src/
  AppName/
  Appname.hs
testsuite/
  tests/
    AppName/
  TestRunner.hs
AppName.cabal
Setup.hs

Части, которые для меня остаются загадкой, — это TestRunner.hs и AppName.cabal.

Как будет выглядеть программа запуска тестов, которая запускает все тесты в каталоге testsuite/tests и его подкаталогах? И как его можно интегрировать с Cabal?

Кроме того, как поместить хакерские зависимости в AppName.cabal и построить их из командной строки?

Мне трудно найти полный пример создания приложения с нуля с тестами и зависимостями.

Спасибо


person GTDev    schedule 25.11.2012    source источник
comment
Вы проверили haskell.org/haskellwiki/How_to_write_a_Haskell_program? Возможно, это ответит на некоторые ваши вопросы.   -  person Jan Christiansen    schedule 25.11.2012


Ответы (1)


Вот фрагмент файла .cabal, который я использовал для одной из моих последних библиотек.

...
Library
  Build-depends:        base >= 4 && < 5, bytestring, directory, filepath, hslogger,
                        SHA, zlib
  Ghc-options:          -Wall
  Exposed-modules:      Ltc.Store

Test-suite reference
  Hs-Source-Dirs:       Test, .
  Main-Is:              ReferenceProps.hs
  Type:                 exitcode-stdio-1.0

  Build-Depends:        base >= 4 && < 5, bytestring, directory, filepath, hslogger,
                        SHA, zlib
  Ghc-Options:          -Wall

  Build-Depends:        test-framework, test-framework-hunit, test-framework-quickcheck2,
                        HUnit, QuickCheck

Как мы видим, файл cabal определяет библиотеку и набор тестов. Библиотека определяет модули, которые она экспортирует, пакеты, от которых она зависит, и устанавливает некоторые пользовательские параметры GHC.

Мы можем легко собрать и упаковать библиотеку для распространения с помощью:

% cabal configure
% cabal build
% cabal sdist

Набор тестов очень похож на библиотеку: во-первых, он имеет те же зависимости, что и библиотека (см. первую строку Build-Depends), а затем добавляет несколько дополнительных тестовых зависимостей (см. вторую строку Build-Depends). Набор тестов здесь представляет собой комбинацию тестов HUnit и QuickCheck, и он использует Test-Framework в качестве средства запуска. Правильный тестTest/ReferenceProps.hs. Это тест типа exitcode-stdio. Это означает, что клика скажет, что тесты пройдены, если ReferenceProps выйдет с кодом 0. В противном случае она скажет, что тесты не пройдены.

Набор тестов выглядит как этот (но здесь мы собираемся использовать несколько простых тесты на обращение списка):

import Data.Monoid
import Test.Framework
import Test.Framework.Providers.HUnit
import Test.Framework.Providers.QuickCheck2
import Test.HUnit
import Test.QuickCheck

main :: IO ()
main = defaultMainWithOpts
       [ testCase "rev" testRev
       , testProperty "listRevRevId" propListRevRevId
       ] mempty

testRev :: Assertion
testRev = reverse [1, 2, 3] @?= [3, 2, 1]

propListRevRevId :: [Int] -> Property
propListRevRevId xs = not (null xs) ==> reverse (reverse xs) == xs

main - это просто подвеска. Вы также можете установить различные параметры для test-framework, заменив mempty. Функция testRev — это тест HUnit, а propListRevRevId — тест QuickCheck; см. соответствующие документы о том, как их писать.

Наконец, мы можем запустить тесты:

% cabal configure --enable-tests
% cabal test
person scvalex    schedule 25.11.2012
comment
Большое спасибо, это отвечает на большинство моих вопросов, и мне нравится, как вы связались с github. Еще одна вещь, как бы вы запускали тесты в подкаталогах Test/ ? Я не хочу помещать все свои тесты в один файл, и было бы здорово, если бы при создании тестового файла тесты запускались в testrunner автоматически. - person GTDev; 25.11.2012
comment
Я могу придумать два способа: 1) добавить больше секций Test-Suite в файл Cabal (это быстро надоест, но это, вероятно, самое простое решение, если у вас всего несколько наборов тестов) или 2) разделить тесты. в несколько файлов, экспортируйте списки тестов в каждый файл, затем используйте один бегун для concat списков тестов и запускайте их. - person scvalex; 26.11.2012