メッセージ。 - [技術] Gaucheでのテストの書き方(の1ケース)

# [技術] Gaucheでのテストの書き方(の1ケース)

いままでたくさんGaucheでプログラムを作ってきたが、あまりテストコードを書いたことがなかった。だけどここ数日、ちょっとテストを書く機会があって、けっこう勉強になっている。なかでも、値を返さないような関数のテストをどう書けばいいか分からなかったので、メールでshiroさんに尋いてみた。

そうすると親切に教えていただけたので、せっかくの情報が共有されていないのはもったいないので、ここで公開してみます(shiroさんには許可をもらっています。ありがとうございました)。#<undef>を返す関数のテスト方法とか、valuesを引数なしで呼んだらどうなるかとか、あまり考えたことがなかったので勉強になった。テストの書き方(シンタックスではなくセマンティクス的なもの)って、案外ネットとかを調べても載っていないような気がする。

fujisawa:
 基本的なことを質問しちゃって恐縮ですが、
 s3-bucket-create 等で(values)を返しているのは、
 どういう意図があるんでしょうか? valuesを無引数で
 呼んだとき、どういう挙動をするのかよく分からず、
 テストをどう書こうかなーと思案中です。
 #<undef>を返すわけでもないんですよね…。

shiroさん:
 「戻り値が無い」ことを示すためです。まあ別に#tとか適当に返しといても
 いいのですが。valuesは渡された引数の数だけの値を返しますから、
 無引数で呼ぶとゼロ個の値を生成します。call-with-valuesの形で
 考えるとわかりやすいかも。
 
   (call-with-values (lambda () (values)) list) => ()
 
 テストについてですが、こういう副作用だけに意味がある操作の場合は
 そもそも戻り値を見る意味がないので、(1)操作実行後にその効果を
 別関数で確かめるか、(2)操作の実行が完了したことだけを、別の値を
 返すことで確かめるか、ということになります。
 
 (1)の場合の例:
   ;; まずバケットがavailableであることを確認
   (test* "bucket-availability" 'available
          (s3-bucket-availability "test-bucket"))
   ;; s3-bucket-create!する。戻り値は見ない。
   ;; 直後にもう一回availabilityを見て、確かに変化したことを確認する
   (test* "bucket-create" 'taken
          (begin (s3-bucket-create! "test-bucket")
                 (s3-bucket-availability "test-bucket")))
 
 (2)の場合の例:
   ;; まずバケットがavailableであることを確認
   (test* "bucket-availability" 'available
          (s3-bucket-availability "test-bucket"))
   ;; s3-bucket-create!して、そのあとで適当な値を返す。
   ;; s3-bucket-create!がfailすれば#<test-error>になるはずなので、
   ;; #tが返ってくれば少なくともエラーにはならなかったということがわかる
   (test* "bucket-create" #t
          (begin (s3-bucket-create! "test-bucket") #t)
   ;; 改めて操作の完了を確認
   (test* "bucket-availability after create" 'taken
          (s3-bucket-availability "test-bucket")> )

shiroさん:
 関連して、一般に「戻り値が未定義である」という手続きをテストするのにも、
 戻り値を比較したらだめですね。「現在のバージョンのGauche」では
 たまたま#<undef>を返すかもしれませんが、もともと未定義なんですから
 将来どうなるかはわかりません。
 意味のない戻り値として最後の式に(values)を使う作法は他の処理系のソースで
 見たんですが、「戻り値を使わないでね」というメッセージにはなると
 思います。
 
 ちなみに(values)で戻ってくるゼロ個の値 (という言い方も変ですが) を
 無理やり変数に代入したり引数に使ったりするのはSchemeとしては不正な
 プログラムです。Gaucheではいちいちエラーにしませんが、その時得られる値は
 でたらめです (通常、直前の計算でVMのレジスタに残ってる値がそのまま見える)。
2010-02-13 17:20:23 / ふじさわ / Comment: 0 / Trackback: 0

Comment

コメント投稿機能は無効化されています。

Trackback

TrackBack投稿機能は無効化されています。