『継続的デリバリー』 第10章 学習メモ

アプリケーションのデプロイ・リリースの概観

1.はじめに

継続的デリバリーにおける、アプリケーションのデプロイ・リリースについての調査記録です。
継続的デリバリーの中での、アプリケーションのデプロイ・リリースについての概観を記載します。
『継続的デリバリー 信頼できるソフトウェアリリースのためのビルド・テスト・デプロイメントの自動化』の第10章に対応します。

2.概要・目的

デプロイメントとリリースの差異は、設定ファイルなどにカプセル化する必要がある。
デプロイメントとリリースの主な違いは、ロールバックの方法である。
すべての環境に対するあらゆる変更の適用のために唯一使える仕組みを提供する。

3.対応概要

(1)リリース戦略の作成

リリース戦略の作成の観点は以下の通り。

  • プロジェクト開始時での決定事項
  • リリース計画時での決定事項
  • 商品化のための決定事項

(2)デプロイ

デプロイのための観点は以下の通り。

  • 最初のデプロイ
    • 下準備用のイテレーション
    • 疑似本番環境のための仮想化・チキンカウント
      • 疑似本番環境の特徴
  • リリースプロセス(自動ステージ後のビルドの扱い)のモデル化
  • ビルドの反映
  • テストステージのワークフロー
  • 設定の反映の検証のためのスモークテスト・監視ツール
  • オーケストレーション
  • ステージング環境へのデプロイメント

4.対応詳細

ロールバックの制約は以下の2つ。

  • データ
  • 複数システムの統合

ロールバックの原則は以下の2つ。

  • 本番システムをバックアップしてからリリース作業に入る
  • 作成した計画に基づいてロールバックを試行する

ロールバック・ゼロダウンタイムリリースの観点は以下の通り。

  • 直近の正常動作するバージョンの再デプロイによるロールバックの是非
  • ゼロダウンタイムリリースにおけるリリースプロセスの疎結合
  • ブルーグリーンデプロイメント
    • DBとコストへの対応が必要
  • カナリアリリースの機能と作用
  • 緊急修正時の規範
  • 継続的デプロイメントを可能にするデプロイメントパイプライン
  • ユーザがインストールするソフトウェアの継続的リリース
    • 自動更新がよい
    • バックアップ
    • 移行スクリプト
    • クラッシュレポート

デプロイメントのためのヒントや裏技は以下の通り。

  • 自動化できていない部分のデプロイメント作業の記録
  • 古いファイルは削除せず移動する
  • システムのウォームアップ
  • スモークテスト
  • 本番環境へのアクセス制限

5.影響・作用

リリースはプロジェクト全体で初期から継続的な改善が必要。
共同作業で、より効率的なデリバリープロセスを構築する。

6.おわりに

以上が、継続的デリバリーの中での、アプリケーションのデプロイ・リリースについての概観です。

7.参考文献

『継続的デリバリー 信頼できるソフトウェアリリースのためのビルド・テスト・デプロイメントの自動化』 第10章 アプリケーションをデプロイ・リリースする

『継続的デリバリー』 第9章 学習メモ

非機能テストの概観

1.はじめに

継続的デリバリーにおける、非機能テストについての調査記録です。
継続的デリバリーの中での、非機能テストについての概観を記載します。
『継続的デリバリー 信頼できるソフトウェアリリースのためのビルド・テスト・デプロイメントの自動化』の第9章に対応します。

2.概要・目的

非機能要件の中でも、特に以下を重点として扱う。

非機能要件は、ソフトウェアデリバリーに関する重大なリスクとなる。
非機能要件は、システム特性とも呼ぶ。
どの非機能要件が重要なのかをプロジェクトの開始時に見つけることが重要。
非機能要件をデリバリースケジュールの中で定期的に計測する。

3.対応概要

非機能要件の分析の観点は以下の通り。

  • 可監査性など、各システム特性も1つの機能として開発する。
  • ユーザビリティの問題をパフォーマンスの問題としない。ユーザビリティとパフォーマンスは別個に扱う。

4.対応詳細

キャパシティを確保するためのプログラミングの観点は以下の通り。

キャパシティの計測手法の観点は以下の通り。

  • 利用シナリオのシミュレートをするテスト
  • 複数のテストを1つのテストスイートで並列実行
  • テストの成功/失敗基準の設定
    • 再現性の高い環境
    • 閾値の調整
    • 最大負荷により閾値を設定

