refactoring and test

86
リファクタリングと テストの関係 t-wada http://d.hatena.ne.jp/t-wada/ @J2EE勉強会 2005820

Upload: takuto-wada

Post on 08-Jul-2015

1.629 views

Category:

Documents


2 download

TRANSCRIPT

Page 1: Refactoring And Test

リファクタリングとテストの関係

t­wadahttp://d.hatena.ne.jp/t­wada/

@J2EE勉強会2005年8月20日

Page 2: Refactoring And Test

前回のおさらい

Page 3: Refactoring And Test

前回の結論(1)

● TDDはテスト技術ではない

● "Test"が指し示しているものは複数ある

– 開発促進と品質保証

– 2つの"Test"に優劣はない。「違う」だけ。

– どちらも非常に重要● テストをロールから分類する

– 開発者 / 顧客 / 品質保証担当者

Page 4: Refactoring And Test

前回の結論(2)

● TDDの"Test"は開発(者)のためのもの

– つまり、開発促進のテスト

● TDDの良さは設計技術でありながら品質保証技術に「かなり近い」こと

Page 5: Refactoring And Test

難しくなったソフトウェア開発

● ソフトウェアの複雑化● ソフトウェアの大規模化● プロジェクトの短納期化

● オブジェクト指向も(それなりに)使われだした

→ソフトウェアの品質が問題に(日経ビジネス)

→「テスト」が注目されてきた

Page 6: Refactoring And Test

テスト分類の混乱

● 単体、ユニット、結合、機能、システム…

● 単体テストとユニットテストは同じもの?– 単体って?

– ユニットって?

● 結合テストは何を結合する?● 品質保証? 動作確認?● だれが? いつ?

Page 7: Refactoring And Test

テストの目的に戻ろう

● 何のためにテストするのか● 誰のためにテストをするのか● テストで何を知りたいのか

「結局、何のためにテストを行うのか」

Page 8: Refactoring And Test

テストをロールによって分類する

● Developer(Programmer) Test– 開発者が行う、開発促進のためのテスト– 単体、ユニット、結合 …などなど

● Customer Test– 顧客(のロールを担うひと)が行うテスト

– 従来の「受け入れテスト」が多くを占める

● QA Test– 品質保証のためのテスト– 行う人は開発者かもしれないし、テスト担当者かもしれない

Page 9: Refactoring And Test

DeveloperTest

CustomerTest

QATest

「テスト」

Page 10: Refactoring And Test

それぞれのテストの目的

● Developer Test– 開発促進– フィードバックを伴う設計行為

● Customer Test– 進捗管理– 機能要件の検証

● QA Test– 品質保証– 非機能要件の検証

Page 11: Refactoring And Test

DeveloperTest

開発促進

設計行為

CustomerTest

進捗管理

機能要件

QATest

品質保証

非機能要件

「テスト」

Page 12: Refactoring And Test

TDD != 品質保証技術

● TDDは「こうしてみようか」をテストする

● QAテストは「こうあってはならない」をテストする

TDDは品質向上技術だが、品質保証技術ではない。そもそも「品質」の話が必要

あなたにとっての「品質」とは何ですか?

Page 13: Refactoring And Test

TDDは設計技法です

● 文脈

– プログラミングは設計行為である(J.Reeves)

– REDは仕様の設計

– GREENは仕様の実装

– Refactoringは内部設計の改善

参考:「ソフトウェア設計とは何か?」    http://www.biwa.ne.jp/~mmura/SoftwareDevelopment/WhatIsSoftwareDesignJ.html

Page 14: Refactoring And Test

TDDと品質保証の関係

● 目的は違えど、手段が品質保証技術に近い● 品質保証との親和性● 帽子を変えることで品質保証モードに入れる

Page 15: Refactoring And Test

前回の発表のねらい

● 議論の土台を作ること● 目的の視点からみたテストの整理

– Developer Testの概念の紹介

● TDDのTはDeveloper Testであることを理解してもらう– 品質保証のための技術ではなく、開発促進のための技術

Page 16: Refactoring And Test

今回のお題

Page 17: Refactoring And Test

今日伝えたいこと(1)

● リファクタリングの目的はコードの理解や修正が簡単になるようにすること

● リファクタリングは設計意志決定のバランスをとる

Page 18: Refactoring And Test

今日伝えたいこと(2)

