より良いエンジニアを目指して

1日1つ。良くなる!上手くなる!

JSTQB学習〜第2回ソフトウェア開発ライフサイクル全体を通してのテスト

ソフトウェア開発ライフサイクルモデル

テストは単独では存在せず、テストの対象を作り上げていく開発の一部になります。

テストの対象となるソフトウェアがどのようなプロセスで作られるか、テストの位置付けを知っておきましょう、という流れです。

業務だけ頑張っていては、自分の担当しか考えないので、こういう俯瞰的な視点というのは重要ですね。

ソフトウェア開発とソフトウェアテスト

テスト成功のための鉄則と言えることがあります。

  • 各開発活動に対応してテスト活動がある
  • 各テストレベルには、そのレベル特有の目的がある
  • テストレベルのテスト分析や設計は、対応する開発活動の間に開始する
  • テスト担当は要件と設計を定義および洗練する討議に参加し、作業成果物(要件、設計、ユーザーストーリーなど)のドラフトができたらすぐにそのレビューをする

シーケンシャル開発モデル

ウォーターフォール=V字モデルと思ってたのですが、ウォーターフォールの上流と下流を対応づけて、アルファベットのVの字で表したものをV字モデルと呼ぶようです。

ここにも記載されてますが、ウォーターフォールは手戻りが発生して、結局、破綻して、シーケンシャル(順序的)に実施できないのが現状です。

そもそもこれが実装できるのかわからないので、ウォーターフォールと宣言しておきながら、先に実装してから設計書を書くみたいな、逆ウォーターフォールみたいなこともしたことがあります。

Wモデルとシフトレフト

テスト活動の一部が上流工程と並行して行われることを明確化したのがWモデル。

要求分析に対して、受け入れテスト計画・設計をしてしまうといった形です。

こうした形でテストを開発の早い段階で行うのをシフトレフトと言います。

シフトレフトという言葉は初耳でした。

www.qbook.jp

イテレーティブ開発モデルとインクリメンタル開発モデル

ここで一つの区切りにしているのは実際には併せて使われることが多いからです。

インクリメンタル開発モデルは、フィーチャー(機能)を少しずつ増やしていく開発です。

イテレーティブ開発モデルは、仕様化、設計、構築、テストというサイクルを何度も繰り返すもの。

イテレーティブ開発モデルはいくつかの種類があり、以下の4つが紹介されています。

  • ラショナル統一プロセス
  • スクラム
  • カンバン
  • スパイラル(プロトタイピング)

ラショナル統一プロセスはIBMが提唱した手法です。2-3ヶ月の期間となっています。今のIBMはソフトウェア開発のリーダーとは言い難いので以下略。

スクラムは、よく聞きますが、結局どれくらいかかるのかなんて、何人で考えてもわからない気がしています。で、カンバンに落ち着くのではないか、と。

といっても、タスクによっては、要件が曖昧であるため、プロトタイピングしてから操作感を見てから仕様を決めてしまうと使い分けたりもします。

状況に応じたソフトウェア開発ライフサイクルモデル

どのソフトウェア開発ライフサイクルや開発モデルを選ぶべきかは、次の点を考慮する必要があります。

  • プロジェクトのゴール
  • 開発するプロダクトの種類
  • ビジネス上の優先度
  • 識別したプロダクトリスク
  • 識別したプロジェクトリスク

バックエンドはシーケンシャル開発モデル、フロントエンドはイテレーティブ開発モデルとインクリメンタル開発モデルといったように一つのプロジェクトの中でも、開発対象によって分けることがあります。

だそうですが、そういうのは、ぼくの経験としてはありませんね。

テストレベル

テストを、コンポーネント単位、システム全体といった形でレベルを分けてテストします。

シラバスでは次の4つについて解説しています。

ちなみに、テストレベルは必ずしも従う必要はなく、いくつかのテストレベルと組み合わせたりします。

ぼくの経験としては、そこまで細かいわけをせず、統合テストだけで済ませている感じでしたね。

大規模なシステムの場合は二桁のテストレベルを定義することもあるそうです。

