Showing 20 Result(s)

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

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

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

10.10.1 優れた受け入れテストのための7つの戦略 内容 受け入れテストは、開発者に何を作る必要があるのか、何がいちばん重要なのか、いつ終わるのかを教えてくれる。機能がどうなると終わるのかを知ることで、開発者が作りすぎるのを防ぐことになる。 ここでは10章(10.1.1)で伝えた内容で「受け入れテスト」について実際にどうやって実践する、有効な7つの戦略を説明している。 戦略 補足 作っているものが何に役立つのか明確にする そのまんま 誰が何のために何をしたいのかを知る そのまんま 受け入れ基準を自動化する ? エッジケース、例外、代替パスを表す ? 例示を使って具体化し、矛盾を一掃する ? 受け入れ基準とふるまいの分離 ? 各テストを一意にする ? 学び まだよくわからない。 要勉強。

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

11.1 レッド/グリーン/リファクタリング 内容 テストファースト開発には3つのことなるフェーズがある。 レッド/グリーン/リファクタリング だ。ユニットテストフレームワークの視覚効果が由来する。 レッドテストを失敗「させる」(コンパイルエラーも含まれる)。コンパイルエラーが起きたら「スタブアウト」を作り、テストを失敗させる。 グリーンすべてのテストを成功させる。 リファクタリングコードからリファクタリングし、テストをリファクタリングする 一つのユニットテストを作る中で、この3つのフェーズを繰り返し行っていく。一つのユニットテストというのは、1アサートという意味ではなく、1つのインターフェースに対してかかっている。1インターフェース:複数アサートはあり得る。 11.2 テストコードの例 Parsonという名前と年齢を持つクラスのテストを例にしてテストを解説している。 レッドのフェーズ。クラスが一つも無いところからハッピーパスのテストを書き始める。内容は、Personクラスのコンストラクタに渡した名前と年齢の値がPersonクラスの getName() と getAge() で取得した値と同じかどうかをテストする。クラスは無いのでコンパイルエラーが発生する。 コンパイルエラーのみ解消するために、Personクラスをスタブとしてとして作成してコンパイルエラーの部分を解消。スタブはクイックフィックス機能で作成し、メソッド返却値はダミーのままにすること。テストはコンパイルエラーが解消するので実行すると、返却値がダミーなのでエラーとなる。最初の目的はテストを失敗させることなのでOK。 グリーンのフェーズ。テストが通るようにプロダクトコードを修正する。コンストラクタの引数をメソッドで返すように実装する。 11.3 制約を導入する Personクラスの年齢に負の数を入れると年齢としてはおかしくなるので、そういった不備をなくすために制約を入れる。そういう場合の解説。ここでもテストファーストで書きながら説明している。 Personクラスに最大と最小の定数のテストを書く レッドフェーズ。 Personクラスに最大と最小の定数を記述しコンパイルエラーを出す。 コンパイルエラーをクイックフィックスを使い解消 実行すると失敗するのでレッド完了。 グリーンフェーズ。 Personクラスの最大値、最小値の値を適切に設定して実行。OKとなりグリーン完了。 次にコンストラクタの引数・年齢に最小値より小さい値を入れたらエラーとなるテスト レッドフェーズ 投げられるとOKとなる例外クラスをテストに書いてコンパイルエラーを起こす。 コンパイルエラーの例外クラスはクイックフィックスで作成し、コンパイルエラーを解消。 実行すると失敗するのでレッド完了。 グリーンフェーズ Personクラスのコンストラクタ内で最小値より小さい場合に例外を投げる処理を追加して実行。OKとなりグリーン完了。 次にコンストラクタの引数・年齢に最大値より大きい値を入れたらエラーとなるテスト 最小値のテストと同じ要領で最大値のテストを追加してグリーンまで完了させる。 リファクタリング 最小値と最大値で違う例外を投げるようにしたが、範囲外を表す1つのクラスにした方が使い勝手が良さそうなため、そちらを使うようにする。 11.4 作ったもの 11.2 – 11.3 で作ったものを通しての要点は「テストは仕様であり、テストは不要に重複しないように作る」のがポイントと言っている。 学び テストメソッド名に関する名前重要。何をテストしているかが分かれば、冗長でも構わない。何をテストしているかと仕様がわかることが重要。 コンパイルエラーの解消はクイックフィックスで解消していくことで、コードのタイプミスを減らせる。 レッドのフェーズは、コンパイルエラーからテストを実行して失敗させること。 最大値、最小値などの値よりも定数の名前が重要。境界値は時代の変化に合わせて変わるかもしれないが、重要なのは簡単に変えられるようにしておくこと。 例外をテストする方法。 レッド/グリーン/リファクタリングの3つのフェーズの基本。 テストコードは「失敗をさせ、正しいコードにすることで保証されたものとなる」で、このためにレッド/グリーンのフェーズがある。 …

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

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

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

