メッセージ。 - [技術] Gaucheでのテストの書き方(の1ケース)
# [技術] Gaucheでのテストの書き方(の1ケース)
いままでたくさんGaucheでプログラムを作ってきたが、あまりテストコードを書いたことがなかった。だけどここ数日、ちょっとテストを書く機会があって、けっこう勉強になっている。なかでも、値を返さないような関数のテストをどう書けばいいか分からなかったので、メールでshiroさんに尋いてみた。
そうすると親切に教えていただけたので、せっかくの情報が共有されていないのはもったいないので、ここで公開してみます(shiroさんには許可をもらっています。ありがとうございました)。#<undef>を返す関数のテスト方法とか、valuesを引数なしで呼んだらどうなるかとか、あまり考えたことがなかったので勉強になった。テストの書き方(シンタックスではなくセマンティクス的なもの)って、案外ネットとかを調べても載っていないような気がする。
fujisawa:
shiroさん:
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のレジスタに残ってる値がそのまま見える)。
Comment
Trackback