キャパシティテストの観点は以下の通り。

  • カナリアリリース戦略の一環として実行
  • 受入テストを引用し、規模を拡大。成功条件を設定して、システムに負荷をかける
  • アプリケーションの記録と再生
  • UI経由でのキャパシティテストを避ける
  • サービスや公開APIへのインタラクションの記録
  • キャパシティテスト用スタブ
  • デプロイメントパイプラインにキャパシティテストを追加

キャパシティテストシステムは、実験用のリソースとなる。

5.影響・作用

非機能要件とは、現実の要件として検討する必要があるが、利用するユーザの考える要件とは異なるもの。
問題の観察や分析が重要であり、これにより、非機能要件の受け入れ基準を、機能要件と同様に設定できるようになる。
受入テストを元にした、より広範囲なシナリオベースのテストで非機能要件を検証することで、システムの特性を包括的で保守可能な形式で維持することができる。

6.おわりに

以上が、継続的デリバリーの中での、非機能テストについての概観です。

7.参考文献

『継続的デリバリー 信頼できるソフトウェアリリースのためのビルド・テスト・デプロイメントの自動化』 第9章 非機能要件をテストする

『継続的デリバリー』 第8章 学習メモ

自動受入テストの概観

1.はじめに

継続的デリバリーにおける、自動受入テストについての調査記録です。
継続的デリバリーの中での、自動受入テストについての概観を記載します。
『継続的デリバリー 信頼できるソフトウェアリリースのためのビルド・テスト・デプロイメントの自動化』の第8章に対応します。

2.概要・目的

自動受入テストは、ドメインの観点でシステムをテスト・表現する。
ドメインの要求に対してサービスを検証し、またリグレッションから保護する。

3.対応概要

自動受入テストの観点は以下の通り。

保守しやすい受入テストスイートのために、受入テストをレイヤ化する。
実装レイヤでは、ドメインの言語を使用し、アプリケーションとのやりとりの詳細を含まずAPIやUIを参照しない。

また、GUIに対するテストの回避のために、APIをテストハーネスから呼び出す。

4.対応詳細

(1)受入テストの作成

受入テストの作成の観点は以下の通り。

  • アナリスト・テスターの役割
  • イテレーティブな分析プロセスにおけるメンバの役割
  • 受け入れ基準の表現
  • DSLの役割・ふるまい

(2)アプリケーションドライバレイヤの実装

アプリケーションドライバレイヤの実装の観点は以下の通り。

  • DSLによる、抽象化・エイリアスの使用・再利用
  • シンプルなケースから作成
  • 外部/内部DSLともに長短がある
  • ウィンドウドライバパターンで抽象レイヤを導入し、テストとGUI疎結合にする

(3)受入テストの実装

受入テストの実装の観点は以下の通り。

  • 状態を扱う
    • 最小限のデータ
    • 可能ならアトミック
    • アカウントなどでスコープを分離
    • 状態へのガードと状態の相対的表現
  • テスト用のバックドア(特権アクセス)を作らない
  • 非同期処理を同期的に検証
  • 外部システムへのテストダブルの使用とあわせて、外部システムとのインターフェースを表すインタラクションテストを実施
    • 統合ポイントへの小粒のテストスイートを作成。完全でなくてよく、実行タイミングを分ける。

(4)受入テストステージ

受入テストステージの観点は以下の通り。

  • 受入テストの記録
  • ステージに失敗したときはデプロイ不可
  • 受入テストをグリーンに保つ
  • 受入テスト前にデプロイメントテスト・スモークテストを実施し、受入テストの前提を検証する。このテストが失敗したとき、ステージをすぐに失敗させる。

(5)受入テストのパフォーマンス

受入テストテストのパフォーマンス改善のための観点は以下の通り。

  • テストヘルパークラスを分離
  • 高価なリソースを共有
  • 並列テスト・コンピュートグリッドを使用
  • 受入テストのためのクラウドコンピューティング

5.影響・作用

受入テストによって、デリバリーチームはユーザがシステムに求めるふるまいに集中できる。
自動受入テストをユーザの視点から見たシステムのふるまいを保証するテストとして用いることで、リグレッションによる問題への重大な防御策となる。
受け入れ基準が駆動するテストを採用することで、以下を達成できる。

  • ソフトウェアが目的にかなうことを保証
  • リグレッションへの防御
  • 自動リグレッションテストを包括的に実施し、品質を大幅に改善
  • 欠陥を素早く検出・修正
  • テスターの労力を仕様の開発・探索的テストやユーザテストの実行に移せる
  • サイクルタイムを減少させ、継続的な開発を可能にする

