doctest とは
テストコードと結果をコメントに書いておくと自動的にテストしてくれるもの。Python の doctest から来てます。Elixir はこれを言語として組み込んでいます。
下準備
サンプルコードを用意してみました。
doctest の対象としたいモジュールを、doctest
マクロを使ってテストコード側で指定します。以下のdoctest Doctest.Hello
部分。
ちなみに doctest
マクロは ExUnit.DocTest
に定義されていて、use ExUnit.Case
することで __using__
コールバック経由で import されるようです。__using__
は Ruby でいうところの、included
っぽい動作をしています。
defmodule DoctestTest do
use ExUnit.Case
doctest Doctest.Hello
end
この指定をすることでmix test
したときにテストと合わせて、doctest も行われるようになります。失敗したときの実行結果はこんな感じになります。
$ mix test
Compiled lib/doctest/hello.ex
Generated doctest.app
......
1) test doc at Doctest.Hello.world/0 (7) (DoctestTest)
** (ExUnit.ExpectationError)
expected doctest: Doctest.Hello.world
to evaluate to: "hello world"
instead got: "goodbye world"
stacktrace:
lib/doctest/hello.ex:9: Doctest.Hello (module)
.
Finished in 0.1 seconds (0.1s on load, 0.00s on tests)
8 tests, 1 failures
書き方
メソッドのドキュメント部分に iex 実行画面のフォーマットのままテストコード、結果を書きます。
面白いことに iex での実行結果をそのまま貼付けると動きます。試しにiexで実行、結果をそのままドキュメントとして貼付け、でテストコード&ドキュメントがかけるのは嬉しい!
@doc """
# iex コンソール出力結果をそのまま貼付け
iex(1)> Doctest.Hello.iex_console_result
"iex console result"
"""
def iex_console_result do
"iex console result"
end
以下に書き方のパターンを載せます。
基本
@doc """
# 基本
iex> Doctest.Hello.world
"hello world"
"""
def world do
"hello world"
end
複数のテスト結果を一度に得る場合
@doc """
# 複数のテスト結果を一度に得る場合
iex> Doctest.Hello.multiple(1)
2
iex> Doctest.Hello.multiple(3)
6
"""
def multiple(num) do
num * 2
end
複数のテスト結果を別々に受け取る場合
@doc """
# 複数のテスト結果を別々に受け取りたい場合
iex> Doctest.Hello.add(1, 2)
3
iex> Doctest.Hello.add(3, 4)
7
"""
def add(x, y) do
x + y
end
複数行に渡るテストコードの場合
@doc """
# 複数行のテストコード
iex> Doctest
...> .Hello
...> .multiple_line
"multiple line"
"""
def multiple_line do
"multiple line"
end
例外のテスト
@doc """
# Exception をテストする
iex(1)> Doctest.Hello.raise_message
** (RuntimeError) raise!!
"""
def raise_message do
raise "raise!!"
end
ドキュメント
doctest については以下にあります(今回の記事はこれのまとめです)。これ以外は見つけられませんでした。
http://elixir-lang.org/docs/stable/ExUnit.DocTest.html
何故 doctest ?
実は一瞬だけ Python の doctest をチラ見したことがあって、そのときはコードと一緒にドキュメント兼テストコード書いておけるの便利ーと少し感動して、感動したまま終わってしまいました。で advent calendar で Elixir のことを調べることになって、再び会うこととなり良い機会だったのでまとめてみました。
このエントリは Elixir Advent Calendar 2013 の5日目でした。明日は @tsuka さんです!