Showing 6 Result(s)

レガシーコードからの脱却 まとめ – 12.9 – 12.9.1

12.9 実践しよう 12.9.1 創発設計をマスターする7つの戦略 内容 創発設計のための効果的な戦略を7つ紹介。 戦略 説明 オブジェクト指向を理解する オブジェクト指向言語を使っているからと言って、オブジェクト指向を理解していると思うな。うまくカプセル化したエンティティを作り、解決する問題を正確にモデル化すべし。 デザインパターンを理解する デザインパターンはふるまいを分離するのに有効。創発設計の中でパターンが明らかになってくる。 テスト駆動開発を理解する テスト駆動開発は、修正した際のセーフティネットであり、創発設計をサポートする。 リファクタリングを理解する リファクタリングは創発設計に大きく関係している。コードを整理していく中でパターンが見つけられるためだ。 コードの品質にフォーカスする コードは「CLEAN」(高凝集、疎結合、カプセル化、断定的、非冗長)に保たなければ、すぐに保守不可能になる。 情けはかけない 必要に応じて設計を変える勇気を持て。思い入れた設計を捨てる勇気を持て。 良い開発プラクティスを習慣にする スクラム、XPのようなアジャイルプラクティスは、創発設計をサポートする有効なツールだ。が、アジャイルプラクティスが設計してくれるわけではない。良い設計は、プラクティスの背景にある原則を理解した上でプラクティスのサポートを受けるべきだ。 学び 12章の総集編 学びを活かすアイディア・行動 テストコードの目的の事前知識整理 コーディング規約づくり

レガシーコードからの脱却 まとめ – 11.10 – 11.11

11.10 モックを使ったワークフローテスト 内容 ユニットテストは一連の順序を検証したり、似たようなほかのシナリオを検証することは出来ない。こういう場合は、ワークフローテストを行う。 ワークフローテストは実際のオブジェクトを使うのではなくモックを使う。 モックは外部との依存関係とどのように相互作用するかを検証するために使う。 テストとしては、モックが正しいパラメータで呼び出されたかを検証する。 11.11 セーフティネットを作る テスト駆動開発はソフトウェアを作るためのリズムや、開発者が安全にコードを書くためのセーフティネットを提供してくれる。 アクロバットをする人にとってのセーフティネットは命を守るものだが、開発者にとってのセーフティネットは、心理的な保証だ。 テストファースト開発を行う最大の利点は、ソフトウェア開発者がテストしやすいコードを書くようになり、維持するコストも抑えられること。 開発者は設計から始めるように教えられるが、プロジェクトの後半のほうが正しい設計についてはるかに多くのことがわかるため、最後に設計をするのが良い。最後に設計する説明は次の章。 学び 外部との依存関係と相関関係をテストするのはワークフローテストと呼ぶこと ワークフローテストもモックを使って行うこと テストファースト開発は開発者に心理的安全を保証してくれて、結果的にコストを抑えることができる。心理的安全は、心に余裕を生み、焦って汚いコードになることを防ぎ、保守性、テスト容易性を保つことができ、結果的に拡張コストを少なくすることができる。 学びを活かすアイディア・行動 テスコードの目的のための事前知識整理

レガシーコードからの脱却 まとめ – 11

11 プラクティス7 テストでふるまいを明示する 内容 テストによって動くものと動かないものがすぐにわかる。これは開発の原動力を大きく影響を及ぼす。 ケイパー・ジョーンズは「開発者の時間の半分以上が、過去にやった仕事の手直しに費やされている」と言っている。例えば、不具合の原因が2箇所による複合的な要因の場合、その原因を特定するのは非常に時間がかかるが、ありえる。この手直しに時間がかかっていることが、テスト駆動開発を行う理由だ。 マネージャーがテスト駆動開発する時間を持てないというのは、以下のループとなっているためだ。 テスト駆動開発をしていないから、問題の原因の特定に時間がかかる 問題の原因の特定に時間をかけすぎてるから、テスト駆動開発を学習する時間がとれない このループになっているのであれば、ここから降りなければならない。 テストは具体的な要件であり、メソッドの使い方を正しくフォーカスすることができる。これは実装を良くするためや、問題をとりのぞくために非常に効果がある。 学び ほとんどの時間を読む時間、調査する時間に費やしているという事実 テスト駆動開発をしていないからテスト駆動開発ができないループに入っている場合、なんとかしてそのループを抜け出なければならない 学びを活かすアイディア・行動 テストコードの目的のための事前知識整理

レガシーコードからの脱却 まとめ – 10.3 – 10.3.2