6.おわりに

以上が、継続的デリバリーの中での、自動受入テストについての概観です。

7.参考文献

『継続的デリバリー 信頼できるソフトウェアリリースのためのビルド・テスト・デプロイメントの自動化』 第8章 自動受け入れテスト

『継続的デリバリー』 第7章 学習メモ

コミットステージの概観

1.はじめに

継続的デリバリーにおける、コミットステージについての調査記録です。
継続的デリバリーの中での、コミットステージについての概観を記載します。
『継続的デリバリー 信頼できるソフトウェアリリースのためのビルド・テスト・デプロイメントの自動化』の第7章に対応します。

2.概要・目的

コミットステージの責務は、リリース候補の生成である。
コミットステージは、デプロイメントパイプラインの実装の開始地点である。

3.対応概要

コミットステージの原則とプラクティスは以下の通り。

  • コミットステージでは、早期のフィードバックが重要であり、CIサーバはプレテストコミット(プレフライトビルド)を提供する。
  • コミットステージが失敗したときは、チーム全体で対応する。
  • 疎結合スクリプトが重要である。
  • 開発者がコミットステージを制御する。
  • ビルドマスターが必要となるパターンがある。

コミットステージの出力についての観点は以下の通り。

  • 成果物リポジトリの媒介的責務。
    バージョン管理のリビジョンと紐づける。

コミットテストスイートにおけるユニットテストの観点は以下の通り。

  • 高速かつ広範囲。
  • 検証対象の単一化。

4.対応詳細

コミットテストスイートの原則とプラクティスは以下の通り。

  • UIはテストしない。
  • DIで他のオブジェクトから分離する。他のオブジェクトとの結合を弱める。
  • DBに依存しない。ステートレスなコミットテスト。
    入力と出力の組み合わせを期待結果と比較するという、テストの基本構造で表現できる疎結合なテスト設計とする。
  • 非同期処理を回避する。
  • テストダブルで対象でないオブジェクトをスコープから除外する。
    モックで対象オブジェクトとのやり取りを検証する。スタブは呼ばれ方を表現できない。
  • 時間を抽象化する。
    遅延・待ちの原因となるふるまいをすべてスタブ・モック化する。
  • コミットテストスイートを高速にするための解決策は以下の通り。
    • テストスイートを分割し、並列実行する。
    • CIサーバのビルドグリッド機能を使用する。
    • 失敗しづらく時間がかかるテストを受入後のステージに移す。

5.影響・作用

コミットステージにより、変更によって入り込む欠陥をできるだけ早く検出し、開発者に通知し、問題を素早く修正できるようにすることができる。
CIに含まれるその他のプラクティスと組み合わせることで、デリバリープロセスの品質と信頼性が大幅に向上する。

6.おわりに

以上が、継続的デリバリーの中での、コミットステージについての概観です。

7.参考文献

『継続的デリバリー 信頼できるソフトウェアリリースのためのビルド・テスト・デプロイメントの自動化』 第7章 コミットステージ

『継続的デリバリー』 第6章 学習メモ

ビルド・デプロイメントスクリプトの概観

1.はじめに

継続的デリバリーにおける、ビルド・デプロイメントスクリプトについての調査記録です。
継続的デリバリーの中での、ビルド・デプロイメントスクリプトについての概観を記載します。
『継続的デリバリー 信頼できるソフトウェアリリースのためのビルド・テスト・デプロイメントの自動化』の第6章に対応します。

2.概要・目的

アプリケーションのビルド・テスト・パッケージングのスクリプト化のための最初のステップが、コマンドラインからのビルドの実行である。テストも、有名なフレームワークを使えば比較的簡単に実行できる。これらにより、CIを開始できる。
コンポーネントの増加や、通常と異なるパッケージングの必要から、複雑なビルドスクリプトを作る必要が生じる。さらに、デプロイメントの自動化のためには、より一層複雑になる。
本稿では、これらの複雑なスクリプトを扱うために、ビルド・デプロイメントツールに共通した原則の概要や、必要な情報、テクニック、さらなる参照などを記載する。

