『JUnit実践入門』写経・実践会 in 横浜 #3 を開催してきた #junitbook


(今回の第11章は『テストダブル』なのですが何故か積まれる書籍『SQLアンチパターン』。その理由は…)


JUnit実践入門』写経・実践会 in 横浜、今回第3回目は『第11章 テストダブル』が対象範囲となっております。

JUnit実践入門 ~体系的に学ぶユニットテストの技法 (WEB+DB PRESS plus)

JUnit実践入門 ~体系的に学ぶユニットテストの技法 (WEB+DB PRESS plus)


会場は毎度お馴染み横浜タネマキ。今回も前回同様貸切開催です。


「『JUnit実践入門』写経・実践会 in 横浜」、これまで前々回、前回と会を重ねて来た中で内容の濃いディスカッションを展開してきたのではありますが、今回はその濃度度合がサプライズ的な参加者の登場により一気に濃い内容・特濃!なものとなりました。


司会進行に用いたスライド資料はこちらです。

和田卓人(@t_wada)さん、急遽参戦!!!

その報せは突然やって来ました。

このツイートに、参加者一同は勿論快諾!

また、『和田さんが来られるのであれば...』という事で参加者の皆さんに要望を募った上で、近所の書店で先日発売された書籍『SQLアンチパターン』の在庫を確認し何とか5冊確保。(TOPにも貼った写真はその時のものでした)

SQLアンチパターン

SQLアンチパターン


開催時間中に途中参戦の形となりましたが、合流以降は和田さんを交えてのディスカッション三昧。内容は多岐に亘り、要所で深い話も聞けるなどして非常に有意義な時間を過ごす事が出来ました。(※その内容については後述するメモにて。)


また、和田さんも『横浜タネマキ』の漫画品揃え具合には感銘を受けておられた模様。


そして終盤には即席サイン会を実施w 上記で確保した計5冊+事前に購入して持参された方の2冊に本日付けで和田さんのサインを頂く事が出来ました。ありがとうございました!


そしてあの人のステッカーも...

製作者のTwitterID:@sue445さんから頂きました。他の参加者の方々も希望者には配布。これもまたレアですね〜。ありがとうございます!

勿論和田さんにも展開致しましたw 世界に広がるいろふさんの輪。

書籍対象範囲ディスカッション【第11章 テストダブル】

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