● テストがリファクタリングを妨げるのは何かがおかしい

● リファクタリングを後押しするテストと、リファクタリングの役に立たないテストがある

● 目的に沿ってDeveloper Testを使いこなそう

Page 19: Refactoring And Test

第一部

Page 20: Refactoring And Test

リファクタリングについての整理

Page 21: Refactoring And Test

リファクタリングをめぐる混乱

● 三週間ほど前、リファクタリングをめぐって議論が繰り広げられました

● ひとりひとりが結ぶ「リファクタリング」の像が異なるという印象

「テスト」と同じ混乱の構図か

Page 22: Refactoring And Test

リファクタリングの定義(1)

リファクタリング(名詞)

外部から見たときの振る舞いを保ちつつ、理解や修正が簡単になるように、ソフトウェアの内部構造を変更させること。

Page 23: Refactoring And Test

リファクタリングの定義(2)

リファクタリング(動詞)

一連のリファクタリングを行って、外部から見た振る舞いの変更なしに、ソフトウェアを再構築すること。

Page 24: Refactoring And Test

リファクタリングの解釈のブレ

● 外部から見た振る舞い

– 外部?

– 振る舞い?

– public? publish?

● テストで担保する?● パフォーマンス?

Page 25: Refactoring And Test

「テスト」と同じ混乱の構図

● 違う内容のものを同じ名前で呼んでいる– 「テスト」の意味合いの違い– 「外部から」の意味合いの違い

誰が、何のために、で再整理しましょう

Page 26: Refactoring And Test

リファクタリングの「誰が」

● これは、私たちプログラマーです● 自分達で、自分達のコードをわかりやすく、シンプルにするのがリファクタリング– 他の人が書いたコードを理解のためにリファクタすることはあるが、特殊例

Page 27: Refactoring And Test

リファクタリングの「何のために」

● シンプル設計● コードを理解しやすく● コードを修正しやすく● コードをシンプルにすること ≒ 設計をシンプルにすること

大目的

「理解や修正が簡単になるように」

Page 28: Refactoring And Test

何がリファクタリングへと駆り立てるのか(RtPより)

● 新しいコードを追加しやすくしたいため● 既存のコードの設計を改善したいため● コードをより良く理解したいため● コーディングの不快感を減らしたいため

Page 29: Refactoring And Test

リファクタリングの「いつ」

● 教条的なことを言うなら、「常に」です● 気づいたときに

● サイクルに織り込んでいるのがTDD

● 「大きいリファクタリング」は、話が別● 小規模なリファクタリングは機械でも出来るし、いつもやっていることです

– rename系、extract系、inline系

Page 30: Refactoring And Test

リファクタリングは何ではないのか

● 非公開メソッドの中だけではない● パフォーマンスチューニングではない● バグフィクスではない● 他人のひどいコードの手直しではない

● 手戻りではない (Refactoring is not rework)

Page 31: Refactoring And Test

パフォーマンスチューニング?

● パフォーマンスのためにリファクタすることはほとんどない

● まず計ってからものを言うべし● 普通はデータベースがボトルネック、コードを見るよりExplain Planするべし!

Page 32: Refactoring And Test

「シンプル」とは何か

● コンテクストに依存する– チームで決めること– チームによってなにがシンプルかが変わる

● パターンはシンプルさのために使う

– Compositeの方が単純なとき

– Strategyの方が単純なとき● 分岐から構造へ

Page 33: Refactoring And Test

まとめると

Page 34: Refactoring And Test

リファクタリング、私の理解

● 目的は、理解や修正が簡単になるように● 設計行為としてのリファクタリング

● 外部からみた振る舞い

– publishedメソッドの事前条件と事後条件のこと

– publishedメソッドの変更もときどきリファクタリングと呼んでいます

● 「テスト」

– 大きい粒度のテスト、Mockベースのテストではなくて実オブジェクトベースのテスト

Page 35: Refactoring And Test

テストがある

テストがない

リファクタリング

privateprotected

public published

Page 36: Refactoring And Test

リファクタリング前提の設計?

● 逆を考えるとわかりやすい– 「一発で正しい設計を行え、修正や改善は許可しない」と言われたら?

● 「修正が効かない」というプレッシャーをあたえると人間は脆い

● テストとバージョン管理で安全に後戻りができるようになる– 安心して前に進むことができるようになる

Page 37: Refactoring And Test