3.対応概要

本節では、ビルドスクリプトとデプロイメントスクリプトに関する一般的な原則とプラクティスを紹介する。

(1)ビルドスクリプトの設計

ビルドスクリプト実装しているプロセスを明確に表現したものであることが理想。
スクリプトを適切な構造にし、きれいに保ち、コンポーネント間の依存関係を最小化する。
プロジェクト開始時点は、デプロイメントパイプラインを実行するためのあらゆる処理をひとつのスクリプトにまとめておく。自動化されていないステップにはダミーのターゲットを入れておく。
スクリプトが十分に長くなったとき、パイプラインのステージごとに別々のスクリプトに分ける。
これにより、コミットスクリプトができる。このスクリプトは、アプリケーションをコンパイルし、パッケージングし、コミットテストスイートを実行し、コードの静的解析を行うために必要なターゲットをすべて含む。
次に必要となるものが機能の受入テストスクリプトとなる。デプロイメントツールを呼び出してアプリケーションを適切な環境にデプロイし、必要なデータをすべて準備し、最後に受入テストを実行する。また、ストレステストやセキュリティテストといった非機能のテストを実行するスクリプトもある。
スクリプトはすべて、ソースコードと同じバージョン管理リポジトリに格納する。

(2)デプロイメントツールの使用

デプロイメントを自動化する際には、汎用スクリプティング言語ではなく適切なツールを使用する。
デプロイスクリプトは、アプリケーションをスクラッチからインストールするときと同様に、アップグレードも実施する必要がある。そのため、デプロイする前に実行中のアプリケーションをシャットダウンする必要がある。また、既存のDBを更新することもゼロから作成することもできる必要がある

(3)すべての環境へのデプロイに同じスクリプトを使う

デプロイメントスクリプトから区別した設定情報を、スクリプトから検索できる仕組みを提供する。

(4)OSのパッケージングツールを使用する

ファイルシステムをまたがって分散するファイル一式のデプロイのためOSのパッケージングツールを使用する。
また、バイナリのパッケージングは自動化する。

(5)デプロイメントプロセスの冪等化

デプロイするたびに、すべてクラッチからデプロイする必要がある。 環境設定を宣言的に指定するツールを使用する。

(6)デプロイメントシステムをインクリメンタルに開発する

デプロイメントシステムはインクリメンタルに開発する。

4.対応詳細

(1)ビルドツールの責務

ビルドツールは、依存関係のネットワークをモデル化するという共通のコアを持つ。
タスク指向のビルドツールは、コンパイラがインクリメンタルビルドのためのロジックを持つC#などの言語のコンパイルに向いている。
プロダクト指向のビルドツールは、インクリメンタルビルド機能を持ち、CやC++コンパイルに向いている。

(2)ビルドツールの歴史

ビルドツールの歴史を紐解いた結果として、著者の執筆時点では、以下が洗練されたツールとされている。

  • Buildr
  • Gradle
  • Psake

    (3)プロジェクト構造

    観点は以下の通り。

  • レイアウト

  • ソースコード管理
  • テスト管理
    ビルドスクリプトで別々に実行
  • ビルドの成果物の管理
    ターゲットディレクトリからはバージョン管理にコミットしない。
    ビルドプロセスで、アプリケーション内のコンポーネントの構成を決める。
  • ライブラリの管理

    (4)デプロイメントスクリプトの実装

    独立したプロセスごとにスクリプトが必要。そこからさらに、機能ごとに個別のスクリプトが必要となる。
    観点は以下の通り。

  • リモートマシンへのデプロイ
    デプロイメントツールや基盤管理ツールの使用か、またはエージェントモデルのCIサーバにより、ローカルスクリプトをリモート環境で実行する。あるいは、自前のスクリプトでも可能。

  • デリバリーの核:「各プロセスは前のプロセスの検証を土台とする」

    • デプロイメント前の低次レイヤの検証

      (5)ビルド・デプロイメントの振る舞い

      観点は以下の通り。

  • 相対パス絶対パス

  • 成果物はチェックインせず、メタデータでリビジョンと紐づける
  • バイナリからバージョン管理へのトレーサビリティ
  • 1ビルドに対して1コミットテストスイートを完遂
  • 統合スモークテストでアプリケーションを制限

5.影響・作用