10.3 良いテストを書く 内容 テスト駆動開発として実践されている「テストファースト開発」と「テストアフター開発」を紹介し、多くの開発者やマネージャーは「テストアフター開発」によって、テスト駆動開発に対するネガティブな誤解を生んでいることを説明している。 テストファースト開発 説明 小さな機能のテストを書いてから、その機能を実装するやり方。 メリット テストの観点(外部からの観察)と、コードの観点(内部からの観察)を行き来することで、フィードバックをもらいながら堅実に進められる。 最初にテストを書くことで、常に100%のコードカバレッジが確保できる。 失敗したテストに合格するようにコードを書くため、テスト可能なコードが書けていることを保証してくれる。 デメリット テストを書くスキルの習得が要る テストアフター開発 説明 コードを書いてからテストを書く。(著者がそう呼んでいる) メリット 自動化された回帰テストを好きなときに作って実行できる。 デメリット コードを書いたあとにテストを書くのは、かなりの再設計、コードをクリーンアップが必要であることがほとんど。結局、テスト可能なコードを最初に作成するほうが楽。 この実態を前提に、多くのマネージャーと開発者は、テスト駆動開発に対し、テストアフター開発のイメージを持ち「やたら手がかかる」というような先入観を持っている。 テストファースト開発では、テストアフター開発のデメリットを防ぐことができる。 すべてのテストを先に書いてから、実装する方法もある。この方法にはいくつかの利点があるのは事実だが、テストファースト開発で得られる頻繁なフィードバックのほうが大きな利点である。著者はすべてのテストを先に書いてから実装する方法はテスト駆動開発とは考えていない。 10.3.1 テストではない テストは二重の役割を果たしているということを説明している。 1つは、仮説であり、ふるまいの仕様。 もう1つは、回帰テストが常に用意されていて実行され、コードが期待したように機能していることを検証すること コードを書く前に書いているユニットテストはテストではなく仮説。サービスの呼び出し方法と期待する戻り値の仮説を立てている。つまり、どうなったら完成するのかの仮説を立てている。 次に、テストに合格するコードを書いたら実際のテストになる。なんらかのふるまいを実行して検証したから。 そしてこの検証機能はソフトウェアの寿命が来るまで以下の価値を提供し続ける。 影響を与える可能性のあるものは何も変わっていないことを保証する コードが期待したように動くことを保証する 10.3.2 ふるまいの集合体 ユニットとはふるまいの単位で独立した検証可能なふるまいのこと。つまり、どのように使ってどのような結果になるかを検証できるふるまいのこと。ふるまいを表すために、常に必要最小限のテストを書くことが重要。 多くの開発者は「ユニットテスト」の「ユニット」と言う言葉を、メソッド、クラス、モジュール、関数などのような実体を指すものと勘違いするが、違う。この勘違いのため、新しいクラスやメソッドを作るたびに新しいテストを作成し、コードの成長とともに多くのテストを追加することで、肥大化するのではないかと心配したり、実際に追加してしまう。 テストファーストのメリットは、必要に応じてあとから簡単にコードをクリーンアップできるようにすることだ。ユニットの単位を勘違いして、コードをクリーンアップするときに、不要なテストを増やしてしまうと、自動回帰テストを持つことの価値の大部分を失ってしまう。 「ユニット」が表現するのはふるまいだ。ふるまいが変わらないなら、テストを変える必要はない。 「ユニットテスト」は「すべてのクラスやメソッドがテストを持つべき」ではなく「あらゆる観察可能なふるまいが、それに紐づくテストを持つべき」である。「あらゆる観察可能なふるまい」=「すべてのクラスやメソッド」というわけではない。 学び 実際にテストアフター開発が起きているからネガティブな先入観が生まれる。では、なぜテストアフター開発をしてしまうのか。要因は、大きく2つ。 傲慢。ほとんどの開発者はテスト可能でないコードを書いてしまう前提を認識していない。 無知。テストファースト開発が習得が必要なスキルだということを知らない。 間違った認識、無知は失敗を生み、ネガティブな先入観を生む。 テストファーストで書くテストは、実際のコードまで書いて、テストとなる。テストだけの時点では、ふるまいの仕様を表す仮説である。 自動回帰テストの環境がないと効果が薄いように感じる。 ユニットとは観察可能なふるまいの単位である。 ユニットの単位を明確にして不要なテストを増やしてはいけない。 学びを活かすアイディア・行動 テストコードの目的のための事前知識準備 現場の回帰テスト環境作り ユニットの単位の深堀り 現場のテストコードのコーディング規約づくり

レガシーコードからの脱却 まとめ – 10.2 – 10.2.2

