Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
14
Help us understand the problem. What are the problem?

More than 5 years have passed since last update.

@ma2ge

Elixir の doctest 書き方まとめ

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

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
14
Help us understand the problem. What are the problem?