Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

ウォーターフォール開発でのxUnit活用

816 views

Published on

ウォータフォール開発におけるxUnitの活用法

Published in: Software
  • Be the first to comment

  • Be the first to like this

ウォーターフォール開発でのxUnit活用

  1. 1. ウォータフォール開発での xUnitの活用 せき よしひろ
  2. 2. この資料の目的 xUnitを用いたシステム開発の説明 • ウォーターフォールモデルのシステム開発におけるxUnitの位置づけ、効率 的・効果的なxUnitの適用方法 裏の目的 この資料を見たみなさんからDISられたいいろいろな意見をいただきたい。 • システム開発とxUnitに関わるいろいろな意見を聞きたい。 • みんなが理解できる文書を書けるようになりたい。
  3. 3. xUnitとは xUnitとは プログラムの単体テストを行うためのテスティングフレームワークの総称 メリット • テストの実行を自動化できる テスト手順実行の自動化、テスト結果確認の自動化 • いつでもテストが行える 回帰テスト、レグレッションテストが容易に行える • 品質および進捗の定量的可視化が行える。 • リファクタリングが容易になる (変えたほうがよいのに)動いているコードは変えるな、というジレンマからの脱却
  4. 4. xUnitによる品質および進捗の定量的可視化 Coberturaによるコードカバレッジ http://blog.octo.com/en/jenkins-quality- dashboard-ios-development/ より引用
  5. 5. xUnitの位置づけ – 疑問 要求分析 妥当性確認(受入)試験 基本(外部)設計 結合(総合)試験 詳細(内部)設計 単体試験 コーディング xUnit ココなのか? 試験規格が必要
  6. 6. xUnitはコードのみを検証をするものか? xUnitで試験すべきコードを試験できているか? • 試験すべきなのに存在していないコードはないか? • 不必要なコードを試験していないか? ⇒詳細(内部)設計からのトレーサビリティは取れているか? 詳細(内部)設計 コーディング xUnit 試験すべき コード 不必要な コード 試験すべきなのに 存在しないコード
  7. 7. xUnitの位置づけ – あるべき姿 xUnitで設計結果を検証したい! 要求分析 妥当性確認(受入)試験 基本(外部)設計 結合(総合)試験 with xUnit if possible 詳細(内部)設計 単体試験 by xUnit コーディング テストコードを 試験規格&成 績にしたい!トレーサビリティ トレーサビリティ トレーサビリティ
  8. 8. xUnitしやすい構造を考える ケーススタディ「ログイン画面」 アカウント seki パスワード ********* OK バウンダリ (⇒外部インターフェース) 処理 エンティティ (⇒保持データ) ※ バウンダリは画面だけではなく、 イベントを発生させる外部境界 (外部システムやタイマー等) DBログインする xUnitの対象としたい
  9. 9. ②業務処理 (Model) 本質的な処理 xUnitしやすい構造を考える 制御処理と業務処理に分ける アカウント seki パスワード ********* OK バウンダリ (⇒外部インターフェース) 処理 エンティティ (⇒保持データ) ①制御処理 (Controller) • 入出力データ変換 • 業務処理呼出制御 • バウンダリ制御 処理を①制御処理、②業務処理に 分けるのがポイント DB ログインする 単体試験対象結合試験対象
  10. 10. ①制御処理 xUnitしやすい構造を考える– ①制御処理(1/3) 制御処理の役割 • バウンダリからのイベントデータを変換し、呼び出す業務処理を制御。 例) HTTPリクエストをJavaオブジェクトに変換し、適切なメソッドを呼び出す • 業務処理結果を変換しデータを提供するバウンダリを制御。 例) 業務処理結果を用いて適切な画面を生成し、HTTPレスポンスとして送信 アカウント seki パスワード ********* OK account=seki&passwor d=#$%&submit=OK バウンダリ (⇒外部インターフェース) ②業務処理 処理A 処理B account: “seki” password: “#$%&” 変換 処理 制御 単体試験対象結合試験対象
  11. 11. xUnitしやすい構造を考える– ①制御処理(2/3) • ポイント • 制御処理で業務処理(本質的な処理)を行わない 制御処理は、イベントデータの変換、呼び出す業務処理の制御、バウンダリへのデータ変 換、バウンダリの制御(画面遷移等)に限定する。 • イベントデータは原則として基本型およびその集合に変換する。 文字列、数値、日付等の表記可能な型、およびその集合(クラス、リスト等) ⇒業務処理のテストを本質的にする、容易にする、デバッグしやすくするため ①制御処理 account=seki&passwor d=#$%&submit=OK バウンダリ (⇒外部インターフェース) ②業務処理 本質的な処理 account: “seki” password: “#$%&” 処理 変換 制御 単体試験対象 結合試験対象
  12. 12. xUnitしやすい構造を考える– ①制御処理(3/3) • 制御処理をxUnitだけで完結するのは難しい • バウンダリのイベント(クリック、D&D、スワイプ等)を真に模擬するのが困難。 • 画面デザインやユーザビリティ等の確認が困難 ⇒ 制御処理は人の手による結合試験が必要 • バウンダリからのデータ送信はxUnitで実現できる Webであれば、Selenium、CapserJS等で可能。 ①制御処理 account=seki&passwor d=#$%&submit=OK バウンダリ (⇒外部インターフェース) 処理 変換 制御 結合試験対象
  13. 13. xUnitしやすい構造を考える – ②業務処理 概要 必要に応じてエンティティにアクセスし、業務に必要な処理を実施する。 ポイント インターフェース(純粋抽象クラス)を作成し、単体試験(xUnit)の対象とする。 • 抽象メソッド(純粋仮想関数)の引数と戻り値は基本型およびその集合を原則とする。 • インターフェースと実装を分ける。 ① 制御 処理 ②業務処理 インターフェース account: “seki” password: “#$%&” 実装 処理 DB エンティティ (⇒保持データ)単体試験対象 単体試験対象
  14. 14. xUnitの位置づけ – あるべき姿 xUnitで設計結果を検証できる! 要求分析 妥当性確認(受入)試験 基本(外部)設計 結合(総合)試験 with xUnit if possible 詳細(内部)設計 単体試験 by xUnit コーディング テストコードを 試験規格&成 績にできる!トレーサビリティ トレーサビリティ トレーサビリティ
  15. 15. 詳細(内部) 設計 コーディング基本(外部)設計 業務処理(Model) xUnitのための開発 – 開発の流れ エンティティ仕様 制御処理 (Controller) インターフェース 実装 利用 コード 呼出 With 基本型 データ DB仕様 0..* 機能 View等 画面 コード (html等) バウンダリ仕様 業務処理 1 1..* 1 イベント With データ 可能ならxUnitする xUnitすべし UML等
  16. 16. xUnitのための開発 – 基本(外部)設計の成果物 ① バウンダリ(画面)とそのイベントを定義 バウンダリの仕様(画面デザインや入力制約等)は最も変わりやすい設計部分であるた め、最初から完全にする必要はなく、コーディング完了までに完成させればよいと考える。 ② バウンダリ(画面)間の関連(画面遷移等)を定義 ③ エンティティを定義 ⇒ 概念モデル(概念クラス図)の作成 ④ バウンダリのイベントがエンティティに及ぼす影響(業務処理)を定義 • エンティティに影響を及 ぼすイベントが業務処 理になりうる。 • ここで定義した業務処 理を詳細(内部)設計へ 入力とし、トレーサビリ ティを確保する。 ユーザ 担当業務 初期表示 R R 検索表示 R R 削除 D ユーザ削除 初期表示 新規登録 C ユーザ登録 初期表示 R R ユーザ取得 変更 U ユーザ変更 担当業務追加 C 担当業務追加 担当業務削除 D 担当業務削除 コピーして新規登録 C ユーザ登録 ユーザ変更 イベント 業務処理 ユーザ検索 エンティティ 画面 ユーザ一覧 ユーザ登録
  17. 17. xUnitのための開発 – 詳細(内部)設計の成果物 ① 業務処理のインターフェースを作成し、APIドキュメントを生成 • 基本(外部)設計で定義した業務処理をインターフェース内の抽象メソッドとして作成。 インターフェースの引数と戻り値は基本型およびその集合を原則 • ルールに則ってコメントを記述して、APIドキュメントを生成。 ② 複雑な業務処理は、UML等で細部構造や処理フローを作成 ③ エンティティからDB仕様(ER図、テーブル仕様等)を作成 詳細 設計 基本 設計 エンティティ仕様 インターフェース DB仕様 0..*機能 バウンダリ仕様 業務処理 1 1..* 1 UML等 トレーサビリティ トレーサビリティ APIドキュメント
  18. 18. xUnitのための開発 – コーディング(業務処理) ケーススタディ publicメソッドAのみをxUnitする場合、何件の試験ケースがあれば良いか? ⇒C0(命令網羅)でも数えたくない… インターフェース publicメソッドA 条件分岐=4 privateメソッドB 条件分岐=5 privateメソッドC 条件分岐=20 publicメソッドD 条件分岐=10 privateメソッドE 条件分岐=4
  19. 19. xUnitのための開発 – コーディング(業務処理) 末端から試験できるようにする privateメソッドを作らない Javaであればpackage private、C#であればinternalにする。 ⇒末端から試験すれば、試験ケースを極小化できる。 インターフェース publicメソッドA 条件分岐=4 package private メソッドB 条件分岐=5 package privateメソッドC 条件分岐=20 publicメソッドD 条件分岐=10 package privateメソッドE 条件分岐=4
  20. 20. xUnitのための開発 – コーディング(業務処理) 複雑な(条件分岐が多い)メソッドを作らない 循環的複雑度(CC: Cyclomatic Complexity)を考慮する。 • 循環的複雑度は条件分岐が多くなるほど数値が高くなる。 • 数値が高いほどバグが混入している可能性が高い。(一般的に15未満にすべし) • PMD、Coverity、QA-C等で計測できる。 • 数値が高くならないようなコーディングができてしまうのが難点。 3項演算子を使わない等のコーディングルールが必要 DRY原則を守り、同じコードを二度書かないようにする • CPD(Copy Paste Detector)を用いればコードの重複の検知が行える。
  21. 21. xUnitのための開発 – 単体試験手法(業務処理) 未実装のコードをモック(スタブ)で試験する 未実装のコードはモック(スタブ)を生成し試験する。 ⇒モッキングフレームワークを利用する • インターフェースを作成しておけば、モック(スタブ)は簡単に作れる。 • JavaならPowerMockito、C#ならMolesを利用する エンティティを考慮した試験を行う DBテスティングフレームワークを利用する • テスト開始前にDBを構築して、エンティティから正しい結果が得られるか試験する。 • JavaならDBUnit、C#ならDBUnit.Net。 • Seasar2やPlay Frameworkのように、サポートしているWebアプリケーションフレームワークも ある。 • 試験コストがかかる。 インターフェース 未実装 ⇒Mock化
  22. 22. xUnitのための開発 – 結合試験(業務処理) Webであればブラウザ制御/模擬試験ツールを利用する • 各種ツール • JavaならGebを用いてJunitと共に試験するのが良い。 • Seleniumであればクロスブラウザのテストが可能 • CasperJSがもっとも手っ取り早く試験できる。 ⇒ いずれのツールも試験結果画面を自動キャプチャすることができる。(試験結果のエ ビデンスを手動で貼り付けていくという作業を省力化できる。) • テスト自動化に手間がかかる。
  23. 23. xUnitの注意点 カバレッジを100%にすることを目的にしてはいけない • カバレッジが100%でも後フェーズで不具合が出ないことはない。 • 100%かどうかは重要ではなく、どのような試験をしたかが重要。 ⇒ 最低でも限界値分析法による試験を行うべき。 • 100%にするのは多大なコストがかかる。(⇒成長曲線を意識する) ⇒ 試験しにくいものは、レビューで担保するか後フェーズの試験に回す。 成長曲線(ゴンペルツ曲線、ロジスティック曲線) http://www.kogures.com/hitoshi/webtext/stat- seicho-kyokusen/ から引用
  24. 24. まとめ • xUnitを用いて設計結果を検証する • xUnitはコードの検証手段でなく、設計結果の検証手段にすべき。 • 上位設計からのトレーサビリティが取れるようにすることが大事。 • xUnitがしやすい設計、コーディングにする。 • 制御処理と業務処理を分け、業務処理で本質的な処理を実施する。 • テストしやすいコードを書く privateメソッドを使わない、複雑にならないようにする。 • xUnitは単に品質を確保するための手段である。 • カバレッジ100%は目的ではない。 試験しすぎはコストがかかる。成長曲線を意識し、程よい試験を。 • 最終目的は品質を確保し、納期を守り、利益を出すこと。

×