テストレベルの属性

本書は、テストレベルそれぞれの特徴を理解するために、次の属性を整理して、確認していきます。

  • テスト目的
  • テストベース(テストケースを導くために参照する開発成果物)
  • テスト対象
  • テストタイプ
  • テストで見つかる典型的な欠陥と故障
  • テスト実行者(責務の割り当て)
  • 固有のアプローチ

と多いですが、各テストレベルにこれらをきちんと把握していないと問題は解けないのです。

ただ、確実にここは重いので、テストを合格を目指すにしては完璧に覚えることよりもさらっと流して捨てるのも手かな、と思いました。

それでもテストレベルの属性の概念は覚えておいて損はないです。というか、JSTQBを勉強して、初めて知りました。

コンポーネントテスト

ドライバやシミュレーターなどを用いて、システムの他の部分と切り離して行うテストです。

ぼくの経験としては二つのWebサービスが連動するようなシステムがあり、片方を担当した時、呼び出すWebサービスが出来上がる前にテストするときはモックを用意して意図したレスポンスを返すテストサービスを作ってテストしてました。

このテストは開発担当者がするものとしています。

  • テスト目的

    • テスト対象に内在する欠陥を検出するため
    • テスト対象の機能的振る舞いが設計および仕様通りであることを検証するため
    • テスト対象の非機能的振る舞いが設計及び仕様通りであることを検証するため
    • テスト対象の品質が信頼できるものであることを確認するため(信頼の積み上げ)
    • コンポーネントテストで検出すべき欠陥が見逃されることを防止するため
    • リスクを軽減するため
  • テストベース

  • テスト対象

    • コンポーネント、ユニット、またはモジュール
    • コードとデータ構造
    • クラス
    • データベースモジュール
  • テストタイプ

  • テストで見つかる典型的な欠陥と故障

    • 正しくない機能(例えば、設計仕様の記述とは異なる)
    • データフローの問題
    • 正しくないコードとロジック

シラバスには書いていないが、コンポーネントテストで性能測定をして、性能欠陥としてみなすことがあるとあります。

テストタイプとしてはコンポーネントテストでも非機能テストもするとしていますし。

確かに、実行可能であればコンポーネントテストで性能測定しておいた方が良いでしょうね。

これは、要はTDD、テスト駆動開発のことが言いたいんでしょう。

統合テスト

大きく分けてコンポーネント統合テストとシステム統合テストの2種類のテストがあります。

コンポーネント統合テストは、コンポーネント間のインターフェース及び相互処理を重点的にテストします。

先ほどの二つのサービスの例だと、二つのサービス間で意図した連携ができるか試すことになるでしょう。

二つだといいのですが、これが4つとか6つとかWebサービスがあって一度に通しでテストすると、どこで何が問題があるかわからないので、問題が切り分けられるように段階的に統合してテストしていくのです。

システム統合テストは、システムテストの後またはシステムテスト実行中に実施するテスト。

他システムとの相互処理を重点的にテストします。

受注処理システムがシステムテスト対象だった場合、受注処理システム、出荷処理システムを統合し、販売管理のビジネスプロセスとしてテストすることになります。

  • テスト目的
    • テスト対象に内在する欠陥、インターフェースに内在する欠陥を検出するため
    • インターフェースの機能的振る舞いが設計及び仕様通りであることを検証するため
    • インターフェースの非機能的振る舞いが設計及び仕様通りであることを検証するため
    • インターフェースの品質が信頼できるものであることを確認するため(信頼の積み上げ)
    • 統合テストで検出すべき欠陥が見逃されることを防止するため
    • リスクを軽減するため
  • テストベース
  • テスト対象
  • テストタイプ
  • テストで見つかる典型的な欠陥と故障
    • コンポーネント統合テスト
      • 正しくないデータ、データ不足、正しくないデータエンコーディング
      • インターフェース呼び出しの正しくない順序またはタイミング
      • インターフェースの不整合
      • コンポーネント間のコミュニケーションの故障
      • コンポーネント間のコミュニケーション故障の処理不在、または不適切な処理
      • コンポーネント間で渡されるデータの意味、単位、境界の正しくない思い込み
    • システム統合テスト
      • システム間で一貫性のないメッセージ構造
      • 正しくないデータ、データ不足、正しくないデータコーディング
      • インターフェースの不整合
      • システム間の通信の故障
      • システム間の通信故障の処理不在、または不適切な処理による故障
      • システム間で渡されるデータの意味、単位、境界の正しくない思い込み
      • 必須のセキュリティ規制への非準拠
  • テスト実行者
    • コンポーネント統合テストは主に開発担当者
    • システム統合テストは主にテスト担当者
  • 固有のアプローチ
    • 開発前に統合戦略と統合テスト計画を立てることができると、ソフトウェアアーキテクチャーやシステムアーキテクチャーを踏まえてテスト計画を考慮することができるため、テスト効率が最大になるように開発を進めることができる