以下の観点でスクリプトの開発を実施することで、ソフトウェアのビルド・テスト・デプロイ・リリースの自動化のための仕組みを構築できる。

  • デプロイメントパイプラインはイテレーティブかつインクリメンタルに開発する。
  • スクリプトをバージョン管理し、デプロイメントの唯一の手段とする。

6.おわりに

以上が、継続的デリバリーの中での、ビルド・デプロイメントスクリプトについての概観です。

7.参考文献

『継続的デリバリー 信頼できるソフトウェアリリースのためのビルド・テスト・デプロイメントの自動化』 第6章 ビルド・デプロイメントスクリプト

『継続的デリバリー』 第5章 学習メモ

デプロイメントパイプラインを解剖する

1.はじめに

継続的デリバリーにおける、デプロイメントパイプラインについての調査記録です。
継続的デリバリーの中での、デプロイメントパイプラインの責務や構成について記載します。
『継続的デリバリー 信頼できるソフトウェアリリースのためのビルド・テスト・デプロイメントの自動化』の第5章に対応します。

2.概要・目的

デプロイメントパイプラインでは、まず、CIでシステムをコントロールする。
また、デプロイメントプロセスを自動化することで、アクセスの容易さとフィードバックの高速化を実現し、速さと安全さを提供する。
ビルド・デプロイ・テスト・リリースプロセスを自動化することで、最終的にプルシステムが構築でき、デプロイメントパイプラインは自由と柔軟性をもたらす

3.対応概要

(1)デプロイメントパイプラインによるプロセスのモデル化

デプロイメントパイプラインとは、ソフトウェアをバージョン管理から取り出してユーザに手渡すまでのプロセスを自動化して表現したものである。
コンセプトから対価の獲得までのプロセス全体は、バリューストリームマップとしてモデル化できる。
継続的デリバリーでは、バリューストリームのうちの、開発からリリースまでの間を扱う。
バージョン管理における特定のリビジョンが、パイプラインに対するインプットとなる。
デプロイメントパイプラインのパターンを適用することで、以下の恩恵を得られる

  • ビルドを徹底的にテストすることで、不適切なビルドを本番にリリースしてしまうことを効率的に避けられる。また、リグレッションバグを避けられる
  • デプロイメントと本番リリースの自動化により、素早く、反復可能で信頼できるプロセスとなる。
    以前のバージョンに戻すことも容易になり、リリースのリスクがなくなる

デプロイメントパイプラインを実現するための、あらゆるプロジェクトに共通したサブセットは以下の通りとなる。

  • コミットステージ
    • 技術レベルの検証。
  • 自動受入テストステージ
    • 機能および非機能レベルの検証。
  • 手動テストステージ
    • ユーザ視点の価値の検証。
  • リリースステージ
    • システムをユーザにデリバリーする。

これらのステージと、その他のソフトウェアデリバリープロセスをモデル化するために必要なステージを合わせて、デプロイメントパイプラインと呼ぶ。

(2)基本的なデプロイメントパイプライン

参考文献の図5-4に基本的なデプロイメントパイプラインの構成図が載っている。
構成のポイントは以下の通り。

  • バージョンコントロールと成果物リポジトリは、パイプラインのすべてのステージと関係する。
    受入ステージ以降に対しては、バージョンコントロールは環境とアプリの設定を提供する。
  • コミットステージと受入ステージの完了後は、UAT・キャパシティ・本番の各ステージに枝分かれする。
    また、受入ステージの完了後は、デプロイメントのための自動スクリプトを使用し、手作業でデプロイする。

さらに、特定のチェックインとビルドを、パイプライン上で通過したステージに関連付けて可視化することも重要である。

4.対応詳細

(1)デプロイメントパイプラインのプラクティス

デプロイメントパイプラインのプラクティスとして、以下が挙げられる。

  • バイナリのビルドは1回限りとし、ファイルシステムやCIサーバで管理する。
  • バイナリを環境に対して疎結合にする。もろくコストの高いプロセスにしないため。
  • あらゆる環境に対して同じやり方でデプロイする。
    デプロイメントスクリプトは各環境で同じものを使い、各環境ごとに一意の設定は別々のプロパティファイルとし、バージョン管理に格納する。
  • 環境に依存しないプロセスとすることで、デプロイの失敗の原因を限定できる。
  • デプロイメントのスモークテストは、最優先のユニットテストスイートの次に優先するテストとする。
    アプリケーションが依存するすべてのサービスに煙を流す。
  • 本番のコピーにデプロイする。
    環境が同一であることを示すために、以下を確認する必要がある。
    • ネットワークトポロジーファイアウォール設定といった基盤が同一である。
    • パッチを含めてOSの設定が同じである。
    • アプリケーションスタックが同じである。
    • アプリケーションのデータが既知の妥当な状態である。
  • 各変更が直ちにパイプライン全体を通り抜けるよう、スケジューリングを行う。
    受入テストが完了して初めて、CIは新しい変更を取得できる。

