SlideShare a Scribd company logo
テストコードのリファクタリング

      #jjug_r33

  2012.11.10 JJUG CCC
  渡辺修司 (@shuji_w6e)


                        1
今日のお話
今日のお話

 冗長で書きにくい
     テストコードを

            Spock
        と           で
  リファクタリング
自己紹介
渡辺 修司
Javaプログラマ

 株式会社エスプラニング所属

 ウェブアプリやデスクトップアプリの開発

テスト駆動開発、ユースケース駆動開発

アジャイル開発

最近の趣味はロードバイクとフットサル
@shuji_w6e
札幌 Javaコミュニティ

TDD Boot Camp

やさしいデスマーチ(Blog)

執筆活動

 WEB DB Press vol.69

 JUnit実践入門(11/21)
テストしてますか?
継続的インテグレーションは強みでなくなった


 Subversion/Gitなどを使用したソースコード管理、
Jenkinsを使用した継続的インテグレーション、様々
なxUnitフレームワークを使用した自動テストなどを
ソフトウェア開発組織として実践することは、今日で
は、その開発組織の技術的な強みではありません。
       http://yshibata.blog.so-net.ne.jp/archive/c20379492-1
現実...




        http://www.flickr.com/photos/togemaru/2882075323/
現代ソフトウェア開発の3本柱
                                         ©t-wada
バージョン管理

テスティング

自動化




          http://www.flickr.com/photos/ercol/4665559509/
現代ソフトウェア開発の3本柱
                                         ©t-wada
バージョン管理

テスティング

自動化




          http://www.flickr.com/photos/ercol/4665559509/
ユニットテストの目的




http://www.flickr.com/photos/essecento/4297955162/
スキル不足
仕様変更


                                     経験不足
複雑な要件

                                                   不安
   http://www.flickr.com/photos/yopse/3772030400/
不完全な人間




   http://www.flickr.com/photos/sharynmorrow/3948100/
ユニットテストとは?
ソフトウェアを構成する最小部品のテスト

主にクラスやメソッドが対象

対象が期待される振る舞いをするかを検証
テストの4象限モデル
                ビジネス面
                                   手動


            機能テスト      受け入れテスト




                                   製品を批評
 チームを支援




          ストーリーテスト    ユーザビリティテスト




                        負荷テスト
          ユニットテスト     パフォーマンステスト



 自動
                    技術面
テストの4象限モデル
                ビジネス面
                                   手動


            機能テスト      受け入れテスト




                                   製品を批評
 チームを支援




          ストーリーテスト    ユーザビリティテスト




                        負荷テスト
          ユニットテスト     パフォーマンステスト



 自動
                    技術面
テストの4象限モデル
                ビジネス面
                                   手動


            機能テスト      受け入れテスト




                                   製品を批評
 チームを支援




          ストーリーテスト    ユーザビリティテスト




                        負荷テスト
          ユニットテスト     パフォーマンステスト



 自動
                    技術面
チームを支援するテスト
自分のコードへの自信

積極的なリファクタリング

安心できるリリース
技術面のテスト
プログラマが行う

プロダクションコードの作成を支援する

ビジネス的価値 < 技術的負債の低減
ユニットテストの特徴
プログラマが行い、

開発チームを支援し、

技術面に属し、

自動化が可能。
セーフティネット




   http://www.flickr.com/photos/32010000@N08/2987901256/
テストコードのリファクタリング
品質とユニットテスト
ユニットテストで直接の品質はあがらない

品質を高めるにはビジネス面のテストが必要

要件を満たしているか?(受け入れテスト)

使いやすいか?(ユーザビリティテスト)

ユニットテストにより技術的負債が減る

変化や追加要求に強くなる
ユニットテストの
                     学習方法




http://www.flickr.com/photos/alisdair/135306281/
ユニットテストは難しい?
ユニットテストは難しい?




     YES
ユニットテストは難しい?
習得するにはそれなりに書く必要

テスト技法を学ぶ必要

テストを書くプロジェクトに参加する必要

チーム全体の意識改革が必要


       YES
ユニットテストは簡単?
ユニットテストは簡単?




     YES
ユニットテストは簡単?
書けば書くほど身につけることができる

パターン化しやすい


       YES
ユニットテストは有効?
ユニットテストは有効?




     YES
ユニットテストは有効?
積極的なリファクタリングによる改善

安心感と自信

より良い設計

デグレ(リグレッション)の予防


         YES
ユニットテストは開発の基盤
リファクタリング

継続的インテグレーション

カバレッジ測定

テスト駆動開発
ユニットテストを学習するコツ
たくさん書く

書いて整理する

なんでも自動化する
ユニットテストを学習するコツ
たくさん書く

書いて整理する

なんでも自動化する
ユニットテストを学習するコツ
たくさん書く

書いて整理する

なんでも自動化する
増えるテストコード
http://www.flickr.com/photos/62765927@N00/2293652369/
DRY原則
Don t Repeat Yourself

重複は悪

コピペはバグの温床
DRY原則
Don t Repeat Yourself

重複は悪

コピペはバグの温床


そう、プロダクションコードならばね
テストコードの特徴
似たようなコードが多くなる

異なるのはパラメータ

異なるのは前提条件

効率良くテストケースを増やしたい

各テストケースで完結する

見通しが良いことが必要
テストコードを整理する方針
重複を排除し過ぎると可読性が落ちる

テストケース毎に独立させる