技術的負債

● スケジュールの無い開発は存在しない● 負債を追ってでもリリースを優先することも● リファクタリングで負債を減らしていく

● 「ええい、やめだやめだ、スクラッチから書き直そう!」とならないために

● リファクタリングは「捨てない技術」

Page 38: Refactoring And Test

道はひとつではない

● 「動作する、きれいなコード」● きれいな、から攻めるか● 動作する、から攻めるか

Page 39: Refactoring And Test

動作する(すぐには)動かない

汚い

きれい

Page 40: Refactoring And Test

動作する(すぐには)動かない

汚い

きれい

Page 41: Refactoring And Test

動作する(すぐには)動かない

汚い

きれい

Page 42: Refactoring And Test

動作する(すぐには)動かない

汚い

きれい

Page 43: Refactoring And Test

TDDのテンポ

● Red, Green, Refactor● Red, Green, Commit, Refactor, Green, Commit

「動作する」を満たしてから

「きれいな」にとりかかる

Page 44: Refactoring And Test

動作する(すぐには)動かない

汚い

きれい

Page 45: Refactoring And Test

動作する(すぐには)動かない

汚い

きれい

Red

Page 46: Refactoring And Test

動作する(すぐには)動かない

汚い

きれい

Red

Green

Page 47: Refactoring And Test

動作する(すぐには)動かない

汚い

きれい

Green

Ref

acto

r

Page 48: Refactoring And Test

動作する(すぐには)動かない

汚い

きれい

Ref

acto

r

Red

Page 49: Refactoring And Test

動作する(すぐには)動かない

汚い

きれい

RedGreen

Page 50: Refactoring And Test

動作する(すぐには)動かない

汚い

きれい

Ref

acto

r

Green

Page 51: Refactoring And Test

動作する(すぐには)動かない

汚い

きれい

Ref

acto

r

RedGreen

Page 52: Refactoring And Test

リターンマッチは可能だ

● 設計の善し悪しは、最初に設計したときには決まらない

● だんだんと「より良い」設計に変えていくことが出来る

– ただし、非常に大規模なアーキテクチャ変更は別

● メジャーバージョンアップ● システムのリプレース

Page 53: Refactoring And Test

進化的設計(Evolutionary Design)

● フレームワークは最後に出来る● ボトムアップ● フィードバック

ここで提示しているのは極論かもしれませんが、

こんな考え方もあることを紹介したいのです。

Page 54: Refactoring And Test

第二部

Page 55: Refactoring And Test

リファクタリングをサポートするテ

ストとは何か

Page 56: Refactoring And Test

テストの資産価値

● リファクタリングの邪魔になるようなテストは価値が低い

● テストはリファクタリングの支えになるものであって、妨げになるものではない

● どのテストもメンテナンスコストはかかる● 半年後であっても読みやすく、リファクタリングの支えになるテストは資産価値が高い

Page 57: Refactoring And Test

再度Developer Testを分類する必要が出てきました

Page 58: Refactoring And Test

Developer Testの分類のキーポイント

● 目的● 粒度● 何を担保するのか● フィードバックまでの時間● 資産価値● メンテナンスコスト● 設計改善効果

Page 59: Refactoring And Test

Developer Testを目的と粒度で分類する

● Unit Test– テスト対象以外は全てMock

● Assembly Test– テスト対象のコラボレータは本物を使う

● Functional Test– コンポーネントをブラックボックスとして扱う– 永続化層も本物

Page 60: Refactoring And Test

DeveloperTest

CustomerTest

QATest

Page 61: Refactoring And Test

CustomerTest

QATest

Developer Test

Unit Test

Assembly Test

Functional Test

Page 62: Refactoring And Test

Developer Testの分類、もうひとつの視点

Page 63: Refactoring And Test

インタラクションベーステスト

● テスト対象のオブジェクトがコラボレータときちんと相互作用するかどうかを検証する

● Mockを多用する

– テストの初めでコラボレータのMockを作成

– Mockにexpectationをセット

– テストの最後でMockをverify

Page 64: Refactoring And Test

ステートベーステスト

● テスト対象のオブジェクトの振る舞いの事前条件、事後条件を検証する

● setUpでデータを準備

● assertEquals等で事後条件のチェック

Page 65: Refactoring And Test

インタラクションベースステートベース

Unit Test

AssemblyTest

FunctionalTest

