web-dev-qa-db-ja.com

Haskellスタックプロジェクトで複数のテストファイルを実行する方法

Stack で既存のHaskellプロジェクトをセットアップしたい。既存のプロジェクトは、testディレクトリの下にある複数のファイルを使用します。これらの個別のテストファイルは、デフォルトでは、Stack(またはcabal?)がテストに単一のtest/Spec.hsを使用しているように見えます。このプロジェクトで複数のファイルを引き続き使用するにはどうすればよいですか?

注:私はHaskellを学んでおり、このプロジェクトは「カタ」アプローチからの私の学習にアプローチしています。したがって、テストは分離されて、一度に言語の1つの側面に焦点を合わせます。

17
1ijk

このようなディレクトリ構造の設定は次のとおりです

> tree                                                                                       
.
├── example.cabal
├── app
│   └── Main.hs
├── ChangeLog.md
├── LICENSE
├── Setup.hs
├── src
│   ├── A
│   │   └── C.hs
│   ├── A.hs
│   └── B.hs
├── stack.yaml
└── tst
    ├── integration
    │   └── Spec.hs
    └── unit
        ├── A
        │   └── CSpec.hs
        ├── ASpec.hs
        ├── BSpec.hs
        └── Spec.hs

通常の単体テストとは別の統合テストと、srcフォルダー内の各モジュールに対応するいくつかのサブモジュールが必要です。

まず、テストスイートをに追加する必要があります

example.cabalファイル

name:                example
...
-- copyright:
-- category:
build-type:          Simple
extra-source-files:  ChangeLog.md
cabal-version:       >=1.10

executable testmain
  main-is:       Main.hs
  hs-source-dirs: app
  build-depends: base
               , example

library
  exposed-modules:     A.C,A,B
  -- other-modules:
  -- other-extensions:
  build-depends:       base >=4.9 && <4.10
  hs-source-dirs:      src
  default-language:    Haskell2010

test-suite unit-tests
  type:          exitcode-stdio-1.0
  main-is:       Spec.hs
  hs-source-dirs: tst/unit
  build-depends: base
               , example
               , hspec
               , hspec-discover
               , ...

test-suite integration-tests
  type:          exitcode-stdio-1.0
  main-is:       Spec.hs
  hs-source-dirs: tst/integration
  build-depends: base
               , example
               , hspec
               , ...

以下をtst/unit/Spec.hsに入力します。これはhspec-discoverからのものであり、...Spec.hs形式のすべてのモジュールを検出し(したがって名前が付けられます)、それらのそれぞれからspec関数を実行します。モジュール。

tst/unit/Spec.hs

{-# OPTIONS_GHC -F -pgmF hspec-discover #-}

この一行だけ

その他のテストファイル

次に、ユニットテストをASpec.hsに追加し、他のユニットテストをBSpec.hsCSpec.hsに追加し、Spec.hstst/integrationフォルダーに追加します。

module ASpec where

import Test.Hspec
import A

spec :: Spec
spec = do
  describe "Prelude.head" $ do
    it "returns the first element of a list" $ do
      head [23 ..] `shouldBe` (23 :: Int)

    it "returns the first element of an *arbitrary* list" $
      property $ \x xs -> head (x:xs) == (x :: Int)

    it "throws an exception if used with an empty list" $ do
      evaluate (head []) `shouldThrow` anyException

その後、テストをコンパイルして実行できます。

$> stack test
# now all your tests are executed
$> stack test :unit-tests
# now only the unit tests run
$> stack test :integration-tests
# now only the integration tests run

ソース

すべての例は https://hspec.github.io にあります。hspecスタイルのテストについて詳しく知りたい場合は、そこから始めるのが最善だと思います。スタックについては、 https://haskellstack.org にアクセスしてください-そこにテスト/ベンチマークに関する情報があります-つまり、テストとベンチマークの実行についてです。

Haskellのさまざまなテストスタイルについては、HUnit、QuickCheck、Smallcheck、doctestsを参照してください(忘れてしまった場合は、心からお詫びします。これらも私が定期的に使用しているものです)。

26
epsilonhalbe