テストケースを追加しやすくする

修正する場合は影響範囲を最小限にする
勝利の
カスタムMatcher、カスタムRule

構造化テスト(Enclosed)

パラメータ化テスト(Theories)

テストダブル(モックやスタブ)

テスト技法
https://github.com/shuji/demo-refactering-unittest




デモ
ArrayListのテスト
リストが初期状態の時sizeは0を返す

リストに1件の文字列を含む時sizeは1を返す

リストに2件の文字列を含む時sizeは2を返す

リストが初期状態の時get_0は
IndexOutOfBoundsExceptionを送出する

リストに1件の文字列を含む時get_0はhelloを返す

リストに2件の文字列を含む時get_0はhelloを返す

etc....
テストクラスを構造化する
同じ階層で多くのテストケースを管理しない

同じフォルダに大量のファイルと同じ

構造化してテストケースを整理

初期化処理が共通するテストをまとめる

Enclosedテストランナー
テストクラスを構造化する
同じ階層で多くのテストケースを管理しない

同じフォルダに大量のファイルと同じ

構造化してテストケースを整理

初期化処理が共通するテストをまとめる

Enclosedテストランナー

       6章 テストのコンテキスト
消費税計算クラスのテスト
コンストラクタで税率を指定できる

  new ConsumptionTax(5);

applyメソッドは金額を指定し、税込み金額
を返す
パラメータ化テストを使う
多くのパターンでテストしたい

テストケースで異なるのはパラメータのみ

自然とコピペが多くなる

テストケースとテストデータを分離する

Theoriesテストランナー
パラメータ化テストを使う
多くのパターンでテストしたい

テストケースで異なるのはパラメータのみ

自然とコピペが多くなる

テストケースとテストデータを分離する

Theoriesテストランナー

       8章 パラメータ化テスト
複雑な条件のテスト
合計金額が6000円以上の場合、送料無料となる
割引クーポン(10%)を利用する場合、消費税適用
前の合計金額に適用する
個々の商品に割引が設定されている商品は割引クーポ
ンには適用されない
送料無料は割引後の合計金額を基準とする
送料は全国一律で800円となる
代引きの場合、手数料が300円(税込み)発生する
消費税は5%とする
Cucumberの活用
テストケースをシナリオとして記述

 日本語によるテストケース

 テーブル表記が扱える

JUnitを使えれば簡単に使える
Cucumberの活用
テストケースをシナリオとして記述

 日本語によるテストケース

 テーブル表記が扱える

JUnitを使えれば簡単に使える


      17章 振舞駆動開発
補足)テストデータの選択
テスト技法を学ぶ

 同値クラス(P28)

 境界値 (P28)

 ペア構成テスト( )

  オールペア法

  直交表
組み合わせの効率化
TestNo   送料   セール品   クーポン   代引き
   1     ✓     ✓      ✓      ✓

   2     ✓     ✓      ✓

   3     ✓            ✓      ✓

   4     ✓     ✓

   5     ✓            ✓

   6     ✓                   ✓

   7           ✓      ✓      ✓

   8           ✓      ✓

   9                  ✓      ✓

  10           ✓

  11                  ✓

  12                         ✓

  13                  ✓      ✓

  14                  ✓

  15                         ✓

  16
オールペア法
組み合わせテストの技法

欠陥は単条件のテストである程度カバー可能

2条件の組み合わせ網羅で9割近くカバー

3条件以上の組み合わせは費用対効果は低い

すべての要素の組み合わせを網羅
http://www.allpairstesting.com/allpairsgenerator
オールペア法
TestNo   送料   セール品   クーポン   代引き   条件
   1     ✓     ✓      ✓      ✓    4

   2     ✓     ✓      ✓           3

   3     ✓     ✓             ✓    3

   4     ✓            ✓      ✓    3

   5           ✓      ✓      ✓    3

   6     ✓     ✓                  2

   7     ✓            ✓           2

   8     ✓                   ✓    2

   9           ✓      ✓           2

  10           ✓             ✓    2

  11                  ✓      ✓    2

  12     ✓                        1

  13           ✓                  1

  14                  ✓           1

  15                         ✓    1

  16                              0
まとめ
テストケースの構造化(Enclosed)

共通の初期化でテストケースをまとめる

パラメータ化テスト(Theories)

テストデータとテストケースを分離する

Cucumberによる機能テスト

テストによって適するツールは異なる

テスト技法

効率良くテストケースを選択
Have a good testing!

More Related Content

テストコードのリファクタリング

Editor's Notes

  1. \n
  2. \n
  3. \n
  4. \n
  5. \n
  6. \n
  7. \n
  8. 30秒程度\n
  9. \n
  10. \n
  11. \n
  12. \n
  13. \n
  14. \n
  15. \n
  16. \n
  17. \n
  18. \n
  19. \n
  20. \n
  21. \n
  22. \n
  23. \n
  24. \n
  25. \n
  26. \n
  27. \n
  28. \n
  29. \n
  30. \n
  31. \n
  32. \n
  33. \n
  34. \n
  35. \n
  36. \n
  37. \n
  38. \n
  39. \n
  40. \n
  41. \n
  42. \n
  43. \n
  44. \n
  45. \n
  46. \n
  47. \n
  48. \n
  49. \n
  50. \n
  51. \n
  52. \n
  53. \n
  54. \n
  55. \n
  56. \n
  57. \n
  58. \n