10.11 本章のふりかえり 内容 正しいユニットテストの書き方で書けば、コードのリファクタリングのサポートをしてくれて「CLEAN」なコードにつながる。 テスト駆動開発は正しく行わないと、保守可能な効果はなくなる。 学び 内容の通り 学びを活かすアイディア・行動 特になし

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

10.10.2 優れたユニットテストのための7つの戦略 内容 ユニットテストのための大切な7つの観点を説明している。 戦略 補足 呼び出し側の視点に立つ 呼び出し側は何を必要としているのか、何を渡す必要があるのか。 テストを使ってふるまいを表す 仕様がわかるドキュメントになるようにわかりやすく書く。テストを最新に保つことが、ドキュメントを最新に保つことになる。 新しい違いを生み出すテストだけ書く テストは一意にする。観察可能なテストにして無駄なテストをなくす。 失敗したテストにパスするためのコードのみを書く まず失敗するコードを書き、テストが通るコードに書き直す。このルールに則った場合に「テストが通ったら正しい」という保証になる。 テストを使って、ふるまいを作る ハッピーパスから作るにしろ、例外からにしろ、テストから作る コードをリファクタリングする 反復開発する場合、保守性は重要だからリファクタリングをして保守可能な状態にする テストをリファクタリングする 実装に依存したテストではなくふるまいを表したテストを書いていなければ不要に修正する必要はない。ただし、テストもコードであるため保守可能な状態にしないとコード品質に影響する可能性がある。 学び テストはコードだという認識。保守可能な状態にリファクタリングする必要がある。 テストはふるまいを表すべき。実装に依存したかたちにしてしまうと不要に修正する必要の可能性が出てくるし、そうなると保守できなくなる。 テストは仕様を表す最新のドキュメント。実行することでプログラムが正しいことを表すため、仕様がわかるように書くことで、最新のドキュメントとなる。メソッドコメントのように変更し忘れがなくなる。 学びを活かすアイディア・行動 現場のユニットテストのコーディング規約づくり

Android の Dialog の基礎