このセクションで挙がった質問と言うか、テーマは以下の3つ。こちらのテーマについては和田さん合流前になされていたもので、『和田さんが来られたら改めてこのテーマ・質問で聞いてみよう』となり、実際にお聞きしました。途中緑字になっている部分が和田さん合流以降のディスカッション内容になります。

  • privateメソッドをテストすべきか否か。
    • 出来る事は分かってるんだけれども、そもそも作業としてやる必要があるのだろうか…?
    • private=外には見せないものなのだから、テストは要らないんじゃない? 
    • ビジネスロジック等の場合、publicにしてしまうと影響範囲が大きくなってしまうので、閉じた世界で終わらせたい。
      • でも一方で重要な部分なのでテストもしたい。悩ましい...。
    • privateメソッドで数百行・1000行とかあったりすると、publicにスコープを上げるのも躊躇ってしまう。
    • テストする際にパラメータが増えたりすると、privateのままにして置くべきかとも思う。
    • 幾つか出た対処法:
      • クラス設計を見直す・クラスメソッド構成を工夫して対処。
      • 言い訳コメントを書いて格上げ。
      • パッケージプライベートにスコープを移動。
    • (和田さん):(privateメソッドのテストは)すべきでは無い。
      • すべき時、となった時は何かがおかしい時。
      • privateメソッドはpublic経由でテスト出来る。
      • 大事な振る舞いなのであれば、責務を変える。他のクラスのpublicメソッドとすべき。
      • そういうタイミングが発生する事=そのクラスに責務を集中しているのではないか?と考える。
      • (仮にprivateメソッドを)テストできたとしても、何ら幸せにはならない。
      • 過去公開されてきた種々のモックライブラリも、『privateメソッド使えます』と星取表合戦の材料に。(和田さん曰く『黒魔法的な軍拡競争』)
      • privateメソッドがアンタッチャブルなのであれば黒魔法使おう、でファイナルアンサー。
        • 黒魔法の使い方は用法用量を守って溺れない程度に。
      • 黒魔法を使わずに改善出来るのなら、そっちで頑張ろう。
  • リファクタリング』に関する作業が一定量掛かる場合、誰が対応する工数を持つのか。
    また対応する工数に関する対処法など。
    何か効果的な資料などあれば教えてほしい。
    • ここでの『一定量』は瞬殺で完了、とかでは無く数時間や数日トータルで掛かるようなものを指す。
    • 質問者は『別途時間を設けている』とコメント。
      • また、質問者は以前この質問を平鍋さん()にぶつけて見た事があるらしい。その時の平鍋さんの回答は『リファクタリングは(お客さんには)請求しています』とコメントしていたそうです。
    • やる/やらないであれば、当然『やる』のが良いのは分かるのだけれど…。
    • SI屋で一括、とかの場合、リファクタリングの価値は見込めない?
      • その場合、リファクタリングを行わない→しばらくして蓋空けたらビックリ、とかは良くある。
      • サービス開発とかなら、その点価値を見込みやすいのはある?
    • リファクタリングの名前は出さずに工数に含めて対応。また名前を出して普通に対応する事も。
    • 良好な関係を築けた後であれば出しやすい。
    • そもそも受託の場合、上司がリファクタリングを許してくれるのか?という点も重要。
    • (和田さん):(こういったテーマでの話は)なかなか出てこない。たらればの話になってしまう。
      • 大企業が2つのチームで比較してみた時の資料で出てくる程度?
      • リファクタリングをしていない時の影響:してないと時間が掛かり、価値を提供出来なくなる。
      • 説得する際は『このままだと機能追加もバグ修正も遅くなりますよ』と言う。
      • リファクタリング工数を設ける』事が出来ればかなり良い方。
      • リファクタリング』という言葉で一括りにするのでなく、別の表現…例えば『アーキテクチャジャンプ』等で言い換えるべき事象もあるのではないか。
      • まぁ、そもそもリファクタリング工数って言葉が出てくる時点で負けが混んでいる感じではあるw
    • リファクタリングは日々の開発にまぶす・日々の開発に組み込む感じが一番良い。そうで無いと継続的・効果的な対応は厳しい。
    • 『許可を求めるな謝罪せよ』の精神で。
  • 『生産性』という言葉について。
    • 何で数値化したいのだろうか。
    • 物差しとしてこういうのを使ってる、というのがあれば。
    • →物差しは過去の遺物、使うべきではない?(ステップ数、N件辺りのバグ数など)
    • 『問題に対して解決した時間』とかが分かり易いのかも。
    • 最近だと『ベロシティ』の概念が分かり易い?
    • 元々製造業等から基準をIT業界に"輸入"したものが意図しない形で伝わっている/今の時代にそぐわなくなった?
    • (和田さん):この言葉も言ったら負けの世界(笑)
      • この『物差し』、人によっては20倍、30倍異なる。
      • それを明確な物差しで測ろうとした場合にどう測るか?
      • 定義は組織によると思うが、AよりBの方が生産性が高い…これを直感的に感じる事はある。
      • "時間"だと思う。XP、アジャイルで言うベロシティが近いのではないか。
      • 自分で出来ると見積もったものに対するズレ・補正値。実際にできた機能の量が一致してきた時点でベロシティ=生産性と呼べるだろう。
      • 人で比較する場合、出来る人の方がコード量が少ないだろう。
      • 定量化するには何かを数えないといけない。
      • 何行辺り何件のバグ、と言うのもあまり意味は無い。
        • (近年推奨されている環境(CIなど)で稼働させて行くと、)予想している出るべきバグ数もずっと少なくなり、軽微なものは実装中になくなり、過程で出るとすれば致命的なものだったりする。(そういう視点・切り口は想定してなかった!みたいな予想外のもの)
      • 変わらないのは人間のスペック。言語が表現力が高くなっている。
      • また、『生産性が高い言語』と言うのはある。
      • 『生産性』という言葉を別の言葉に言い換えるべき。
      • ステップ単金が決まらないと決まらないところもあるそうです。
      • 機能見積もりが機能してない現状。
      • 生産性は、昔の自分達に対して取り続ける・予実を取る事の方がより正確なものになりうる。