(2)コミットステージ

ユニットテスト + コミットテスト用選抜テスト = コミットテストスイート」となる。
実行可能なコードの生成自体を成功基準として扱うことで、CIによりビルドプロセス自体を評価できる。
コミットステージが問題の大半を検出し、きわめて素早く実行できる必要がある。
これにより、後に続くテストステージが通ることを推測し、デプロイメントパイプラインの実行と並行して、新しいフィーチャの開発ができる。

(3)自動受入テスト

機能の受入 + リグレッション = 受入テスト」となる。
受入テストのプラクティスとして、以下が挙げられる。

  • 各環境ごとに並列に受入テストを実行。
  • UIに疎結合な受入テストとする。
  • ドメイン駆動、ユビキタス言語でのテストの表現
    →拡張性・保守性を付与する。
  • 開発環境での自動受入テストの実行を可能にする。

(4)後に続くステージ

デプロイメントパイプラインにより、テスターがあらゆるビルドをテスト環境に好きなようにデプロイできる。
手動テストでは、自動テストでうまくできないテストに集中する。
非機能のテストの結果に対する評価は人間が判断してもよい。

(5)リリースに備える

デプロイメントパイプラインが以下を達成することで、リリースの問題を緩和する。

  • デリバリーにかかわるすべての人がリリース計画を作成し、保守する。
  • 最もエラーの起こりやすいステージからプロセスを自動化し、ヒューマンエラーの影響を最小化。
  • 疑似本番環境で行われるプロセスを繰り返すことで、プロセスやそのための技術をデバッグできる。
  • 計画通りいかなかったときにバックアウトを可能にする。
  • 設定と本番データを移行する戦略を、アップグレードとロールバックプロセスの一部とする。

リリースプロセスの完全な自動化が目標となる。

a.デプロイメントとリリースの自動化

本番環境の変更は、自動化されたプロセスを通じてのみ行われるべき。
これにより、信頼できる監査、問題の診断、修正にかかる時間の予期が可能となる。
また、本番環境を管理するプロセスは、ステージング環境やインテグレーションテスト環境といったその他の環境でも使う
キャパシティテストのフィードバックにより、設定の変更を評価する。
環境のプロビジョニングと保守を自動化するコストは、自動プロビジョニングや環境の管理、適切な構成管理プラクティス、仮想化により大幅に低減できる。
リリースプロセスは、継続的に評価され、改善される必要がある。

b.変更のバックアウト

最善のバックアウト戦略は、アプリケーションの1つ前のバージョンをリリースの間も使えるようにしておくこと。
次善の戦略は、以前の適切なバージョンを1から再デプロイすること。

(6)デプロイメントパイプラインの実装

デプロイメントパイプラインを実装するためのステップは以下の通り。

  • バリューストリームをモデル化して、動くスケルトンを作成
  • ビルドとデプロイプロセスを自動化
  • ユニットテストとコード解析を自動化
  • 受入テストを自動化
  • リリースを自動化

ビルドとデプロイメントの自動化の要点は以下の通り。

  • バイナリが開発ツールに依存しない
  • CIサーバの設定
  • デプロイメント先環境の用意
  • 自動デプロイメントのテスト
  • バイナリと設定の分離

コミットステージが5分を超えたら、いくつかのスイートに分割する。

パイプラインは以下のために拡張されうる。

パイプラインの実装のために、以下の3つのプラクティスがある。

  • バイプラインはインクリメンタルに実装する。
  • パイプラインの実装では、プロセスの開始時刻と終了時刻、またどの変更がプロセスの各ステージを通過したかを記録する。これにより、プロセスのボトルネックを特定できる。
  • パイプラインのリファクタリングを実施する。

(7)メトリクス

