fc2ブログ

makopi23のブログ

makopi23が日々の生活で感じたことを気ままに綴るブログです。

「『JUnit実践入門』写経・実践会 in 横浜 #3」に参加しました

2013/2/2(土)「『JUnit実践入門』写経・実践会 in 横浜 #3」に参加してきました。

connpass(告知サイト)
http://connpass.com/event/1668/

Togetter
http://togetter.com/li/448707

以下の書籍の勉強会なのです。

JUnit実践入門 ~体系的に学ぶユニットテストの技法 (WEB+DB PRESS plus)JUnit実践入門 ~体系的に学ぶユニットテストの技法 (WEB+DB PRESS plus)
(2012/11/21)
渡辺 修司

商品詳細を見る


参加者は13名くらいでしょうか。
んで、直前に@t_wadaさんが飛び入り参加されました。
TDD界隈では有名な方ですねー。12月のDevlove2012でも講演を聞いてきてブログにも書きました。

t_wadaさんが来るとあって、みなさん先日発売された以下の書籍にサインを貰うべく、買い出し部隊まで結成w
(t_wadaさんはこの書籍の訳者の一人なのです)


SQLアンチパターンSQLアンチパターン
(2013/01/26)
Bill Karwin

商品詳細を見る


主催者の @shinyaa31 さんが近場の大型書店に電話で問い合せ、即席で5冊確保。
んで勉強会中にt_wadaさんのサイン会が開かれました。
こーゆう飛び込みイベント、らしさがあっていいですねー

ちなみに私、この勉強会には今日が初参加でした。
前々からこの勉強会には興味あったのですが、都合が合わなかったりして参加できなかったのです。

今日は11章「テストダブル」が勉強会のターゲットでした。
先日書籍を購入し、8章くらいまでは写経まで終え、今日の午前に11章を読んでから参加しました。

以下、今日行われた議論のメモ。


『JUnit実践入門』写経・実践会 in 横浜 #3 from shinyaa31

■11.1節 「テスタビリティを高めるリファクタリング」

■お題1: private メソッドはテストするべきか否か?

■privateメソッドををpackage privateに変更してテストしている。
 package privateだと、公開範囲は最小限にして、テストプログラムを同一のpackageに属させてテストできる。

■privateメソッドは本質的に閉じてるんだから、テストやらなくてもいいでしょ。

■privateメソッドはリリースする機能とは直接関係ないから、テストやらなくてもいいのでは。

■Javaのリフレクションを使えばテストできないことはない。でもリスクになる。参照とか追えないし。

■privateメソッドを使っているpublicメソッドをテストすれば、privateメソッドも一緒にテストできる。
 でも、その場合はテストケースが爆発したりするし、引数とかも増えたりすることが多い。

■privateメソッドはpackageプライベートに格上げして、コメントでなぜそうしたか、理由を書いておく。
 そして格上げしたコードをそのままリリースする。


■お題2: privateメソッドをテストするとき、その工数は誰が持つの?

■リファクタリングの工数は、誰が捻出するのか?という問題。

■永和システムマネジメントの「価値創造計画」という話では、リファクタリングの時間を確保して、
 お客さんからその分を請求する、とのこと。

■お客さんを説得して納得してもらうことが必要。

■受託の一括請負だと、難しいところもあるし、認められないこともある。SIerだと難しい。

■自社開発だと、汚い家に住みたくない、というのでリファクタリングをやる。


お題3: 生産性という言葉について

■生産性、という言葉は使うべきではない。

■価値は、提供する機能と、それを実現するためにかかった時間、で測るべきでは。
 
■COBOLの時代なら、生産性という概念は確かにあった。コピペ文化で、書いたもん勝ち。
 
■工場の製造ラインにあった生産性の概念を、そのままソフトウェアに持ってきたのがCOOBLの時代だった。


■11.2節 「テストダブルとは?」

■モックの利用場面が思いつかない。

■モックは、メソッドが呼ばれたか呼ばれてないかをテストするもの。

■メソッドが呼ばれたことを確認するテストをやったことある人いるか?
 → 参加者の中にはいなかった。。。

■「xUnit Test Patterns」という書籍を渡辺さんが訳して、Webから見れる。

xUnit Test Patterns: Refactoring Test Code (Addison-Wesley Signature Series (Fowler))xUnit Test Patterns: Refactoring Test Code (Addison-Wesley Signature Series (Fowler))
(2007/05/21)
Gerard Meszaros

商品詳細を見る



■モック/スタブ/スパイの違い
 ・モック: 
  スタブとかスパイの上位互換。

 ・スタブ
  そのままだと扱いにくいものはテストを不安定にするので、それを置き換える。
  (扱いにくいものを置き換えるためのもの)

 ・スパイ
  戻り値がないので確認の方法がない場合がある。そういうのをテストしたい場合に使う。
  呼ばれる側のものを差し替える。