システムテスト

システムやソフトウェアプロダクト全体の機能性と非機能性の両方について確認するために、システムが実行するエンドツーエンド全体の振る舞いや能力をテストします。

  • テスト目的
    • テスト対象に内在する欠陥を検出するため
    • テスト対象の機能的振る舞いが設計および仕様通りであることを検証するため
    • テスト対象の非機能的振る舞いが設計および仕様通りであることを検証するため
    • システムが完成し、期待通りに動作することの妥当性確認するため
    • システムが法的または規制的要件、または標準を満たすことを確認するため
    • システム全体の品質が信頼できるものであることを確認するため(信頼の積み上げ)
    • システムテストで検出すべき欠陥が見逃されることを防止するため
    • データ品質を検証するため
    • リスクを軽減するため
  • テストベース
    • 機能要求および非機能要求が書かれたシステム要求仕様(書)
    • 機能要求および非機能要求が書かれたソフトウェア要求仕様(書)
    • ユースケース(仕様書)
    • エピックおよびユーザーストーリー
    • システム振る舞いのモデル
    • 状態遷移図
    • システムマニュアルおよびユーザーマニュアル
    • リスク分析レポート(リスクベースドテストを採用している場合)
  • テスト対象
    • アプリケーション
    • ハードウェア/ソフトウェアシステム
    • オペレーティングシステム
    • テスト対象システム(SUT)
    • システム構成および構成データ
  • テストタイプ
    • 機能手数と、非機能テスト、ホワイトボックス、リグレッションテストを含む
  • テストで見つかる典型的な欠陥と故障
    • 正しくない計算
    • 正しくない、または期待通りではないシステムの機能的または非機能的振る舞い
    • システム内の正しくない制御フローおよび/またはデータフロー
    • エンドツーエンドの機能的タスクを適切かつ完全に実行できない
    • 本番環境でシステムが適切に動作しない
    • システムマニュアルおよびユーザーマニュアルに記載されている通りにシステムが動作しない
  • テスト実行者
    • テスト担当者が実行することもあれば、独立したテストチームがシステムテストを請け負うこともある
  • 固有のアプローチ

リスクベースドテストって何?と思いました。

モジュールに対して、リスクを洗い出し、分析した上で、優先順位を決める手法のようです。

ranorex.techmatrix.jp

受け入れテスト

受け入れテストもシステムやソフトウェアプロダクト全体の機能性と非機能性の両方について評価します。

システムテストと同じじゃんと思ったのですが調べてみると

受け入れテストは基本的に発注側が行うのに対し、システムテストを行うのは開発側です。 受け入れテストの目的は飽くまで「要求通りに開発されているかのチェック」であって、不具合を見つけることではありません。また、ソフトウェアに求められる要件を満たしているか確認する、開発側のシステムテストとも異なります。

だそうです。

blog.aiqveone.co.jp

請負に依頼したソフトウェアがテストするときに受け入れテストと称して、テストすることはありましたね。

これは受け入れテストの中の契約による受け入れテストです。

  • ユーザー受け入れテスト
  • 運用受け入れテスト
  • 契約による受け入れテスト
  • 規制による受け入れテスト
  • アルファテスト
  • ベータテスト