ソフトウェアデリバリープロセスにとっての最も重要なメトリクスは、サイクルタイム
サイクルタイムの短縮のために、以下のプロセスに従うことで、制約理論を適用できる。

  • システムにとっての制約条件を特定。制約条件とはボトルネックのこと。
  • ボトルネックの箇所のスループットを最大化。
  • 他のプロセスをすべて制約に従属させる。
  • 制約の限界を上げる。リソースを増やす。
  • 繰り返す。

その他のメトリクスは以下の通り。

  • 自動テストのカバレッジ
  • コードベースの特徴
  • 欠陥の数
  • 速度
  • 1日当たりのバージョン管理システムへのコミット数
  • 1日当たりのビルド回数
  • 1日当たりのビルド失敗回数
  • 自動テストを含むビルドにかかる時間

5.影響・作用

デプロイメントパイプラインの目的は、デリバリーにかかわるすべての人にとって、チェックインからリリースまでのビルドの進展の可視化にある。
また、ボタン1つで手動テスト環境にデプロイでき、環境にどのリリース候補があるのかわかるようになる。
デプロイメントパイプラインを実装することで、リリースプロセスの非効率な部分を特定できる。
さらに、プロセスを分析するための情報を得られる。

6.おわりに

以上が、継続的デリバリーの中での、デプロイメントパイプラインの責務や構成です。

7.参考文献

『継続的デリバリー 信頼できるソフトウェアリリースのためのビルド・テスト・デプロイメントの自動化』 第5章 デプロイメントパイプラインの解剖学

『継続的デリバリー』 第4章 学習メモ

テスト戦略

1.はじめに

継続的デリバリーにおける、テスト戦略についての調査記録です。
継続的デリバリーの中での、テスト戦略の実装方法について記載します。
『継続的デリバリー 信頼できるソフトウェアリリースのためのビルド・テスト・デプロイメントの自動化』の第4章に対応します。
メモ:以下、文中はである調になります。

2.概要・目的

(1)概要

W・エドワード・デミングが挙げた14のポイントのうちの一つに、「高品質を実現するために、大人数での調査に頼るのをやめよ。まずはプロセスを改善し、本番の品質を作りこめ」とある。
テストは職務横断的な活動であり、チーム全体を巻き込む。
品質を作りこむために、自動テストを様々な抽象度(ユニットテストコンポーネントテスト・受入テスト)で書く必要がある。
デプロイメントパイプラインの一部としてこれらのテストを実行し、さらに、あらゆる変更に対してデプロイメントパイプラインをトリガーする。
この自動テストに加えて、品質を作りこむために、手動テストも実施する。
ショーケース・ユーザビリティテスト・探索的テストを、プロジェクトを通じて継続的に実施する。

(2)目的

テスト戦略の設計は、第一に、プロジェクトのリスクを識別して優先順位をつけ、そのリスクを緩和するためのアクションを決定するプロセスである。
さらに、優れたテスト戦略によって、以下のような作用が生じる。

  • テストによって、ソフトウェアが期待通りに動いていることを保証できる。バグ・サポートのコストを減らし、製品に対するユーザの評価を高められる。
  • テストをすることで開発プロセスに制約を課し、優れた開発プラクティスを促進する。
  • 包括的な自動テストスイートが、アプリケーションに関する最も完全で最新化された形式のドキュメントとなる。実行可能な仕様のかたちを取り、システムがどう動くべきか、実際にどう動くかを表す

3.対応概要

(1)テストの種類

f:id:sh0623k:20210108123741p:plain

テストは上記の画像のように分類できる。
y軸は価値を表し、x軸はフィードバック先を表す。

(2)第2象限のテスト

この区画には機能の受入テストがある。
受入テストは、ストーリーに対する受け入れ基準が満たされていることを保証するテスト。
受入テストによって、開発者の完了条件と、ユーザの要件を表現する。

(3)受入テストの自動化

受入テストの自動化の作用は、以下の通り

  • フィードバックループの加速
  • テスターが、探索的テストやもっと価値の高い活動に集中できるようになる
  • 受入テストが強力なリグレッションテストスイートとなる
  • テストから要件ドキュメントを自動生成でき、要件ドキュメントが陳腐化しない

自動受入テストは、通常、正常パス的なふるまいを完全に網羅するのみとする。
このとき、ほかの種類の自動リグレッションテストは包括的なものが一式揃っている必要がある。
優先して自動化すべきテストが、主要な正常パスに対するテストである。
代替正常パスと異常パスの優先度は、アプリケーションの安定性に依存する。

