LoginSignup
29
15

More than 5 years have passed since last update.

Elixir の doctest 書き方まとめ

Posted at

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 さんです!

29
15
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
29
15