前略: ダイアログはDialogではなくDialogFragmentで作るというめんどくささ Android でダイアログを作ろうとすると、今は「DialogFragment で作る」というのが一般的です。ただ、調べると、DialogFragmentを使わずにAlertDialogだけでダイアログを作る記事なども見受けられると思います、、、、ここでは、ダイアログはDialogFragmentで作るのが一般的だということと、その時の注意点を。 Dialog is ダイアログUIを提供するクラスです。代表的なサブクラスはAlertDialogやDatePickerDialogなどがあります。DialogFragmentを使う場合でも、UIを実現しているのはこれらのクラスが実態になります。UIとしては画面上の一部で表示するのが一般的ですが、全画面として表示するようにカスタムすることも可能です。参考 DialogFragment is 公式サイトによると、以下のように。 これらのクラスでは、ダイアログのスタイルと構造が定義されますが、ダイアログのコンテナとして DialogFragment を使用してください。DialogFragment クラスでは、Dialog オブジェクトでメソッドを呼び出す代わりに、ダイアログの作成と表示の管理に必要なすべてのコントロールが提供されます。DialogFragment を使ってダイアログを管理すると、ライフサイクル イベント(戻るボタンを選択したときや画面を回転したときなど)が正しく処理されます。DialogFragment クラスを使用すると、従来の Fragment のように、大きな UI で埋め込み可能なコンポーネントとしてダイアログの UI を再利用することもできます(ダイアログ UI を大小の画面で異なって表示させる場合など)。 少しかいつまんで言うと↓↓↓ ダイアログのコンテナとして DialogFragment を使ってね。 ダイアログ制御に必要なすべてのコントロールができるよ。 戻るボタン押したときや画面回転したときなどのライフサイクルイベントで正しく動くよ。 DialogFragment 使わないといけないの?? 「ダイアログ表示したいだけなのに、何?ダイアログ「フラグメント」って」「なんか直感的じゃないんだよな、ダイアログでいいじゃん」と思う人もいると思います。少し歴史を紹介しますが、使わないといけないというわけではないです。が、もう Google 的には Dialog 使う場合は DialogFragment を使うという感じになってます。 Android2系時代当時、Dialog表示は Activity の onCreateDialog メソッドでダイアログ表示処理を書いて、 showDialog というメソッドを呼び出すことで onCreateDialog が実行され、表示していた。これが一般的だった。 ちなみに、 onCreateDialog で実装しないと画面回転時などにクラッシュするか、落ちないにしても WindowLeak …

BroadcastReceiver の基礎

前略: BroadcastReceiver の概要とポイントをまとめた 開発チーム内での共通認識レベルとして必要かなと思われる概要とポイントをまとめました。図とかあったらよいかと思ったんですが、そこまでできていないです。文字だけです。そして、基本は公式サイトを抜粋・文言変更して作ってます。 ブロードキャスト(ブロードキャストメッセージ)とは BroadcastReceiver を調べると、用語としてブロードキャスト(またはブロードキャストメッセージ)というのが出てきますので、念の為それも整理します。そもそもブロードキャストとは?調べてみると、 「コンピューター-ネットワークで、接続されているすべての端末に対し相手を特定せずにデータを送ること。」 というようなことが書いてあります。なので、 ブロードキャストメッセージとは 「コンピューター-ネットワークで、接続されているすべての端末に対し相手を特定せずに送られるデータのこと。」 と言えそうです。これらを念頭に置くと、以下がわかりやすくなるかもしれません。 BroadcastReceiver is Android は OS やアプリから、なんらかのイベントが発生したことをシステム全体に対して送受信することができます。まず、これが Android におけるブロードキャストです。たとえば、端末の起動、デバイスの充電の開始など、さまざまなシステムイベントが発生したときに、OSがイベント発生をブロードキャストします。また、アプリから独自のブロードキャストを送信することもでき、この場合はアプリ間のイベント通知として使用されたりするのが一般的です。Androidでは、そういったOSやアプリから送信されるブロードキャストを受信するためのコンポーネントとして、 BroadcastReceiver というものを用意しています。アプリは BroadcastReceiver を使って、特定のブロードキャストを受信するように登録することで、そのブロードキャストをシステムから受信できる仕組みになっています。ブロードキャストメッセージの実態は intent を使うようになっており、ブロードキャストをアプリが受信すると、受信した BroadcastReceiver の onReceive が動き、引数の intent にその中にイベント発生を表すアクション文字列が入ってくるようになっています。たとえば、機内モードに切り替えたときであれば android.intent.action.AIRPLANE_MODE という文字列がアクションとして intent に入っています。電源ONや機内モード切り替えなどのシステムのイベント発生によるブロードキャストをシステムブロードキャストといいます。システムブロードキャストのアクション一覧は BROADCAST_ACTIONS.TXT に記載されています。(ググれば出てきます。) システムブロードキャストの動作変更 Android OSのバージョンアップに応じて、システムブロードキャストの動作についても定期的に変更されています。特に、OSのバージョンが挙がっていくにあたって、ブロードキャストに対する制約が増えていく傾向にありますので実装観点でも注意が必要です。 Android 9(API レベル 28)以降NETWORK_STATE_CHANGED_ACTION のブロードキャストはユーザーの位置情報や個人を特定できるデータを受信しなくなっている。Android 9 以降のデバイスは、Wi-Fi からのシステム ブロードキャストに SSID、BSSID、接続情報、スキャン結果は含まれない。- Android 8.0(API レベル 26)以降システムはマニフェストで宣言されたレシーバーに対して追加の制限を課します。アプリのtargetSdkVersionが …

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