(4)第3象限のテスト

第3象限のテストは、ユニットテストコンポーネントテスト、デプロイメントテストである。
ユニットテストは、システムのコンポーネント間でやりとりしないテスト。
この制約により、ユニットテストは非常に高速に実行でき、素早いフィードバックを実現する。
コンポーネントテストでは、アプリケーションの様々な構成要素間のやりとりで発生する問題を検出する。
デプロイメントテストは、アプリケーションをデプロイする際に必ず実施する。
アプリケーションが正しくインストールされ、正しく設定され、必要なサービスと接続できて、レスポンスが戻ってくることを確認する。

(5)第1象限のテスト

第1象限のテストでは、期待されている価値をアプリケーションがユーザに対してデリバリーしていることを検証する。
カナリアリリースなどの発展的なアプローチによって、効果の高い機能を採用することができる。

(6)第4象限のテスト

非機能テストでは、機能以外のシステムの品質をすべてテストする。
システム全体にフィードバックするテストであり、機能要件と同じ検証方法を用いる。
非機能のテストのためのツールを使用することで、非機能の問題を早期検出できるプロセスを構築する。

(7)テストダブル

テストダブルとは、テスト対象の検証のためのシミュレーション用部品である。 例として、モックやダミーがある。 モックはコラボレーターとのやり取りをアサートし、コードの動作に関する詳細はアサートしない。

4.対応詳細

(1)起こりうる状況と戦略

a.新規プロジェクト

新規プロジェクトにおいては、受け入れ基準をドメインの観点で表現することが重要である。
これにより、保守性の高いテストスイートを作成できる。

b.プロジェクトの途中

プロジェクトの途中においては、ドメインの核となるユースケースリグレッションから守る、正常パステストを優先して自動化する必要がある。
さらに、変更のないテストについても、自動化を進める。
シンプルなスクリプトと多様なデータによって、アプリケーションの状態を多く表現する。

c.レガシーシステム

レガシーシステムでは、まず自動ビルドを構築する。
次に、リグレッションテストスイートを作成する。
その後、自動テストをレイヤ化するアプローチを取る。
自動テストは、リグレッションから守るという目的に対して、価値がある。
あるいは、数多くの別々の環境でソフトウェアを実行する必要がある場合も、価値が生まれる。

d.インテグレーションテスト

インテグレーションテストでは、アプリケーションの各部分が、依存サービスと連携できることを保証する。
テストダブルの構築では、正常系と異常系をそれぞれシミュレートする必要がある。
外部サービスとの統合の問題として、以下が挙げられる。

  • 使えるテストサービスがあるか。性能は十分か。
  • サービスプロバイダは、質問に答えたりバグフィックスをしたりカスタマイズ機能を追加したりしてくれるか。
  • システムの本番バージョンにアクセスして、キャパシティや可用性の問題を診断するためにテストすることができるか。
  • サービスAPIはアプリケーション開発に使っている技術を用いて簡単にアクセスできるか。あるいはチーム内に専門スキルを持つ人が必要か。
  • 自分たちで使うテストサービスを書いたり保守したりする必要があるか。
  • 外部サービスが期待通りふるまってくれなかった場合に、自分たちのアプリケーションはどう動くべきか。

(2)受入テストの作成プロセスの最適化

受入テストや受入テストの目的を簡潔に書くことで、開発者はストーリーの概要を適切にとらえ、最も重要なシナリオを理解できる。
テスターと開発者が早いうちから協力関係を築くことで、開発者とテスター間のフィードバックサイクルの量を減らすことができ、機能の漏れやバグの数も削減できる。

(3)欠陥バックログの管理

バグのバックログがあるとき、問題が誰にでもはっきりとわかるようになっていること、また、開発チームのメンバが責任をもってバックログを減らすためのプロセスを推進することが重要である。
あるいは、欠陥をフィーチャと同様に扱うというアプローチを取る。

5.影響、作用

テストによるフィードバックループを構築することで、各プロセスの「完了」を表現できる。
これにより、プロジェクトの前進性を保証することができる。

6.おわりに

以上が、継続的デリバリーの中での、テスト戦略の実装方法です。

7.参考文献

『継続的デリバリー 信頼できるソフトウェアリリースのためのビルド・テスト・デプロイメントの自動化』 第4章 テスト戦略を実装する