11.2 テストダブルとは?


  • 書籍で言及されている『モック』の使い方(依存オブジェクトの呼び出しを検証する)でテストを行う、というケースが今イチ思いつかなかったのだが、皆さんはどう?
    • 質問者同様、あまりこの文脈での利用者は居なかった模様。
  • ここではスタブ・モック・スパイと3種類出て来ているが、モックとスパイの違いが今イチ分からん部分が…
  • (和田さん)この辺りについては、書籍『xUnit Test Pattern』に載っている。

xUnit Test Patterns: Refactoring Test Code (Addison-Wesley Signature Series (Fowler))

xUnit Test Patterns: Refactoring Test Code (Addison-Wesley Signature Series (Fowler))

("When To Use It"の項より抜粋)

Mock Objects can be either "strict" or "lenient" (sometimes called "nice".)

A "strict" Mock Object fails the test if the calls are received in a different order than was specified
when the Mock Object was programmed.

A "lenient" Mock Object tolerates out-of-order calls.
    • 文脈的には"strict"の方が先に登場し注目されてきた背景がある。
    • Strict Mock(厳格なモック)
      • 言われてない事、想定外の事が発生した場合、即テストを失敗させる。
    • Lenient Mock(寛大なモック)
      • 緩いモック。想定外の事が来ても失敗させない。
    • また、モックとスタブ&スパイについては以下の様に検証実施順序も異なる。
      • モック
      • スタブ・スパイ
        • JUnitテストと同じ順序。準備(setup) → 実行(exercise) → 検証(verify)。

    • Strict Mockについては、プロダクトコードと密結合になりやすい傾向が。下手したら全滅の可能性も、工数も掛かる。
      • モックはデザインパターンと同じで『はしか』のようなもの。痛い目を見て戻ってくるものである。
        • Fragile Test問題を誘発…ここで失敗しなくてもいいじゃないか。これは実装のテストになってしまってる。
      • モックの強力さを知りつつ、使いドコロは気をつけよう。

実践テスト駆動開発 (Object Oriented SELECTION)

実践テスト駆動開発 (Object Oriented SELECTION)

    • Classicist
      • Kent Beckはこちらに属する。和田さんもこちらを支持。
      • Kent Beckが書籍『実践テスト駆動開発』の書評を頼まれて『私の考えと違うが、良い本だ』とコメントしているのがこの背景を踏まえると大変に興味深い。

    • DIもモックに近いものがある。偽物を差し込める。
    • システムテストの中で厳密なテストをしたいところとそうでないところがあるはず。
    • 例外テストはその辺モックがやりやすい。
      • 以前は『LANケーブル抜く』みたいなテストケース書いてた事もあった。

    • 『代役』が本物と同じ振る舞いをしているかどうかをどこで判断?
      • →そこが難しいところ。気付いたら挙動が本物と変わっており、代役が追いついていない。

11.3 Mockitoによるモックオブジェクト


  • Mockライブラリの選定基準について
    • 結局は選定者の好み?w
    • (和田さんのMock利用遍歴)
      • 1.10年前のモックはメソッド名を文字列で呼ばれる事が多かった。モック対象のメソッド名をgetNameで渡してたり...
      • 2.レコーディングフェーズ:interfaceを介してレコーダーのリプレイが出来る。教育的効果が高い。インタフェースの概念も学べる。後発のEasyMock/Mockito等が該当。
      • 3.そして現在はMockito。(jMock -> Easymock -> Mockitoへ)
        • Mockitoはバランスが良い。やり過ぎてない。語彙と考え方が一致している。
        • モック・スパイ等の語彙がメソッドなどに現れてくるもの、語彙を理解して実装されているものはお勧めし易い。Mockitoはその点で優等生系とも言える。
      • 4.一方で、Javaに於けるMockライブラリで魔改造?と思えるものがある:→jMockit
      • HttpServletRequestからパラメータを取りたかった(けどどうしても出来なかった)ので使った。
      • jMockit魔改造っぷりがよく分かる比較図。
    • 魔改造について
      • モックが高機能になるほど、レガシーコードがそのままテスト出来てしまい、(レガシーコードを)改善しようという意識も働きにくくなってしまうというマイナス側面も。
      • なので、ここぞ!という時に魔改造的なものを利用するに留めておく事が望ましい。正統派モック・魔改造モックの利用用途を見極めて。
      • PartialMockとして部分的に用いるのはアリ。

  • モックライブラリ導入をしてみた、という参加者のお話
    • 比較的すんなり入った。メンバーが学んでくれた。
    • まずはモックを使わないでテストを書かせる→書けない…→『そこでこのモキートですよ!』パターン
    • テストと一緒にメンバーも成長出来るような形で作れれば。
  • テストの『粒度』について
    • 結合してしまったら、それはもう単体テストでは無い?
    • ユニットテストはどうあるべきか。
      • この点については、Mockist Mapなるものがあるらしい。(...キーワードで探してみたけど見つからず。)
    • 単体テスト=早さ重要。早さは金で買う時代。
    • 単体テストで出来るものは単体テストフェーズで。/ じゃあDBテストとかはどうなる?デメリットも大きい。→杓子定規的に定めるのも宜しくない。出来る所でやる。
    • 書籍『レガシーコード改善ガイド』に参考になる記述がある。(P.14〜P.17 "単体テストとは")

