こんにちは、小井土さん。
大村ともうします。
このテーマ、以前から気にしていたのですが、今回、一連のスレッドに触発
され、いろいろ考えてみることができました。とてもここには書ききれませんし
まだ結論はでていないのですが、少しコメントを書かせてください。
◇
考え始めて、最初に戸惑ったのは「テストのためだけのメソッド」といっても
かなり曖昧なので、どういうものを考えているのかがよく分らないということ
でした。
「テストのためだけのメソッドは是か非か」という質問には、「そういう場合も
あるしそうでない場合もある」と答えるしかないのかなと思います。
そこで、このスレッドの最初にもどって確認した感想は [XP-jp:00913]に書いた
通りです。
[XP-jp:00889] でのsave()みたいなメソッドだけが議論の対象ではないだろうと
思っているのですがそこらへんはよく分っていません。
◇
それから、Javaの場合は、reflectionを使えばprivateな変数にもアクセスでき
るので、原理的には「テストのためだけのメソッド」を対象のクラスに作り込む
必要はないように思います。(テスト側のクラスで作ることもできますから)
だとすると、こういう議論は意味がないということになるのかもしれません。
それでも、そういうメソッドを作りたいということがあるとしたら、手間の問題
なのでしょうか。reflectionを使うより、ちょこっとメソッドを追加するほうが楽だとか。
そういうのは論理的には論外だけど、実践ではありかなという気もします。
とにかく、一番重要なのはテストをすることなので、reflectionを使うことに決めて
しまって、それで面倒くさくなってテストをやめたりしたら、本末転倒ですから。
◇
"Toru Koido" <koido@....jp> wrote:
from "[XP-jp:00898] テストのためだけのメソッド"
>私は、テストとクラスは独立したものであることが重要だと考えます。
>依存関係的には、テスト->クラスであって、この関係は物理的にも論理的も
>崩すことはよくないと考えます。
>
>テスト専用のメソッドを追加することは、この関係を論理的に壊していることに
>なるからです。
この点に関しては、私も感覚的にそう思っています。説明するとしたら、そのようにすると思います。
だから、もし、テストを作っていて、そういう必要性がでてきたら、対象のクラスの設計が
なんかおかしいんじゃないの? と再検討するのが道かなと思います。
必要な場合があるとしたら、たとえば、実装に固有のオブジェクトの状態を確認するとか
そういうことかなと思うのですが、ここんとこまだ考え中なんですけど、本当にそういう
必要性ってあるんでしょうか。今のところ、必要性があるというのは疑わしいと思っています。
テストの再利用性などを考えても、あんまり内部構造にからんだテストを作るとまずい
ですし... まあそれは、内部構造にからんだテストとそうでないテストを分けておくという話
にすればよいのかもしれません。
◇
あと、ひとつの考え方として、
「クラスは自分の機能をテストできるような手段を外部に提供しなくてはならない」
という方針で設計していくのもありかなと思います。
なんとなくもっともそうな言い方なのですが、どうでしょう。
その場合には、テスト専用のメソッドを作るのは許されることになります。というか
義務です。で、テストを視野に入れた設計が要求されることになります。
そういう世界も辻褄はあっているように思うのですが...
ただ、[XP-jp:00889] でのsave()のようなメソッドはこの範疇にははいらないので、
議論の流れからはずれているのかもしれないなという気はしています。
でも、相変わらずテスト専用のメソッドって何なのかわかってないんですけどね...
◇
それから、ここらへんの迷いは、JUnitでのテストでは、何をテストすればいいの?
という疑問がきっちり解明されていないからかもしれません。white boxテストだといっても、
クラスの内部構造にべったりのテストは、本当に望ましいのか? とかいう疑問は
あります。
◆
>C++のようなコンパイラでは良く、デバック版とリリース版とわけてテスト用のメ
>ソッドを
>クラスに組み込むことは良くやっていますが、これではリリース版ではテストができ
>な
>いことになるのでXP的には論外と思います。
この部分はxUnitのように、テストコードを対象のクラスの外側に作ることのメリットを
言われているんですよね。
これに関連して思い出すのは、Dylanという言語のMac上の実装だったApple Dylanと
いうシステムです。
Apple Dylanでビルドしたオブジェクトにはデバッグ版もリリース版もないのですよ。
細かいことは忘れましたが、デバッガはリモートデバッグみたいな感じで、実行中の
オブジェクトにアクセスし、別のところにあるデバッグ情報を参照、リンクしてソースと
バイナリの対応をとっていたように思います。
他の処理系でそういうのがあるのかどうか、知らないんですけど、とても強く印象に
残っています。
JUnitを使っていて、最近、そのことを強く思い出したんですが、こういうのはよく知られた
方法なのでしょうか。
と、あらぬ方向に話が流れたままですが、以上です