ATECFESテストの活用による開発効率化
-
Upload
h-iseri -
Category
Technology
-
view
3.370 -
download
0
description
Transcript of ATECFESテストの活用による開発効率化
第一回Androidテスト祭り基調講演「より効率的に開発するために~スマートフォン時代のソフトウェアテスト・アプローチ」後篇
テストの活用による開発効率化
井芹 洋輝2011/8/6 @日本ノーベル
開発工程内でテストを活用し開発を効率化する
開発者テスト
テストのサポート
テーマ
デバッギングテスト
class MacroWord
TEST_F(TestMacroWord, test_macroData_macroWord_bug21){
MacroData macroData;macroData.push_back("AUTO_DEBUG_1");macroData.push_back("AUTO_DEBUG_2");macroData.push_back("AUTO_DEBUG_2");macroData.push_back("AUTO_DEBUG_2");macroData.push_back(“BB_H_");
MacroWord macroWord(macroData);
EXPECT_EQ("AUTO_DEBUG_1", macroWord.data_[0].macroName_);EXPECT_EQ(1, analyzer.data_[0].number);
EXPECT_EQ("AUTO_DEBUG_2", macroWord.data_[1].macroName_)EXPECT_EQ(3, analyzer.data_[1].number);
EXPECT_EQ(“BB_H_", macroWord.data_[2].macroName_);EXPECT_EQ(1, analyzer.data_[2].number);
}
class MacroWord
1. 自動テスト上でバグを再現する
TEST_F(TestMacroWord, test_macroData_macroWord__bug21){
MacroData macroData;
macroData.push_back("AUTO_DEBUG_2");macroData.push_back("AUTO_DEBUG_2");macroData.push_back("AUTO_DEBUG_2");
MacroWordProxy::wordCount(macroData);
EXPECT_EQ(3, MacroWordProxy::getSize(0));}
class MacroWord
1. 自動テスト上でバグを再現する
2. テストでバグを絞込み特定する
TEST_F(TestMacroWord, test_macroData_macroWord__bug21){
MacroData macroData;
macroData.push_back("AUTO_DEBUG_2");macroData.push_back("AUTO_DEBUG_2");macroData.push_back("AUTO_DEBUG_2");
MacroWordProxy::wordCount(macroData);
EXPECT_EQ(3, MacroWordProxy::getSize(0));}
class MacroWord
1. テスト上でバグを再現する
2. テストでバグを絞込み特定する
3. 修正後テストがパスすることを確認。テストはCIへ
バグを再現 バグを特定 バグ修正のチェック
学習テスト
boost::xpressive
TEST(regex, test_regex_fileseek){
namespace xp = boost::xpressive;string target; xp::smatch match;xp::sregex rex = xp::sregex::compile ("(¥¥.c|¥¥.h)$");
target = "test";EXPECT_EQ(false, xp::regex_search(target, match, rex));
target = "test.c";EXPECT_EQ(true, xp::regex_search(target, match, rex));
target = "test.h";EXPECT_EQ(true, xp::regex_search(target, match, rex));
target = "./../source/_svn/text-base/main.c.svn-base";EXPECT_EQ(false, xp::regex_search(target, match, rex));
target = "test.cpp";EXPECT_EQ(false, xp::regex_search(target, match, rex));
}動作チェック 用例ドキュメントとして活用
テストで動作を確認する。不安がなくなるまで試す
コードの新規設計
コードの追加・変更
記述改善
コードの保守
コードの解析
デバッグ
バグの早期検出
ユニットレベルでのバグ検出
進捗管理
TDD
仕様化テスト
学習テスト
探索的テスト
手法は続く ..
BDD
Cover & Modify
リファクタリングでのテスト デバッギン
グテスト
ATDD ストーリ駆動
テストファーストによる設計
Test as Documentation
主にアジャイル開発関連のテスト&探索的テストの文献で蓄積
開発効率化のためにテストを活用する
•バグの混入防止
•デバッグの効率化
•テスト容易性の確保
•バグの早期検出
•バグのコンポーネントレベルでの検出
テスト工数を削減する
•コードの解析補助
•設計補助
•コードのふるまいの保護
開発工数を削減する
開発でのテストの活用は、軽快な開発での品質確保を強力にサポートする
開発効率化のためにテストを活用する
テストによる開発効率化をどう実現するか
テスト工数の重複
製品/テスト変更時のテストの保守工数増加
課題
製品
テスト
テスト
テスト
仕様・構造で依存
全体整合を維持
特定工程で構築するほかに
開発中継続的に開発に合わせながらテストを構築する
テスト対象をFixしてテストを作りこむほかに
テスト対象の変化を許容しテストで変更をサポートする
担当ばらばらに作るのはでなく
開発プロセス全体で全体最適が得られるようにテストを育てる
テスト・アプローチの発想の転換が要求される
テストによる開発効率化をどのように推進するか
開発と一体化した
テストプロセス
テストを支える
テストインフラの構築
堅牢なテストの構築
開発と一体化した
テストプロセス
テストを支える
テストインフラの構築
堅牢なテストの構築
テストの保守・運用を柔軟に支える環境は、堅牢なテストの構築に丌可欠
テストインフラ
テストの活用をサポートするテストインフラを構築する
テストをいつでも/継続的に実施できるように
堅牢なテストを保守できるように
テスト設計をよりやりやすくするように
テストの活用をサポートするテストインフラを構築する
テスト側・テストの実行環境・テストの保守環境・テスト環境の構成管理…
プロダクト側・テスト向けの機能・IF・テスト容易性を支える設計…
テストインフラ:テスト側モデル例
●CI●各種テストサーバ
自動テスト環境ユニットテストUIベーステストシミュレータ実機評価
●テスト指標の評価カバレッジ評価結果管理テスト実装のメトリクス
●変更管理 バージョン管理サーバ
開発環境
●テスト環境 ユニットテストUIベースシミュレーション
●変更管理 DVCS
Jenkins CI×Monkey Runner/Junit/Robotium等
CIのテストの効果
継続的な回帰テストの実施
テストのビルドチェック
テスト環境の制約の回避
テストの品質指標の継続評価
テストインフラへの要求
CIへの自動テストの組み込み
テストのビルド・インテグレーションも評価する
1次元と2次元で評価する
コードカバレッジ
「60%」 ←極端に低くないか?テストは妥当か?
CIによるテストの保守
←テストを壊すコミットをしていないか?能力は妥当か?
CIはテストの実行だけでなくテストの保守・管理を支える
テストインフラの要
テストインフラへの要求
自動テストのCIへの組み込み
テスト条件に応じてテスト実行環境を分割サーバ側/開発側で多重化
重いテストはサーバ側へ
制約ある環境はサーバ側で自動化
テストインフラへの要求
テスト環境の分割・多重化
サーバ
開発環境
開発者テストの選択肢を広げる
テスト環境の制約回避
Slow Tests問題の改善 コミット時テスト:コミット間隔内で
TDD: 0.1秒でもかかれば遅すぎる
テストインフラへの要求
テスト環境の分割・多重化
サーバ
開発環境
分散型バージョン管理システム
Git/Mercurial/Bazaar
テストの分割・多重化に適した構成管理環境を構築
テストインフラへの要求
テストの分割・多重化への対応
開発環境
リポジトリ
共有テスト環境
コミット後でしかテスト結果が分からないテストに失敗するコードを変更管理リスク
開発環境
共有テスト環境
リポジトリ
①
②③テストが終わるまでコミットできない変更情報が損なわれるリスク
分散型でない場合
分散型バージョン管理システム
Git/Mercurial/Bazaar
テストの分割・多重化に適した構成管理環境を構築
テストインフラへの要求
テストの分割・多重化への対応
開発環境
共有リポジトリ
共有テスト環境
プライベートリポジトリ
テストを支える機能やインターフェース
適切なアーキテクチャ・構造(前半解説)
接合部
制御点
観測点
防御的機構
テストインフラ:プロダクト側
テスト時に製品用コード/テスト用コードの切替を実現する構造/IF
Dependency Injection/Dependency Lookup
DIコンテナ, Constructor Injection,…
差分プログラミング/リフレクション
プリプロセッサ/Class path設定
接合部(Seam)
テスト対象
テストコード
製品用コード
テスト用コード
Seam
テスト対象を間接的に制御するインターフェース
Mock/Stab/Fake
バックドアインターフェース
制御点(Control Point)
テスト対象
テストコード
依存コンポーネント
テスト対象の出力(直接/間接)を取得する
Mock/Spy
ロギング
テスト用インターフェース
観測点(Observation Point)
テスト対象
テストコード
依存コンポーネント
プロダクトに組み込まれた自己検証機構
防御的プログラミング、契約による設計
Assertion
エラー処理の拡充
ロギング処理・ログチェック処理の拡充
防御的機構
接合部/制御点
テスタビリティを落とすコンポーネントに配備
テスト丌能なコードが発生すれば組み込み
観察点/防御的機構
継続的に組み込み
デバッグやテストに支障がでれば組み込み
プロダクト側でのテストインフラの構築
慣習的に満遍なく組み込む
テストからフィードバックを得て継続的に作りこむ
プロダクト側でのテストインフラの構築
開発と一体化した
テストプロセス
テストを支える
テストインフラの構築
堅牢なテストの構築
トップダウン/ボトムアップ両面でテストの堅牢性を支える
上流工程の実践
堅牢なテスト設計構造の確保
テスト対象の分析と整理
実装工程の工夫
堅牢なテスト実装構造の確保
堅牢なテストを生み出すテストプロセスを構築する
トップダウン/ボトムアップ両面でテストの堅牢性を支える
テストプロセス
テスト計画
•以下を検討
•テスト環境の明確化
•テストフェーズの設定
•アプローチの設定
•スケジュール
•プロジェクトリスク分析
テスト分析
•テスト対象の分析
•テスト条件の分析・整理
•テスト観点の抽出
•テストタイプの抽出
テスト設計
•採用するテスト観点の構造化
•具体的なテストの種類の定義
•フェーズ
•テストタイプ
•環境
•テストケースの抽出
テスト実装
•具体値の設定
•テストコード/スクリプト/手順書等での実装
テスト上流工程の実践
テスト計画 テスト分析 テスト設計 テスト実装
テストの上流設計成果物は変更をある程度許容し、変更をサポートする
テスト環境の定義、テスト対象の分析、テスト条件の割り出し、テスト観点の定義と整理、…
テストの上流工程の実践
Ex)Test Doubleの運用 計画
テスト環境の明確化
対象の実装見込み
対象コンポーネントの分析
テスト対象の分析 テスト容易性に劣るコンポーネントの抽出
Seamの実装状況
観測点/制御点の分析
テスト条件の抽出
テスト環境の抽出
実行速度に対する要求分析
観測点/制御点の分析
観点の整理
Test Double使用/未使用時のテスト切り分け
テストの上流工程の実践
テスト計画 テスト分析 テスト設計 テスト実装
テスト設計でのアプローチ
課題
製品
テスト
テスト
テスト
仕様・構造で依存
全体整合を維持
ビッグバンでテストを構築するのでなく、必要な時に必要なテストを確保する
テストでなく、テストを支えるテスト容易性・テストインフラを継続的に満遍なく行き渡らせる
テスト設計では視点の転換が要求される
テストで実行できる状態を維持する
コードカバレッジ×CIの自動テスト
観測点×シミュレーションによる自動テスト
とりあえず実行できている対象なら、後からテストの追加・変更も容易になる
テストを支えるテスト容易性・テストインフラの確保
適切なインプット・手法にのっとって、整合のとれたテスト設計を行う
適切な設計に基づいていない雑多なテストは保守コストを肥大化させる
コンパクトかつ網羅的なテスト設計を行う
テスト実装での工夫
テスト計画 テスト分析 テスト設計 テスト実装
堅牢なテストの確保にはテスト実装の工夫が丌可欠テストコードやテストスクリプト
テスト実装での工夫
Ex)
可読性の改善
高リスクコードの分離・ラッピング
重複コードの共通化
テスト実装での工夫
@TestPublic void test_1(){
Int a;…
}
@TestPublic void test_無効なIDを指定すると例外を返す(){
Int dummyID;…
}
@TestPublic void test_hoge(){
…コピペコード……}
@TestPublic void test_fuga(){
…コピペコード……}
Private void 共通メソッド(){
…コピペコード…}
@TestPublic void test_hoge(){共通メソッド()…
}
@TestPublic void test_fuga(){共通メソッド()…
}
テスト実装の工夫
開発と一体化した
テストプロセス
テストを支える
テストインフラの構築
堅牢なテストの構築
テストによる開発効率化を実現するテストプロセス
開発成果物の一部としてテストを構築する
テストのフィードバックを元に製品の作りこみを行うフィードバックサイクルを維持する
開発工程 テスト工程
テストプロセスの実施
開発計画テスト計画
要求分析 設計・実装・作りこみ
テストインフラ
テスト分析
開発工程内テストの設計・実装・実施・作りこみ
テストインフラ
システムテストの設計
相互フィードバック相互フィードバック
製品側開発プロセス
テストプロセス
まとめ
テストの活用は、軽快な開発での品質確保を強力にサポートします
効果をより増幅するために プロダクトの工夫でテストをささえましょう 堅牢なテストを支えるテストインフラを構築しましょう 開発成果物の一部としてテストを取り込みましょう
開発とテストの設計・実装は並行させ、相互フィードバックを繰り返しましょう
まとめ