Haskellのdoctest入門
Haskellのdoctest入門
ソフトウェアを文書化することは挑戦的でありえます、しかし、それは必ずしもそうである必要はありません.
本稿では、DocTestを紹介します.
モジュールdocsの中にテストを置くことによって、doctestは関数が自分のために話すことを許します、そして、あなたがあなたのテスト努力から最も得るのを援助します.
記事を読む
doctestとは
doctestは単にインタラクティブなセッションのようなドキュメントに埋め込まれたテキストの一部です.特別なライブラリを使用すると、これらのセッションを実行し、正しい値を返すことを確認できます.
このアイデアは、Pythonの素晴らしいから来ている
doctest
モジュールが、その後、実質的にすべてのプログラミング言語に広がっている.Haskellでは、doctestはGHCIセッションですHaddock comments .
もしあなたがHaskellのソースコードドキュメンテーションを通してスキムしなければならないなら、あなたはそれらの線が空想で気づいたかもしれません
>>>
最初のシンボル.-- | @const x@ is a unary function which evaluates to @x@ for all inputs.
--
-- >>> const 42 "hello"
-- 42
--
-- >>> map (const 42) [0..3]
-- [42,42,42,42]
推測したかもしれませんが、それらはdoctestです.Haskellでdoctestを定義する方法は?
基本的なdoctestの例を見てみましょう.
-- | 1 + 2 is 3.
-- >>> 1 + 2
-- 3
ご覧のように、Haskellのdoctestには三つの要件があります.-- |
or {- |
. >>>
そして、スコープにある有効なHaskell式を含んでいますimport
ステートメント-私たちはさらに記事をカバーします.doctest
図書館.さて、DocTestを使用してプロジェクトを作成し、それらのdoctestを実行するために使用できるHaskellライブラリを調べましょう.
DocTestを使用したHaskellプロジェクトの作成
DocTestライブラリで動作するには、DocTestを使用したHaskellプロジェクトを作成する必要があります.
まず、プロジェクトをブートストラップ
stack
:stack new doctests-demo
その後、プロジェクトのルートディレクトリに移動し、Haskell module :cd doctests-demo
touch src/Sample.hs
最後に、doctestを使って新しく作成した関数を追加しますSample.hs
モジュール-- src/Sample.hs
module Sample where
-- |
-- >>> foo + 13
-- 55
foo :: Integer
foo = 42
-- |
-- >>> bar
-- "bar"
bar :: String
bar = "bar"
プロジェクトは現在、doctestを実行する準備が整いました.Haskellのdoctestライブラリ
Haskell生態系の2つのDocTestライブラリをカバーします.
doctest
and cabal-docspec
. 最初のものは古くて、より人気がありますdoctest
’問題点.doctest
doctest
最も一般的に使用され、積極的に維持されたdoctestライブラリの一つです.同時に、大規模プロジェクトやライブラリとしてGHC依存性のような欠点がある.doctestの使い方
まず、ライブラリをインストールする
stack
:stack install doctest
その後、プロジェクトのルートディレクトリに移動し、ライブラリの実行可能ファイルを使用します.cd doctests-demo
doctest src
上記のコマンドは次のように出力します.Examples: 2 Tried: 2 Errors: 0 Failures: 0
doctestを使う
ソフトウェアの素晴らしい部分ですが、ライブラリにはいくつかの欠点があります.
最大の欠点は、ライブラリが大規模プロジェクトのためにあまりに遅いようです.パフォーマンスの問題を引き起こす理由の1つは、ライブラリがdoctestの各グループ間のソースを再読み込みすることです.これは、お互いに影響を与える例のグループを避けるために行われます.このことについてはlibrary’s readme .
また、いくつかのマイナーな欠点があります.
まず、依存性がGHC as a library , これは、プロジェクトを新しいコンパイラバージョンに切り替えると、結局何かが壊れてしまう可能性が高いということです.
第二に
stack
, プロジェクト依存関係をスコープにするには、追加のテストスイートを作成する必要があります.依存性の低下のイラスト。
私たちのdoctestの例を少し編集することでこれを説明しましょうaeson
and text
依存関係の一覧には)
-- src/Sample.hs
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TemplateHaskell #-}
module Sample where
import Data.Aeson
import Data.Aeson.TH
import Data.Text
data Anime =
Anime { title :: Text
, rating :: Double
}
$(deriveJSON defaultOptions ''Anime)
-- |
-- >>> encode favourite
-- "{\"title\":\"One-Punch Man\",\"rating\":8.9}"
--
favourite :: Anime
favourite = Anime "One-Punch Man" 8.9
さて、もし私たちがdoctestを実行しようとするならdoctest src
, 次のメッセージで失敗します.
src/Sample.hs:9:1: error:
Could not find module ‘Data.Aeson’
Perhaps you meant Data.Version (from base-4.14.3.0)
Use -v (or `:set -v` in ghci) to see a list of the files searched for.
|
9 | import Data.Aeson
| ^^^^^^^^^^^^^^^^^
回避策は、追加のテストスイートを作成することです.
tests:
doctests:
source-dirs: doctests
main: Main.hs
ghc-options:
- -threaded
- -rtsopts
- -with-rtsopts=-N
dependencies:
- doctest
# bring in your project into the scope
# as well as its dependencies
- doctests-demo
その後、テストスイートディレクトリとMain.hs
実行可能
mkdir doctests
touch doctests/Main.hs
-- doctests/Main.hs
import Test.DocTest
-- This test suite exists only to add dependencies
main :: IO ()
main = doctest ["src"]
最後に、以下のコマンドを使ってdoctestを実行します.
stack test :doctests
カバル博士
cabal-docspec
貢献者が少なく、全体的なコミュニティの注意が少ないが、人々の束はすでに実際のプロジェクトでそれを使用します.
Caval docspecの使い方
使いましょうcabal-docspec
doctestを実行するにはdoctests-demo
プロジェクト
まず、セットアップcabal-install
とグローバルコンパイラ.私たちはghcup これを達成する.
その後、CACALでプロジェクトを構築します
cabal v2-build
ダウンロードcabal-docspec
からのバイナリrelease page :
curl -sL https://github.com/phadej/cabal-extras/releases/download/cabal-docspec-0.0.0.20211114/cabal-docspec-0.0.0.20211114.xz > cabal-docspec.xz
xz -d < cabal-docspec.xz > "$HOME"/.local/bin/cabal-docspec
rm -f cabal-docspec.xz
chmod a+x "$HOME"/.local/bin/cabal-docspec
ここで、doctestの例を実行します.
cabal-docspec
上記のコマンドは次のエラーに失敗します.
expected: "{\"title\":\"One-Punch Man\",\"rating\":8.9}"
but got:
^
<interactive>:10:1: error:
Variable not in scope: encode :: Anime -> t
ライブラリが少し違ったものを扱うので、上記のことが起こります.モジュールを明示的にインポート/エクスポートする必要があります.
私たちのdoctestを少し編集しましょうcabal-docspec
仕事
-- |
+ -- >>> import Data.Aeson
-- >>> encode favourite
-- "{\"title\":\"One-Punch Man\",\"rating\":8.9}"
--
favourite :: Anime
favourite = Anime "One-Punch Man" 8.9
現在cabal-docspec
コマンドが成功する
Total: 2; Tried: 2; Skipped: 0; Success: 2; Errors: 0; Failures 0
Examples: 2; Tried: 2; Skipped: 0; Success: 2; Errors: 0; Failures 0
なぜcabal docspecを使うべきか
ここでは理由を使用する理由がありますcabal-docspec
プロジェクトについて
-- src/Sample.hs
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TemplateHaskell #-}
module Sample where
import Data.Aeson
import Data.Aeson.TH
import Data.Text
data Anime =
Anime { title :: Text
, rating :: Double
}
$(deriveJSON defaultOptions ''Anime)
-- |
-- >>> encode favourite
-- "{\"title\":\"One-Punch Man\",\"rating\":8.9}"
--
favourite :: Anime
favourite = Anime "One-Punch Man" 8.9
src/Sample.hs:9:1: error:
Could not find module ‘Data.Aeson’
Perhaps you meant Data.Version (from base-4.14.3.0)
Use -v (or `:set -v` in ghci) to see a list of the files searched for.
|
9 | import Data.Aeson
| ^^^^^^^^^^^^^^^^^
tests:
doctests:
source-dirs: doctests
main: Main.hs
ghc-options:
- -threaded
- -rtsopts
- -with-rtsopts=-N
dependencies:
- doctest
# bring in your project into the scope
# as well as its dependencies
- doctests-demo
mkdir doctests
touch doctests/Main.hs
-- doctests/Main.hs
import Test.DocTest
-- This test suite exists only to add dependencies
main :: IO ()
main = doctest ["src"]
stack test :doctests
cabal v2-build
curl -sL https://github.com/phadej/cabal-extras/releases/download/cabal-docspec-0.0.0.20211114/cabal-docspec-0.0.0.20211114.xz > cabal-docspec.xz
xz -d < cabal-docspec.xz > "$HOME"/.local/bin/cabal-docspec
rm -f cabal-docspec.xz
chmod a+x "$HOME"/.local/bin/cabal-docspec
cabal-docspec
expected: "{\"title\":\"One-Punch Man\",\"rating\":8.9}"
but got:
^
<interactive>:10:1: error:
Variable not in scope: encode :: Anime -> t
-- |
+ -- >>> import Data.Aeson
-- >>> encode favourite
-- "{\"title\":\"One-Punch Man\",\"rating\":8.9}"
--
favourite :: Anime
favourite = Anime "One-Punch Man" 8.9
Total: 2; Tried: 2; Skipped: 0; Success: 2; Errors: 0; Failures 0
Examples: 2; Tried: 2; Skipped: 0; Success: 2; Errors: 0; Failures 0
しかし、図書館は密接に結びついているようだ
cabal-install
それ以来cabal-install
生成メタデータplan.json
ファイル.結論
読書ありがとう!
記事では、私たちはDocTestの概念を見て、Haskellでそれらを定義する方法を学びました、そして、私たちがそれらを確かめるのを助けることができる2つのライブラリの概要を与えました:
doctest
and cabal-docspec
.このシリーズの次の部分では、私たちの構成と内部の
cabal-docspec
詳しくは.更新を維持するには、以下のフォームを介してニュースレターを購読または購読してください.Reference
この問題について(Haskellのdoctest入門), 我々は、より多くの情報をここで見つけました https://dev.to/serokell/introduction-to-doctests-in-haskell-1hh5テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol