Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

This branch is 1853 commits ahead of troter:master

Fetching latest commit…

Cannot retrieve the latest commit at this time

..
Failed to load latest commit information.
data
README-utils.md
README.md
common-lisp-tests.l
defun-builtin-tests.l
editor-tests.l
environ-tests.l
eval-tests.l
foreign-test.l
glob-tests.l
insdel.l
lisp-tests.l
nanri-master-change-tests.l
netinst-tests.l
random-tests.l
run-tests-helper.l
sequence-tests.l
simple-test.l
system-tests.l
typespec-tests.l

README.md

テストの実行方法

テストを実行するには

  1. unittest/simple-test.l (テストのフレームワークや便利マクロなど)を読み込む
    • 普通の lisp ファイルとして読み込みます
  2. M-x load-test-file から実行したいテストの書いてあるファイルを読み込む
  3. 以下のどれかで実行する
    • M-x run-all-tests - 読み込んだテストを全て実行
    • M-x run-tests-from-file - 指定したファイルから読み込んだテストを実行
    • M-x run-tests - 前回実行したテストをもっかい実行

すると "*Test Results*" というバッファに色々出てきます。最期の行に "ALL passed" とか "0 failed" とか表示されていればオッケーです。

全てのテストを実行するのであれば unittest/run-all.l を eval-bufferload-file やコマンドラインの "-l" オプションで読み込むのがカンタンです。

注意事項

(後で書く)

テストの書き方

テストは unittest/ 以下のてきとーなファイルに書きます。 簡単なものなら lisp-tests.l に追加、たくさんテストを書く場合は専用のテストファイル作っちゃってください。

個々のテストは deftest で書きます。こんな感じです。

(deftest テストの名前 (オプション)
  "説明文字列"
  テストする式
  => 正しい戻り値)

テストする式 と期待する挙動

deftest には、テストする式 とその式に対して期待する挙動を書きます。必要なら複数の テストする式 を書くこともできます。

期待する挙動は、戻り値、出力、マクロ展開、エラーが指定できます。1つの テストする式 に対して複数の期待を同時に書くこともできます。(ただし矛盾しない範囲で。エラー投げつつ値を返すとか無理です。)

オッケーなら non-nil を返す

テストする式 が真(non-nil)を返せばオッケー、という場合は 戻り値などを書く必要は無く、テストする式 だけ書いておきます テストする式 の後に => non-nil と書きます。

(deftest 1-is-not-zero ()
  (not (zerop 1))
  => non-nil)

2012-03-12 仕様変更

ひとつのテストに複数の テストする式 を書けるようにしたのに伴って、戻り値などの期待を省略すると「エラーでなければオッケー」という扱いになりました。

戻り値のテスト

テストする式 がこの値を返せばオッケーという場合は => 正しい戻り値 と書きます。

(deftest 1+2=3 ()
  (+ 1 2)
  => 3)

正しい戻り値 と実際の戻り値は equal で比較されます。比較関数を指定したい場合は オプション:compare 比較関数 とか書いておきます。

(deftest 1+2=3 (:compare =)
  (+ 1 2)
  => 3)

多値を返す場合は => 正しい戻り値 を実際に返ってくるだけ並べるだけです。 (暫定)テストする式 はきっちり指定された数の戻り値を返さないとダメです。多くても少なくてもダメです。

(deftest a-b-c ()
  "a と b と c を返す"
  (values 'a 'b 'c)
  => a
  => b
  => c)

細かい説明

  • 比較関数は評価されないので、関数名(シンボル)か #' なしのラムダ式を書いておく。
  • 比較関数には 正しい戻り値 と実際の戻り値が渡されます(この順番で)。
  • 正しい戻り値 は評価されないので、比較関数で頑張るか #.(...) で何とかする。
  • 実際の戻り値はきっちり指定された数の値(多値的な意味で)を返さないとダメです。

エラーを投げる

テストする式 がこの型のエラーを投げればオッケーという場合は !! エラーの型 と書きます。エラーの型 はエラーの名前(type-errortoo-many-arguments など)をクォートせずに書きます。

(deftest not-a-number ()
  (+ "foo" :bar)
  !! type-error)

出力のテスト

テストする式*standard-output* などに何か書き出せばオッケーという場合は >> 正しい出力 と書きます。

(deftest hello-00 ()
  (princ "hello")
  >> hello
  => "hello")

出力先を指定するには オプション:output 出力先 とか書いておきます。

(deftest hello-01 (:output *trace-output*)
  (princ "hello" *trace-output*)
  >> hello
  => "hello")

細かい説明

  • 実装上の都合で出力先の指定はシンボルをクォートせずに書く必要があります。
  • >>(スペースを含む)から改行までが正しい出力です。
  • 複数行の場合は >> 出力 を複数行に渡って書きます。
  • 最期に改行する場合は、空の >> を書いておきます。
  • 出力だけを書いて戻り値を書かなかった場合、オッケーなら non-nil を返すものと解釈されます。nil を返す場合は => nil と書く必要があります。
    • non-nil を返す場合は戻り値を省略できますが、deftest の終わりの閉じカッコは新しい行に書く必要があります。(そうしないと出力の一部とされてしまう。)

めんどい例:

(deftest hello-02 ()
  (format t "hello~%hello~%")
  >> hello
  >> hello
  >> 
  => nil)

マクロ展開のテスト

テストする式 がマクロ呼び出しで、特定の式に展開されればオッケーという場合は == 展開後の式 と書きます。

(deftest setf-to-setq ()
  "シンボルへの setf は setq に展開される"
  (setf x 1)
  == (setq x 1)
  => 1)

展開後の式 に uninterned symbol(#:G0381 みたいなの)があると、実際の展開形の同じ場所には uninterned symbol があればオッケーになります。gensym で一時変数を作ってる場合に使います。

細かい説明

  • テストする式macroexpand-1macroexpand のどちらかで展開した結果が 展開後の式 と一致すればオーケー。
  • マクロ展開の期待を書いたのに テストする式 がマクロ展開されない場合は fail します。
  • (暫定)今のところレキシカル環境には対応してない。

説明文字列について

テスト実行してダメだった場合にダメだった詳細と一緒に表示されます。何のテストなのかわかりやすい説明を書いとくとダメだったときに助かるのでなるべくなら書いておいて欲しいですが、めんどかったら省略できます。

テストの実行を中断する

何らかの都合によりテストの途中で一旦実行を中断しないといけない場合には、テストする式 として :break と書いておきます。:break を含むテストを実行すると、:break のところで一旦止まります。その後(デフォルトでは)タイマーで自動的に続行されます。

タイマーからテストを実行すると間違った結果が出たりすることがある(滅多にないとは思うのですが)ので、何かおかしい場合には自動的な続行を無効化してみてください。

(setf *auto-continue-after-break* nil)

無効化した場合、中断されたテストは M-x continue-run-tests で続行できます。

Something went wrong with that request. Please try again.