Page 66: Refactoring And Test

リファクタリングを担保するテストとは

● ある程度大きい粒度のテストでないと、リファクタリングの前後を担保できない

● インタラクションベースのテストはリファクタリングの役にたたないことが多い

Page 67: Refactoring And Test

リファクタリングの誤解

● 「リファクタリング前後でテストが失敗してはならない」?

担保するテストはGreen to Greenであるべし

しかし、

全てのテストがGreen to Greenとは限らない

Page 68: Refactoring And Test

リファクタリングの最中には

● ステートベースのテストは失敗しない

● インタラクションベースのテストは失敗してもいい

● あくまで「想定の範囲内」であれば、ですが

Page 69: Refactoring And Test

なぜインタラクションベースのテストは失敗してもいいのか

● 内部設計を改善するということは、オブジェクトたちの相互作用(インタラクション)も変わる可能性が高い– 責務の再配置には、インタラクションの変更がつき従う

– インタラクションが変わるのは悪いことではなく、良いこと

Page 70: Refactoring And Test

インタラクションベースステートベース

Unit Test

AssemblyTest

FunctionalTest

リファクタリングの支えになりにくい領域

Page 71: Refactoring And Test

CustomerTest

QATest

Developer Test

Unit Test

Assembly Test

Functional Test

リファクタリングの支えになりにくい領域

Page 72: Refactoring And Test

私のチームがテストの粒度に使っているメタファ

● はしご● 踏台● 階段

● 調子のいいときには三段飛ばし● 心配なときには一段ずつ

Page 73: Refactoring And Test

トップダウンとボトムアップ

● インタラクションベースのテストだけを積み上げて正解に辿り着くのは難しい

● 受け入れテストだけを拠り所に開発を行うのは足場が少なすぎる

Page 74: Refactoring And Test

足りないピースは?

Page 75: Refactoring And Test

低コストな機能(Functional)テスト

● 大きいリファクタリングのキーポイント● 機能のブラックボックステストをいかに低コストで行うかがカギ

● 例えばJ2EEであれば

– Selenium

– HttpUnit

– Cactus

Page 76: Refactoring And Test

Mockでテストできないもの

● オブジェクトたちが実際に協調して動くこと

● Mockは妄想。妄想でもインタラクションの設計はできる

● 詳細なシーケンス図と役割が似ている?– 違いはコードで書かれること– 図とコードの距離

Page 77: Refactoring And Test

インタラクションベーステスト(Mock)のデメリット

● 価値が前方(気づき)に集中する

● メンテナンスコストが結構高い● テストがなかなか資産化しない

           => 資産価値が低い

Page 78: Refactoring And Test

最後にちょっとMockテストの弁護をします

Page 79: Refactoring And Test

Mockのメリット(1)

● フィードバックの早さ

– MockのテストはGreenにするまでの時間が短い

● 例外系のテストが行いやすい– ネットワークエラー– データベースエラー

Page 80: Refactoring And Test

Mockのメリット(2)

● 悪い設計に気づくまでの時間が短い

– Mockのセットアップがめんどくさい

                => インタラクションが複雑

– Mockを沢山作らなければならない

                => デメテルの法則に反している

● 責任の配置を考える機会が増える

– Tell, don't Ask

– QueryからCommandへ

Page 81: Refactoring And Test

テスト設計の勘どころは、次回以降をご期待ください

Page 82: Refactoring And Test

今日伝えたかったこと(1)

● リファクタリングの目的はコードの理解や修正が簡単になるようにすること

● リファクタリングは設計意志決定のバランスをとる

Page 83: Refactoring And Test

今日伝えたかったこと(2)

● テストがリファクタリングを妨げるのは何かがおかしい

● リファクタリングを後押しするテストと、リファクタリングの役に立たないテストがある

● 目的に沿ってDeveloper Testを使いこなそう

Page 84: Refactoring And Test

Enjoy Testing!

Page 85: Refactoring And Test

Special Thanks

● J2EE勉強会に参加されているみなさま● 角田さん● ひがさん● 中村さん● 稚内北星学園大学様(会場提供ありがとうございます)● かくたにさん● kdmsnrさん (今回はblikiに本当に御世話になりました)

● TDD,Refactoringを編みだしたKent Beck氏● そして、それを私に教えてくれた、masarlさん

Page 86: Refactoring And Test

ご静聴ありがとうございました