■モックは、スタブやスパイの振る舞いも包含している。

■モックには2種類ある。

Strict Mock
 言われてないことが発生したら即テストを失敗させる。

Lenient Mock
 スタブ+スパイ。いわゆる、緩いモック。

■先にStrict Mockが登場したので、そちらばかり注目されてる状況にある。

■Strict MockとLenient Mockは、アサーションのタイミングが違う。

 ・モック(Strict Mock)
  アサーションを先にやる。最後はベリファイをやる。
  こーゆうことが起こるから、後はよろしくな、というスタイル。

 ・スタブとスパイ(Lenient Mock)
  作る→テスト→アサーション、の順。

■Strict Mockはプロダクトモックと密接なので、テストのコストがかかるのでは?
 → 実際かかる

■モックの力は強力。惚れ込んで、痛い目をみて、元に戻ってくるくらいがちょうどいい。

■「Fragile Test」という用語がある。何かを変えるとテストがいきなりどかーんと壊れる。
 崩れやすい、脆いテストのこと。

■モックを使いすぎると、リファクタリングしたくなくなる。(負の連鎖の不幸)

■モックは、楽にスタブやスパイのように使える。勉強の手間が減る。

■TDDのMLには2種類の人がいる。

 ・Mockist:
  モック急進派の人たち。例えば書籍「実践テスト駆動開発」の著者とか。

 ・Classicist:
  モック古典派の人たち。例えば、Kent Beckとかt-wadaさんとか。
  Kent Beckは、書籍「実践テスト駆動開発」の書評で、「これは私の遣り方と違うが良い本だ」と言っている。
  (モック古典派だけど、書評を頼まれてモック急進派を褒めざるを得ない状況だったみたい)

■Classicist vs Mockist
 http://codebetter.com/iancooper/2008/02/04/classicist-vs-mockist-test-driven-development/
     
■モックは設計ツールとしては凄く良い。使われ方を必ず考えるようになるので。

■周りをモックで囲むと、木を見て森を見ず、にならないか?
 → 全体を見えなくするために周りをモックにする、のがモックの役割。
   全体を考えてするテストは、モックテストとは別物。なのでそれで良い。

■DIもInjectionされまくる。全体を知らない。そのおかげで依存度が下がり独立性が高くなる。
 ただ全体性は見えない。

■そのへんのバランスが大事。自分のちょうどいい間合いを自分で知る。
 モックという道具があることを知る。

■テストには濃淡がある。例外的な条件を作りやすいのがスパイとかモック。

■DBを落とした状態でテスト、とか、ファイルシステムの容量あふれたとか、例外条件を作りやすいのがテストダブルの利点。

■代役(テストダブル)が本物と同じということを保証するのは、結局のところ人間。ここが致命的。

■本物の方の仕様が変わったのに、モックをメンテしてないと、モックのテストは通るのに何故か本番でコケます、という事態になる。
→ なので、モックの使いすぎテストだけやるのはダメ。


■11.3節 「Mockitoによるモックオブジェクト」

■Mockitoの発音について。
 ・今日の勉強会では、「モック伊藤」連発状態w
  Togetterに「モック伊藤」ネタがある。 http://togetter.com/li/422376
 ・t-wadaさんは「モヒート」と発音してる。
  → モック + キラキラネーム + ググりやすい の3要素がある。

 ・Mockitoの開発者は「モキート」と読んでるらしい。由来はカクテルの名前。

■Seasar2を使ってるプロジェクトでEasyMockを使ってる。
 → なぜなら、Seasar2からEasyMockを使いやすいようになっているため。

■モックのライブラリは、プロダクションとフレームワークの相性で選定する。

■2002年くらいの頃は、モックを使うときにメソッド名を文字列で書いていた。
 → これからこーゆうメソッドが呼ばれるからよろしく、という書き方。
   (「こーゆうの」の部分を文字列で指定していた)

 → IDEでリファクタリングが着いてこなかった。。。

■後発のEasyMockとかMockitoは、インタフェースで書けるようになってIDEで補完されるようになった。
 → これまでの反省から、上手くするコツを取り入れた。

■t-wadaさんのモック歴:
 
 jMockで痛い目 → EasyMock → Mockito

■現在はmockitoが第一候補。

 ・バランスが良い。
 ・語彙と考え方が一致してる。
 ・やりすぎてないところがいい。

■モックライブラリを選ぶコツ

・語彙を理解して実装されているか
 ・モック、スパイ、テストダブルという語彙がライブラリ名に現れているか

■モックが高機能になるほど、レガシーコードがテストできるようになってしまう。
 → レガシーコードを改善しようとする意識が働きにくくなるという負の面がある。。。

■正統派モックライブラリを使うのが良い。魔改造なのは用途限定で。。。