10.2 QA 内容 QAテストの種類・形態を紹介。 コンポーネントテストユニットがどのように連携するかを調べる 機能テストユニットを機能ごとにまとめてEnd to End(端から端まで)のふるまいが完全かを調べる シナリオテストユーザーがシステムを使って、実際に使えるかを調べる パフォーマンステスト何百万ものアクセスに耐えうるか調べる セキュリティテストコードの脆弱性を探す プロジェクトに必要なテストはリスクによって異なる。たとえばペースメーカーとソーシャルメディアのアプリケーションではテストの方法は変える必要がある。Google、マイクロソフト、Amazonは品質担当はQAの自動テストを作れる人たちにして成果を上げている。 10.2.1 テスト駆動開発はQAの代わりではない ふるまいを「検証」ではなく「表す」方法としてテストファースト開発(TDD)を行うと、どんなテストが必要かがより明確に理解でき、無駄がなく意味のあるテストの土台が手に入る。これは安心してコードをきれいにするのに役立つ。 しかし、これ自体がQA作業を置き換えるわけではないと言っている。セキュリティ関連のテストをしなくてよいわけでもないし、パフォーマンス関連のテストをしなくてよいわけではない。 10.2.2 ユニットテストは万能ではない 基本的に、ユニットテストはテストファーストで作れば、良い設計の手助けとなる。 しかし、ユニットテストではなくEnd to Endテストで確認したいものもある。たとえば、UIとのやりとり、DBとのやりとり、マルチスレッド、高度なコード、などだが、これらはテスト駆動開発を使用せずに書かれていて、テストのないコードになっておりテストが困難な場合が多い。 設計を変更して構わないなら本質的にテストできない機能はないが、設計を変更できないときもある。(既存のコードとやり取りしている場合、既存のパッケージを使用している場合など。) そういうわけで、ユニットテストはテストファーストで進めば、良い設計の手助けとなるが、万能ではない。 学び テストの種類と目的の理解が深まった 自身のプロダクトはどんなテストが必要か、こういったテストの種類を知った上で考える必要がある テスト駆動開発はパフォーマンステスト、セキュリティテストなどのQAをするのは難しい。(費用対効果が薄い) テストファーストでユニットテストを作れば良い設計の手助けになる UI、DB、マルチスレッド、高度なコードなどはテストが難しい(観測が難しい) 学びを活かすアイディア・行動 テストコードの目的の事前知識整理 現場でのテストコードの運用範囲を決める。 テストコードのコーディング規約づくり(テスト運用の注意点)

レガシーコードからの脱却 10.1 – 10.1.3

10.1 テストと呼ばれるもの 内容 テスト駆動開発の話の前に、一般的なテストの種類と目的を理解しようという前置き。 10.1.1 受け入れテスト=顧客テスト 受け入れテスト、あるいは顧客テストはストーリーのふるまいを明確にするもの。受け入れ基準を定義することで、受け入れテストがどうなったら終わりになるか明確になる。それにより、 開発者が特定のエッジケースや例外のシナリオの理解に役立つ 開発者がどうなれば正解か理解しきれずに進めてしまい、作り過ぎてしまうことを防止する などの効果がある。これにより開発者は安心して進む事が出来る。受け入れテストツールにGherkinという自動化ツールがあることの紹介。受け入れテスト駆動開発に関する書籍2冊紹介。 Lean-Agile Acceptance Test-Driven-Development Specification by Example 10.1.2 ユニットテスト=開発者によるテスト ユニットテストの概要が書いてある。 ストーリーよりも小さいテスト 開発者がテスト駆動開発で作るテストコードによるテスト ドキュメントとしても機能する 将来の変更時のミスを見つけるための回帰テストにもなる 10.1.3 それ以外のテスト=QAテスト ワークフロー中のコンポーネント間の相互作用をテストする結合テストのように、QAプロセスの「一部」になる。結合テストは、モックではない実際の依存関係を使用してコンポーネント間の相互作用をテストする。そのためユニットテストより多くの依存関係をビルドするのでビルド時間がかかる。 機能をテストするために、ユーザーの入力をシミュレーションするツールを使うこともあるが、これがテストの唯一の方法なら、考慮すべき設計上の制約があるかもしれない。できるかどうかはさておき、簡単に検証できるようにテスト可能なコードを書くことを追求すべき。 テストを2つのカテゴリに分類するとする。 リリース候補を検証するために必要なテスト そのほかすべて これらはできるだけ多く自動化することが重要だが、リリース候補のテストをすべて自動化することはさらに重要。人間を介入させると、外部への依存性が生まれ、うまくいかないことがあるからだ。問題が起きる可能性を最小限にするために、できるだけ依存関係を少なくなるようにするが、ソフトウェア開発プロセスも依存関係を少なくすることが必要だ。GPSなどの機能は人間によるテストが必要なケースだが、そういう場合はコンポーネントを切り分けて必要なところだけを人間に任せる。 学び 受け入れテストはストーリーの振る舞いを明確にするものであり、これが要件である。 これを基準にテストの増えすぎや実装の増えすぎを抑えることができる。 テストスイートの意味。テストの集合。 上記「内容」 結合テストの定義について明確になった。モックではなく実際の依存関係を使い、コンポーネント間の相互作用をテストする。 問題を減らすためにソフトウェア開発プロセスにおける依存関係も減らす。 人間を介入させると外部への依存関係が増える。 学びを活かすアイディア・行動 テストコードの目的の前提知識整理 受け入れテスト自動化の学習 現場のテストコードのコーディング規約づくり