レガシーコード改善ガイド (Object Oriented SELECTION)

レガシーコード改善ガイド (Object Oriented SELECTION)

単体テストは速く走る。速く走らないとしたら、それは単体テストではない。
他の種類のテストが単体テストの仮面をかぶっていることもよくある。次に当てはまるものは単体テストではない。

 1.データベースとやり取りする
 2.ネットワークを介した通信をする
 3.ファイルシステムにアクセスする
 4.実行するために特別な環境設定を必要とする(環境設定ファイルの編集など)

上記に該当するテストが悪いというわけではない。多くの場合において、
そのようなテストを書く価値はあり、しばしばテストハーネス内に記述される。
しかし単体テストは、そのようなテストと切り分けて、変更を行うたびに高速で
実行できるように保ち続けることが重要である。

(※『レガシーコード改善ガイド』P.17 上部囲みより引用)
  • 最近は『ゴリ押しで行け』。
    • 1,3は最近は皆やっている。
    • 2.はスタブやモックにする。

  • 『Mockito』の発音について
    • 開催前から分かれる『もきーと』『もひーと』『もっくいとう』の発音。
    • 『モック伊藤』が出て来て以降、それまでの発音していたものが都度『もっくいとう』に置き換わってしまった人もw
    • 和田さん来た!聞いてみよう...

    • おぅ......(つДT)w
    • その後もTLで続く発音談義...。

謎の『モック伊藤』、結局存在しなかったのか…強烈なインパクトを残したまま、我々モック伊藤探検隊の調査はここで一旦終了となった...(しろめ

これはアレですな、このシリーズで『Mockitoはどこまでモック伊藤なのか Mockitoの限界に迫る』をやってみて検証する必要がありますね...(しろめ

LT:TestCode Refactoring Using ExternalResource

スーパークラスを継承してテストを書く点についてデメリットを紹介し、External Resourceを使おう!という内容のLT。

内容的には前回(第4章〜第10章)に該当するものでしたが、お願いしてLTしてもらいました。ありがとうございました!

次回開催(#4)について

次回第4回は以下の日程・内容で開催を予定しております。

  • 開催日時:2013/03/03(日) 15:00〜19:00 (※開始時間は早まる可能性もあります)
  • 開催日時:横浜タネマキ
  • 対象範囲:第12章 データベースのテスト


基本的にはこれまで通り[書籍の黙読・写経・ディスカッションパート]→[時間が余ったら各自自由にもくもく]な感じで進めて行こうと思ってますが、LTなりその他の企画についてもその時の流れで盛り込んで行ければと思います。


参加エントリ募集ページは以下になります。書籍の内容、及びデータベースのテストについて話してみたい・聞いてみたい・色々試してみたい!という方、いらっしゃいましたら是非ご参加お待ちしております!

懇親会

第3回目にして、初めてこのシリーズでは懇親会を実施。

会場から程無く歩いた所にある中華料理屋にて計9名が参加。テスト談義に花が咲く、とても楽しい2時間でした。

急遽参加&ディスカッションに濃密さをプラスして頂いた和田さん、またご参加頂いた皆様、ありがとうございました!

その他関連



そしてこの回で、勉強会通算参加回数150回目となりました!
節目となった回をこのような内容の濃い形で終える事が出来、感謝しております。
ご参加頂いた皆様、改めてありがとうございました!