運用受け入れテストは、実際にバックアップやリストアのテストと聞くとピンときます。

それだけではなく、インストール、アンインストール、アップグレード、性能テストも含まれます。

アルファとベータの違いとしては、テストするのはどちらも開発組織外の担当ですが、アルファは開発担当者のテスト環境、ベータは外部のサイトと環境の違いがあります。

  • テスト目的
    • システムの機能的振る舞いが仕様通りであることを検証するため
    • システムの非機能的振る舞いが仕様通りであることを検証するため
    • システムが完成し、期待通りに動作することの妥当性確認をするため
    • システム全体の品質が信頼できるものであることを確認するため
    • (ユーザー受け入れテストの目的)
      • システムがユーザーニーズに合致していることを確認するため
      • システムが機能要件を満たしていることを確認するため
      • システムが非機能要件を満たしていることを確認するため
      • システムが最小限の困難さ、コスト、リスクでビジネスプロセスを実行できる品質であるという確信を得るため(信頼の積み上げ)
    • (運用受け入れテストの目的)
      • 例外的な、または困難な状況になった運用環境であっても、システムを適切な稼働状態に維持できるという信頼を積み上げるため
    • (契約による受け入れテストの目的)
      • 契約に準拠しているという信頼を積み上げるため
    • (規制による受け入れテストの目的)
      • 規制に準拠しているという信頼を積み上げるため
    • (アルファテストおよびベータテストの目的)
      • 日常的な状況の運用環境である時、顧客またはシステム運用者の目的を達成できるという信頼を積み上げるため
      • システムが使用される状況や環境において、テスト対象に内在する欠陥を検出するため
  • テストベース
    • ビジネスプロセス
    • ユーザー要件(定義書)
    • ビジネス要件(定義書)
    • システム要件(定義書)
    • 規制、法的契約、標準
    • ユースケース(仕様書)
    • システムドキュメント
    • ユーザードキュメント
    • インストール手順
    • リスク分析レポート(リスクベースどテストを採用している場合)
    • (運用受け入れテストで使用できるテストベース)
      • バックアップ/リストア手順(書)
      • 災害復旧手順(書)
      • 非機能要件(定義書)
      • 運用ドキュメント
      • デプロイメント指示書およびインストール
      • 性能目標
      • データベースパッケージ
      • セキュリティ標準または規制
  • テスト対象
    • テスト対象システム
    • システム構成および構成データ
    • 完全に統合されたシステムのビジネスプロセス
    • リカバリーシステムおよびホットサイト
    • 運用プロセスおよびメンテナンスプロセス書式
    • レポート
    • 既存または変換された運用データ
  • テストで見つかる典型的な欠陥と故障
    • システムのワークフローがビジネス要件またはユーザー要件を満たさない
    • ビジネスルールが正しく実装されていない
    • システムが契約要件または規制要件を満たさない
    • セキュリティの脆弱性、高負荷時の不適切な性能効率、サポート対象プラットフォームでの不適切な操作などの非機能特性の故障
  • テスト実行者
    • (ユーザー受け入れテスト)
      • 顧客
      • ビジネスユーザー
    • (運用受け入れテスト)
    • (契約による受け入れテスト)
      • ユーザー
      • 独立したテスト担当者
    • (規制による受け入れテスト)
      • ユーザー
      • 独立したテスト担当者
      • 規制機関(テスト結果を証明または監査する場合)
    • (アルファテスト)
      • 潜在的な顧客
      • 既存の顧客
      • システム運用者
      • 独立したテストチーム
    • (ベータテスト
      • 潜在的な顧客
      • 既存の顧客
      • システム運用者
  • 固有のアプローチ
    • 顧客が使用できるかどうかを評価し、リリースの判定を行う場合がある
    • 最後のテストレベルで行うことが多いが、次のタイミングで行うこともある。
      • 市販ソフトウェアプロダクトは、インストール時や開発しているソフトウェアとの統合時点で受け入れテストを実施する
      • 新機能の拡張部分の開発をシステム開発会社へ委託している場合、システムテスト前に拡張部分の受け入れテストを実施する。

受け入れテストはさまざまな形態があるので、ライフサイクルの最後とは限りません。

まあ、ベータテストとかそうですね。

格闘ゲームベータテストは、将来的に購入するユーザーがプレイしてます。

そこでトーナメントに参加するはずが、カジュアルマッチでマッチングしたとか、そもそもトーナメントが正しく運営されなかったみたいな不具合を動画で見たことあります。

その結果を踏まえて、不具合修正、さらにテストを行い、リリース、という流れになりますからね。

テストタイプ

目的に応じて、実施するテストタイプは異なります。

機能テスト

テスト対象が「何をするのか(what)」をテストします。

仕様通りに実装されているかどうか評価することを目的とします。

テストベースは以下 - 要求仕様書 - ユースケース(仕様書) - 機能仕様書 - エピック(開発規模が大きくなると想定できるユーザーストーリー) - ユーザーストーリー

ドキュメントはいつでも書かれているわけではなく、その場合は、ステークホルダーヒアリング、テスト担当者の見解に基づいてテストします。

という件は、そうだよねーと。ドキュメントが揃ってるわけないものね、と。

テスト対象はシステム、コンポーネントを統合したサブシステム、コンポーネントなどさまざま。

テストレベルもコンポーネントレベル、システムテストレベルとさまざま。

ブラックボックステスト技法に分類されるテスト技法を使うことができます。

同値分割法、境界値分析、デシジョンテーブルテスト、状態遷移テスト、ユースケーステストなど。

テストカバレッジは、機能の網羅性すなわち機能カバレッジで測定できます。

機能テストは、テストベースであるドキュメントを用いるだけでは、設計・実行ができず、次のようなスキルや知識が必要な場合があります。

  • ソフトウェアが解決する特定のビジネス問題
  • ソフトウェアが果たす役割

業務システムだと、このあたりのソフトウェアが解決したい問題、業務知識がついてまわる問題です。

これをどうキャッチアップするのかが課題で、会社が決まった時間を取ってやることが少ないため、よきにはからえとなりがちです。

かといって、勉強会を開催しても、内容が薄く、効果が薄かったりします

非機能テスト

テスト対象が「どのように動作するのか」をテストします。

コンポーネントやシステムの特性、性能、使用性やセキュリティの特性を評価するのが非機能テストの目的です。

テストベースは計測可能な項目と評価可能な値などを定義したドキュメントが非機能テストのテストベースになります。

システム/ソフトウェア品質特性の分類に合わせて記述されることがあります。

実際、それで記述したことがありますが、形骸化していますね。されることがある、なので形骸化するのであればやめるべきなんですよね。

テストタイプは性能テスト、ロードテスト、ストレステスト、ユーザビリティテスト、相互運用性テスト、保守性テスト、信頼性テスト、移植性テストなど。

テストレベルは、システムテスト、受け入れテストで実施するものと思われがちですが、コンポーネントテスト、統合テストレベルでも実施できます。

テスト技法はブラックボックステスト技法に分類されるテスト技法を使うことができます。

テストカバレッジは、非機能要素の種類の網羅性で測定できます。デバイスの互換性であれば、定義した全デバイスのうち、互換性テストで実施したデバイスの割合で表せます。

以前、Webアプリケーションのテストで、実際に、さまざまなメーカーのスマートフォンを用意してテストしてました。もちろん、全てのスマートフォンは用意できないのである程度絞ってましたね。

全網羅は無理ですから。

以下が必要な場合があります - 設計や技術に特有の弱点 - 特定のユーザーの知識

ホワイトボックステスト

システムの内部構造や実装に基づいてテストケースを抽出するテストです。

テストベースは内部構造を理解するには以下

構造を視覚化したドキュメントには次のようなものがあります

これら全てを取り揃えて、完全網羅するのは今の複雑かつスピーディーな開発の現代では厳しいかなあと感じます。

テストレベルは、コンポーネントテストレベル、統合テストレベルだけでなく、システムテストレベル、受け入れテストレベルにおいても実施できます。

テスト技法は、実行した結果、ソフトウェアの構造の何パーセントをカバーしたかを検証します。

テストカバレッジは、構造要素の種類の網羅性すなわち構造カバレッジで測定できます。

コンポーネントテストレベルの例では、コードカバレッジを用います。

コンポーネント統合テストレベルの例では、構造要素としてコンポーネント間のインターフェースを設定し、テスト済インターフェースの割合に基づき、どの程度網羅したかを評価します。

次に示すような特別なスキルや知識が必要な場合があります。

  • コードのビルド方法
  • データの格納法
  • カバレッジツールの使用方法や結果を正しく解釈する方法

どれも、そこまで必要になったことはないかなと思ったのですが、ビルドはできて当たり前ですし、データの格納法はフォルダ構成とかわからないとテストできないですからね。

変更部分のテスト

テストを実行し欠陥を見つけた場合、欠陥を修正した後で実行済みのテストを再度テストしなくてはいけません。

機能の新規追加や変更を行なったりしてシステムを変更した場合も同様に実行済みのテストを再度テストします。

変更部分のテストを実施する理由を次に示します。

  • 元の欠陥が修正されたことを確認するため
  • 機能が正しく実装されていることを確認するため
  • 予測しなかったら悪い影響が発生していないことを確認するため

以下の2種類があります。

  • 確認テスト ... 欠陥部分が正しく修正されているかどうか確認するテスト
  • リグレッションテスト ... 新たに作り込んだ欠陥がないこと、および意図せず他へ影響していないことを確認するテスト

テストレベルは全てのテストレベルで実行できます。

テストタイプとテストレベル

というわけで、全てのテストタイプは、全てのテストレベルで適用できます。

常に適用する必要はありません。

わかりやすいですね。なので、問題で出てきたら、これはボーナス問題ですね。

メンテナンス(保守)テスト

開発が終了した後のメンテナンスの段階で実施するテストです。

今のソフトウェアは、使い続ける限り開発され続けることが多いので、あまりこの線引きはないように感じます。

目的は以下

  • 変更が正しく適用されていることを評価する
  • システムの変更していない部分での副作用を確認する

メンテナンステストで実施しなければならないテストの範囲を決める要因には以下のものがあります。

  • 変更のリスクの度合い
  • 既存システムの規模
  • 変更の規模

メンテナンスを行わなければならないケース

  • ソフトウェアの変更作業を行った時
  • ソフトウェアの運用環境が変わった時
  • 新しい環境への移行作業を行った時
  • ソフトウェアを廃棄した時

WindowsなどのOSのバージョン対応は非常にダルいテストだったりします。

特にリモートワークだと、これが大変で、環境は会社にしかないのです。

コロナで出社禁止の時は、端末を自宅に送ってもらってテストとかしてました。

ソフトウェアを廃棄するときは、データ移行作業や保管作業のテストや、データを保管した後のリストアや抽出の手順のテストが必要になります。

ちょっと違いますが、ソフトウェアを解約したとき、データのエクスポートの対応をする必要があったりしましたね。

メンテナンスの影響度分析

特に難しいのは2点

  • 変更による副作用
  • 変更が影響するシステム領域の識別

って、これまでエイヤで決めてました。

どこまで影響するのかは難しいです。

システム領域というか、機能になりますが、あの機能が拡張されたけど、前テストしたとき、全然不具合ないから大丈夫でしょと思ってたら、影響する機能の問題で、バグだらけだったことがありました。

以下のような状態の場合、影響度分析は困難になるので注意しましょう。

  • 仕様が最新でない、存在しない
  • テストケースが文書化されていない、または最新版ではない
  • テストとテストベースの間の双方向のトレーサビリティが維持されていない
  • ツールによる影響度分析のためサポートが貧弱であるが、全くない
  • ドメインおよび/またはシステムの知識を持つ担当者がいない
  • 開発時にソフトウェアの保守性が考慮されていない

というわけで第2章が終了しました。とにかくテストレベルで大苦戦しました。