10.8 テスト駆動開発をチームに広める 内容 テスト駆動開発の正しいやり方を身につける唯一の方法なんてものは存在しないが、まずは、良い共通理解を形成するところから始める。 テスト駆動開発導入にあたって足かせになるのは、経営者と開発者それぞれ異なったテスト駆動開発に対する負の先入観。これらを統一した共通認識にするところから始める必要がある。 10.9 テストに感染する 開発者の最初の大きな課題は最初にテストを書くことが不快だということだ。なぜ不快かというと、実装を集中して書くことを訓練してきたからだ。その習慣をやめて最初にテストを書くようになるまで長い時間がかかる。 開発者は「目的」と「やり方」の世界を行き来するが、まず「作るものは何か」(目的)から始めるべきだ。それがインターフェイスであり、テストだ。 まず、呼び出すメソッドの外観、名前、入力パラメーター、戻り値を明らかにする。それから「どうやって作るか」に焦点を合わせる。 一直線にプロダクションコードを書くという習慣をやめれば、自然にテストファーストに考えられる。この現象を、テスト駆動開発の初期提案者の1人エリック・ガンマ氏が「テストに感染し始めた」と言った。 学び チームに導入したければ、経営者、開発者はそれぞれの観点でメリット、デメリットを整理して共通認識になるように準備する必要がある。 テストを最初に書く違和感の直し方は、「作るものは何か?」(外観、名前、入力パラメータ、戻り値)を明確にし、そのテストを書くところから始めよう。 最初にテストを書く習慣が開発者にはない。 学びを活かすアイディア・行動 テスト駆動開発のメリデメの整理。経営観点と開発観点。 テストコードの目的の事前知識整理

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

10.7 テスト駆動開発は失敗することがある 内容 テスト駆動開発はスキルであり、スキルが十分に習得されていないと、開発者の負荷になり、プロジェクトの進行は遅くなる。それが原因でプロジェクトが失敗するというように判断したのなら、テスト駆動開発をやめるのが正しい。 開発者が対応できないときは、開発者に新しい学習曲線の負担をかけるべきではない。テスト駆動開発を続けてプロジェクトを失敗させ倒産するか、テスト駆動開発をやめるかの選択に直面しているなら、テスト駆動開発をやめることはいちばん確実で正しい。リリースの準備ができているなら、テスト駆動開発の導入に挑戦する必要はない。 テスト駆動開発の間違った会社の例 とある会社ではコードの品質、「CLEAN」なコード、優れた開発原則は導入できていたにもかかわらず、テストの運用がうまくいかなかった。 テストが冗長コードをクリーンにするのに1日、テストをクリーンにするのに1週間かかっていた。原因はテストコードもコードであると見直しておらず、テストの冗長性が非常に高くなっていたため。 インターフェースではなく実装に依存したテストインターフェイスに対してテストするのではなく、実装に対してテストをしていたため、コードのクリーンアップをしようとしたときに、テストをクリーンアップするのが困難だった。 ユニットテストの書き方が違うテストを実行するためにOracleに接続していて、モックを使っておらず実際のDBに接続していたため時間がかかっていた。 テストの量を不要に増やした彼らはQAの立場で「テストが多ければ良いテストだ」と考え、あまりにも多くのテストを書いていた。上記の要因を踏まえ、大量の運用できないテストを作っていた。 学び テスト駆動開発はスキルであり、習得が必要。習得には負荷がかかるので導入は計画的にしなければいけない。 負荷が高すぎたり、間違ったやり方で工数が上がりすぎては本末転倒。 学びを活かすアイディア・行動 ユニットテストのコーディング規約づくり失敗するとどうなるかを書く。