継続的インテグレーションとテストの話
- 2. 自己紹介
岩田 英一郎 (@eiichiroi)
元さいたまな人
経歴
2009年6月∼ アルバイト
2010年3月 埼玉大学 大学院理工学研究科 修了
2010年8月∼ PFI入社
所属
製品開発部
Sedueプロジェクト
仕事
Sedue(検索エンジン)の開発
コア∼運用ツールを幅広く
研究開発成果の取り込み
2
- 5. 本日の内容
型?
残念ながら違います
継続的インテグレーション
概要/流れ/価値/懸念点/導入
テスト
単体テスト/統合テスト/システムテスト/受け入れテスト
結論
継続的インテグレーションとテストは重要
3
- 6. 本日の内容
型?
残念ながら違います
継続的インテグレーション
概要/流れ/価値/懸念点/導入
テスト
単体テスト/統合テスト/システムテスト/受け入れテスト
結論
継続的インテグレーションとテストは重要
注意
基礎的な話が多めなので、ご存知の方はあまり面白くないかも
3
- 7. 継続的インテグレーションとは?
インテグレーション
複数のコンポーネントで構成されるソフトウェアが一つのシステム
として機能することを検証すること
継続的?
変更がある度に!
目的
ソフトウェア品質の向上
特に重要なこと
迅速なフィードバックを得られるようにすること
自動化が効果的(ボタン一発!)
4
- 8. 継続的インテグレーションの流れ
監視
バージョン管理 インテグレーション
システム サーバー
(git, subversion, ...) (jenkins, ...)
5
- 9. 継続的インテグレーションの流れ
監視
バージョン管理 インテグレーション
システム サーバー
(git, subversion, ...) (jenkins, ...)
1.開発/検証/パッチレビュー
2.プライベートビルド 5
(開発環境でのビルド)
- 10. 継続的インテグレーションの流れ
監視
変更をコミット
バージョン管理 インテグレーション
システム サーバー
(git, subversion, ...) (jenkins, ...)
1.開発/検証/パッチレビュー
2.プライベートビルド 5
(開発環境でのビルド)
- 11. 継続的インテグレーションの流れ
監視 実行
変更をコミット
ビルドスクリプト
バージョン管理 インテグレーション
1.コンパイル
システム サーバー
2.テストの実行
(git, subversion, ...) (jenkins, ...)
3.インスペクションの実行
(コードの解析)
4.デプロイ
1.開発/検証/パッチレビュー
(パッケージ作成など)
2.プライベートビルド 5
(開発環境でのビルド)
- 12. 継続的インテグレーションの流れ
フィードバックの生成
監視 実行
変更をコミット
ビルドスクリプト
バージョン管理 インテグレーション
1.コンパイル
システム サーバー
2.テストの実行
(git, subversion, ...) (jenkins, ...)
3.インスペクションの実行
(コードの解析)
4.デプロイ
1.開発/検証/パッチレビュー
(パッケージ作成など)
2.プライベートビルド 5
(開発環境でのビルド)
- 13. 継続的インテグレーションの流れ
フィードバックの通知
フィードバックの生成
監視 実行
変更をコミット
ビルドスクリプト
バージョン管理 インテグレーション
1.コンパイル
システム サーバー
2.テストの実行
(git, subversion, ...) (jenkins, ...)
3.インスペクションの実行
(コードの解析)
4.デプロイ
1.開発/検証/パッチレビュー
(パッケージ作成など)
2.プライベートビルド 5
(開発環境でのビルド)
- 14. ビルドの種類
プライベートビルド インテグレーションビルド リリースビルド
種類
プライベートビルド
インテグレーションビルド
リリースビルド
実行される場所や内容が異なる
迅速なフィードバックを得られるようにするため
6
- 15. ビルドの種類 - プライベートビルド
プライベートビルド インテグレーションビルド リリースビルド
開発環境でのビルド
リポジトリに変更をコミットする前に実行する
個人(開発者)向け
ビルドの範囲
コンパイル
軽量なテスト(単体テスト)
実行時間の目安
10分以内
7
- 17. ビルドの種類 - インテグレーションビルド(2/3)
プライベートビルド インテグレーションビルド リリースビルド
コミットビルド
リポジトリに変更がコミットされる度に実行される
ビルドの範囲
コンパイル
軽量なテスト(単体テスト)
実行時間の目安
10分以内
9
- 18. ビルドの種類 - インテグレーションビルド(3/3)
プライベートビルド インテグレーションビルド リリースビルド
2次ビルド
コミットビルドが成功した後に実行される(場合によって日次/週次)
ビルドの範囲
コンパイル
軽量なテスト(単体テスト)
重量なテスト(統合テスト/システムテスト/受け入れテスト)
インスペクション
デプロイ
実行時間の目安
10分∼数時間以内
10
- 19. ビルドの種類 - リリースビルド
プライベートビルド インテグレーションビルド リリースビルド
リリース前に行うビルド
ユーザ(顧客)向け
ビルド範囲
コンパイル
テスト
単体テスト/統合テスト/システムテスト/受け入れテスト
性能テスト/負荷テストを含めることも
インスペクション
デプロイ
実行時間の目安
インテグレーションビルドと同様 + α
11
- 21. 継続的インテグレーションの価値
検証コストの削減
ビルドの自動化による恩恵
常にデプロイ可能なソフトウェアを提供できる
迅速なフィードバックによりバグの混入∼修正まで短時間で
失敗したら最優先で直す
修正/機能追加を自信を持って行える
既存のテストを壊してないかすぐ分かる
12
- 22. 継続的インテグレーションの価値
検証コストの削減
ビルドの自動化による恩恵
常にデプロイ可能なソフトウェアを提供できる
迅速なフィードバックによりバグの混入∼修正まで短時間で
失敗したら最優先で直す
修正/機能追加を自信を持って行える
既存のテストを壊してないかすぐ分かる
品質の高いソフトウェアへ
12
- 23. 継続的インテグレーションの懸念点
CIシステムの構築が大変?
出来ればプロジェクトの初期から導入するのが望ましい
プロジェクトの途中から導入する場合はやや大変
自動化に必要な機能開発など
段階的導入を検討する
‒ 日次ビルド、コンパイルと単体テスト∼
ハードウェア/ソフトウェアの費用は?
削減できる検証コストに比べれば微々たるもの
開発環境で走らせれば良いのでは?
クリーンなビルド環境は重要です
プライベートビルドが通っても、インテグレーションビルドが通ら
ないこともあります(迫真)
13
- 24. 継続的インテグレーションの導入
Jenkins Travis CI
インテグレーションサーバーのセットアップ
Jenkins
Travis CI
ビルドの自動化
1. コンパイル
2. テスト
3. インスペクション
4. デプロイ
14
- 25. Jenkins - セットアップ
Jenkins Travis CI
Jenkins
インストール
起動
ブラウザ経由でポチポチ設定
リポジトリの場所の登録
ビルドスクリプトの登録
ビルド結果の通知方法の設定
ビルド結果もブラウザで確認できる
プラグインも豊富
続きは
Jenkins実践入門
Jenkins ユーザ・カンファレンス 2012 東京
15
- 26. Jenkins - 色々なフィードバック手段を試してみる
Jenkins Travis CI
フィードバック手段
メール
光(ランプ)
音
タスクバー、Growl
ブラウザのプラグイン
いつ、だれに、何をフィードバックするのかを考慮しつつ決める
16
- 28. Travis CI
Jenkins Travis CI
Travis CI
継続的インテグレーションを提供するサービス
オープンソース向け
GitHubと連携
http://travis-ci.org/
※公式対応言語に注意(C++とかD言語とか公式対応してません)
セットアップ
1. GitHubとの連携を許可
2. リポジトリ毎にTravisの有効/無効を設定
3. ビルドスクリプトを書いてリポジトリにコミット
.travis.ymlをリポジトリのトップディレクトリへ
pficommonをforkして登録してみた
http://travis-ci.org/#!/eiichiroi/pficommon
18
- 29. 継続的インテグレーションの導入
コンパイル テスト インスペクション デプロイ
インテグレーションサーバーのセットアップ
Jenkins
Travis CI
ビルドの自動化
1. コンパイル
2. テスト
3. インスペクション
4. デプロイ
19
- 30. ビルドの自動化 - 1.コンパイル
コンパイル テスト インスペクション デプロイ
コンパイル手順の自動化
waf
autotools
make
rake
ant
(言語やプロジェクトに応じて選択)
20
- 31. ビルドの自動化 - 2.テストの実行
コンパイル テスト インスペクション デプロイ
テストフレームワーク
Google Test, Boost.Test
(言語やプロジェクト、テストの種類に応じて選択)
テストの実行範囲が重要
迅速にフィードバックを得られるように、分類して実行範囲を絞る
段階的にテストを実施すると良い
軽量なテスト
単体テスト
重量なテスト
統合テスト/システムテスト/受け入れテスト/...
データベースのセットアップなどが必要になることも多い
21
- 32. ビルドの自動化 - 3.インスペクションの実行(1/2)
コンパイル テスト インスペクション デプロイ
ソースコードの静的解析・動的解析
コーディング規約違反の検出(cpplint)
コピペの検出
各種コードメトリクスの計測
クラス数
メソッド数
テストの網羅率(カバレッジ)
注意点
解析をして終わりにしない。何かしらの対処を行う
コーディング規約違反を直す
コピペは共通化できるなら直す
カバレッジが低いところを補強する
22
- 33. ビルドの自動化 - 3.インスペクションの実行(2/2)
コンパイル テスト インスペクション デプロイ
pficommonのカバレッジを測定してみた
gcc + gcov + lcov
スクリプト
https://gist.github.com/2643761
結果
http://eiichiroi.github.com/pficommon/
network...(^p^)...pull requestお待ちしております
23
- 34. ビルドの自動化 - 4.デプロイ
コンパイル テスト インスペクション デプロイ
ソフトウェアを利用可能な状態で提供すること
デプロイ対象のプラットフォームごとに
(テストやインスペクションの実施)
パッケージの作成
設定ファイルの準備
...
継続的にデプロイまで行うのは割と大変
短期間でのリリースを行う場合はほぼ必須になる
24
- 35. テスト
単体テスト 統合テスト システムテスト 受け入れテスト
テストのないコードはレガシーコード!
ソフトウェアの品質を担保するために必要
テストの分類(IEEE標準規格)
単体テスト
統合テスト
システムテスト
受け入れテスト
注意
組織によっては分類が少ないことも
コンパイル 単体テスト 統合テスト システムテスト 受け入れテスト インスペクション デプロイ
プライベートビルド
コミットビルド 2次ビルド
リリースビルド
25
- 36. 単体テスト
単体テスト 統合テスト システムテスト 受け入れテスト
個々のコンポーネントに対して個別に行うテスト
コンポーネント 車の場合
関数 エンジン
クラス
キャリブレータ 他のエンジン部品
...ねじ?
テストする人
燃料モジュール 空気モジュール
各コンポーネントの開発者
ねじ1 ねじX 何か ねじ1 何か
優れた単体テスト
実行速度が速い(1テスト0.1秒では遅い)
問題箇所の特定がしやすい
26
- 39. 単体テストの注意点
単体テスト 統合テスト システムテスト 受け入れテスト
単体テストではないもの
外部リソースに依存するテスト
データベース/ネットワーク/ファイルシステムにアクセスする
→モックオブジェクトなどで分離
細かいテクニックはレガシーコード改善ガイドを参照
ソフトウェアを変更するにはテストが重要
テストのない状況からテストを整備していく方法
依存関係を排除するテクニック集
28
- 40. 統合テスト
単体テスト 統合テスト システムテスト 受け入れテスト
システムの一部を対象とするテスト
複数のコンポーネントが依存関係を持つテスト
外部リソースへ依存するテスト
データベース/ネットワーク/ファイルシステムにアクセスする
車の場合
テストする人
開発チームの人 エンジン
優れた統合テスト
キャリブレータ 他のエンジン部品
網羅率が高い
燃料モジュール 空気モジュール
単体テストと統合テストの境界
ソフトウェアの規模による ねじ1 ねじX 何か ねじ1 何か
テストの実行時間が十分少ないときには分けないことも
29
- 41. 統合テストの例: pficommon
単体テスト 統合テスト システムテスト 受け入れテスト
pfi::text::jsonのテスト
pficommon/src/text/json_test.cpp
粒度が粗めのテストが多い
pfi::data::serializationのテスト
pficommon/src/data/serialization_test.cpp
色んな型の変数をファイルへシリアライズしている
興味ある型はgithubを見てください
30
- 42. システムテスト
単体テスト 統合テスト システムテスト 受け入れテスト
システム全体を対象とするテスト
車の場合
UIやAPIを経由してテストする
車
テストする人
テストチーム
駆動装置 HVAC 他の車体部品
優れたシステムテスト
幅広いテスト エンジン トランスミッション
機能/負荷/性能テストなど
キャリブレータ 他のエンジン部品
統合テストとシステムテストの境界
ソフトウェアの規模によって変わる
何を「システム」と定義するか?サブシステムに分割することも
統合テストとシステムテストを合わせて結合テストと呼ぶことも?
組織によって違ったりしてカオス
31
- 43. 受け入れテスト
単体テスト 統合テスト システムテスト 受け入れテスト
ユーザの要件を満たしているかどうかのテスト
アルファテスト
開発者側で行う受け入れテスト
ベータテスト
顧客側で行う受け入れテスト
ユーザビリティのテストなども行う
テストする人
顧客
顧客層を代表する人
顧客やソフトウェアのユースケースを良く理解している
優れた受け入れテスト
実環境とテスト環境が同じ
ハードウェア/ソフトウェア/データ/人
32
- 44. まとめ
継続的インテグレーション
概要/流れ/価値/懸念点/導入
テスト
単体テスト/統合テスト/システムテスト/受け入れテスト
結論
継続的インテグレーションとテストは重要
検証コストの削減
常にデプロイ可能なソフトウェアを提供できる
修正/機能追加を自信を持って行える
段階的にでも良いので導入しましょう
33
- 45. 参考文献
継続的インテグレーション入門
やや古くなっているが、まとまっている
Jenkins実践入門
Jenkins導入するなら
体系的ソフトウェアテスト入門
テストプロセス、テスト計画、テスト実行
レガシーコード改善ガイド
開発者は読むべき
34