■プロジェクトにモックを導入しようとしてみた。
 → 比較的上手くいっていて、メンバーが結構学んでくれた。
 → なぜなら、JUnitでテストができなくて困った思いをモックが解決できると知ったから。
 → テストが成長するのと同時に人も成長する。

■Mockistのマップがある。

■書籍「レガシーコード改善ガイド」 其の壱

p.12, p.14, p.17あたりに、ユニットテストのスコープを定義している。
(これはユニットテストで、これはユニットテストではないという区分け)

→ ちょっとやりすぎな気がする。。。

■書籍「レガシーコード改善ガイド」 其の弐

テストのスピードについて言及している。
(~以上時間がかかるのテストは、ユニットテストではない、と言ってしまっている。)

→ でも、最近はスピードは金で買う時代。
  スピードがユニットテストの判断基準になることは減ってきている。

■モックを作ると、対象特有の動作が検知できなくなることがある。
 例えばDBをモックに置き換えると、DB特有のエラーが検知できなくなる。

■ネットワークアクセスはモックやスタブにする。あとは特殊な環境も。


■@sue445 さんによるLT「TestCode Refactoring Using ExternalResource 」

TestCode Refactoring Using ExternalResource #junitbook from sue445 Sueyoshi


■継承を使ってSetupとかTeardownとかはやらないほうがよい。

■代わりに、@ruleを使って初期処理・終了処理を抜き出すべし。

■JUnit3の時代だと、継承は避けられなかった。

■JUnit4からJunitの世界に入る人は、継承をそんなに使わないのが当たり前になる。


■@t_wadaさんへの質問タイム

■11.1節のお題「private メソッドはテストするべきか否か?」に関して

■privateメソッドはテストすべきでない。publicメソッド経由でテストできるはず。

■自分にとって大事なprivateメソッドは、別のクラスのpublicメソッドに抜くべき。

■privateメソッドをテストしたい状況は、そのprivateメソッドに責務を持たせすぎでは。
 → 分割していくべき。privateではなくpublicの責務として抜き出していく。

■privateメソッドは、リフレクションとか使ってテストはできるが、やったとしても幸せにはならない。


■11.1節のお題「privateメソッドをテストするとき、その工数は誰が持つの?」について

■お客さんにリファクタリングの重要性を説得するための統計資料はなかなか出てこない。
 → 結局は、たらればの話になって、感覚的な話になってしまう。

■プロジェクトへの価値は、機能を予想可能な間隔でリリースできること。
 → このままリファクタリングしないでいくとヤバくなる、ということをお客さんに理解してもらうべき。

■「リファクタリング工数」という言葉が出てきた時点で負けでは。

■リファクタリング自体は価値を産まない。

■リファクタリングはプログラミングの一部としてやる。

■リファクタリングの許可を求めにいって、OKがでることはまずない。

■リファクタリングは日々の作業にまぶして、ちょっとずつやっていく。日々のプログラミングに組み込む。

■自動テストを書くのも、リファクタリングも、プログラミングに入れてしまわないと実行不可能。


■11.1節のお題「生産性という言葉について」

■「生産性」という言葉が出た時点で負けかなと思っている。

■「生産性」はコード量ではなく、時間で測る。

■品質が同じものをどれくらいの時間で届けることができるか。

■自分が見積もった量と、実際にできた量がだんだん一致してきた時に、ベロシティは生産性と呼べる。

■出来る人ほどコード量は少なくなる。

■唯一変わらないのは、人間のスペック。
 → 短い行数で、少ない暗記で実現できるプログラミング言語は生産性が高いと言える。

■ファンクションポイント見積もりの方がステップ見積もりの方が良い。

■生産性は、他の人と比べても意味はない。
 そうではなく、昔の自分と比べる。その場合は、生産性という言葉はありえる。

■研究開発と製品開発では、生産性はぜんぜん違う。研究開発では製品開発ほどテストは要求されないので。
10倍くらい生産性が異なるので、お互い話がまったく噛み合わない。

■生産性が悪かったのか、見積が悪かったのかは、プロジェクトの最後にならないとわからない。


★感想:
上のような熱い議論が約4時間にわたって繰り広げられ、とても濃い時間でした。
あと、勉強会の会場なんですが、ジョジョが全巻置いてあって、私、この日がジョジョでびゅーでした。
次回は少し早めに行って、ジョジョの続きを読もう。。。

テストは書いた分だけ上達する、とは以前t_wadaさんがおっしゃっていましたが、この本だけでもきちんと写経していこうと思います。
あと、goosの写経会もどっかにないかなー。あれ一人でやるの辛いんで。。。

次回開催は3/3の予定だそうで、次も写経して参加しようと思います。

最後に、主催者の@shinyaa31さん始め飛び入り参加の@t_wadaさん、みなさんありがとうございました。

-->