Rubydoctestの挙動メモ

2012 年 1 月 6 日 by 山平

前回、Rubydoctestのドキュメントを邦訳しました(rubydoctest – Example Usage の邦訳)
本家のドキュメントも少ないのですが、他に情報らしい情報もほとんど見当たりません。
唯一見つけた情報も使い方というよりは紹介ですし、かなり古い記事です。

なので使ってみた結果をここに記録しておきます。

呼び出しに関すること

微妙なパス指定

ファイル名の指定に”*(任意の文字列)”,”?(任意の文字)”が使えるようですが、”**(任意の階層)”は使えないようです。
なので、

  • ./aaa/astk.rb
  • ./aaa/bbb/msptmy.rb
  • ./xxx/inds.rb

上のような構成で”rubydoctest **/*.rb”とタイプしてもmsptmy.rbはテストされません。

rubydoctest **/*.rb
=== Testing ‘xxx/hoge.rb’…
OK  | Default Test
1 comparisons, 1 doctests, 0 failures, 0 errors
=== Testing ‘aaa/astk.rb’…
OK  | Default Test
1 comparisons, 1 doctests, 0 failures, 0 errors

ここはトップレベルの指定だけで全部テストしてほしいところです。

シンプルなirbセッションを貼り付ける

irbの結果を張り付けるだけでテストコードが作成できるのは便利なのですが、シンプルなirbセッションを張り付けないと怒られてしまいます。
「シンプルなirbセッション」とは、「–simple-prompt」オプションを指定して起動したirbセッションのプロンプトのことを意味しています。

シンプルでない(デフォルト)の場合

$ irb
irb(main):001:0> 1+1
=> 2
irb(main):002:0>

シンプルなirbセッションの場合

$ /usr/bin/irb –simple-prompt
>> 1*1
=> 1
>>

なので「.bashrc」にエイリアスをつけておくのがいいと思います。

alias irb=’irb –simple-prompt’

テストに関すること

まず、挙動確認に使ったソースと動作結果を示します。

ソース「doctest.rb」

#!/usr/bin/ruby

#doctest: 事前にインスタンスが作れる
# テスト中は変数が生きているので、以降のテストでも利用可能
# クラスの場合などに便利
#>> d = Doctesttest.new
#>> d.class
#=> Doctesttest
class Doctesttest

#doctest: 足し算
#>> d.add(1,2)
#=> 3
def add(a, b); a + b; end

#doctestディレクティブがないと前のテストに
#含まれている用に見えるけど、無視はされてないっぽい
#>> d.sub(1,2)
#=> -1
def sub(a, b); a - b; end

#doctest: ここでdoメソッドを試す
# !!!ディレクティブで止める
#!!!
def do(expression); eval expression; end

#doctest: !!!ディレクティブはexitで抜ける
# 抜けた後はrubydoctestのセッションに戻る
# 2回"exit"とタイプしないといけないのはなぜ?
#>> d.do "1+1"
#=> 2
end

テスト結果

$ rubydoctest doctest.rb
=== Testing ‘doctest.rb’…
OK  | テスト中の変数は最後まで生き残る
なのでクラスのインスタンスを最初に作れば
以降のメソッドで使いまわせる
OK  | 足し算
OK  | ここでdoメソッドを試す
!!!ディレクティブで止める
>> d.do “1+2+3”
=> 6
>> exit
>> exit
OK  | !!!ディレクティブはexitで抜ける
抜けた後はrubydoctestのセッションに戻る
2回”exit”とタイプしないといけないのはなぜ?
4 comparisons, 6 doctests, 0 failures, 0 errors
$

事前に宣言したオブジェクトを使える

ソースの先頭でDoctesttestクラスのインスタンスを作成しています。
テスト中はこのインスタンスが生きているので使い回すことができます。
クラスのメソッドを確認するのに毎回オブジェクトを作る必要はありません。

doctestディレクティブ

doctestディレクティブが記述されていないテストは「OK | メッセージ」という形式で結果が出力されませんが、テストとしてはカウントされているようです。
(最後の「4 comparisons, 6 doctests」に注目)

クラスのテストの場合には、1メソッドに1doctestディレクティブで記述するのが読みやすそうです。

!!!ディレクティブ

テストの途中でirbセッションを触ることができます。
大量の自動テストの途中で止まってしまうことを考えると不便ですが、デバッグ中に毎回入力する内容までを自動化すると便利です。
ただし、エラーが発生した場合、通常のirbセッションと違って変なスタックトレースが出力されてしまって問題のある箇所が特定できません。。。

テストにセッションを返す際は「exit」と入力すればよいとドキュメントにあるのですが、なぜか2回入力しないと戻りませんでした。

結論

便利そうで意外と不便なのですが、それでも使いたくなる魅力を感じるのは私だけでしょうか?
何を重視するかによっても評価は変わってくると思いますが、

  • ソースファイルの中に一緒に記述できるので、忘れたころにソースを触る必要が合った場合にテストコード紛失の恐れがない
  • コメントとして記述するのでrdoc等のドキュメントにもテストコードが出力され、一粒で二度おいしい(これもソースファイルだけの管理で紛失の心配がない)

この二点にたまらない魅力を感じるのは、私の「作っては放置し、久しぶりに触っては苦労する」という習慣のせいなのでしょうが。。。

以上です。

タグ: ,

TrackBack