ソフトウェアプロダクトライン開発でのテストアプローチ

ソフトウェアプロダクトライン開発とは

ソフトウェアプロダクトライン開発(SPLE:Software Product Line Engineering。ソフトウェア製品系列開発)は、複数の類似した製品群(プロダクトライン)の開発についての開発手法・テクニックです。プロダクトラインで共有する資産を効果的に運用して、プロダクトラインの価値を高めたり、開発生産性を高めたりすることを目指します。

ここでいうプロダクトラインは次のようなものです。

  • 仕向け地ごとといった複数のバリエーションのグループ
  • 異なるグレード群のグループ

SPLEは、複数の製品で共有する共通資産をソフトウェアプラットフォームとして開発し、それを使って個別のソフトウェアプロダクトの開発の効率化を目指します。

ここでいうソフトウェアプラットフォームは、コンポーネントといったソフトウェアの部品だけでなく、その要件、設計、テストといった開発情報も含まれます。

このソフトウェアプラットフォームを整備し、複数のプロダクト群に共通資産として展開することで、次の恩恵を確保します。

  • 開発リードタイムの短縮。既存の共通資産を活用することで個別プロダクトの開発リードタイムを圧縮する。
  • 開発費用の低減。既存の共通資産を活用することで、複数のプロダクト群を開発する場合の総コストを削減する。
  • 品質の向上。品質を作りこんだ共通資産を活用することで、その作りこみの恩恵を個別プロダクトでも享受する。
  • 顧客価値の向上。上記のリードタイム短縮やコスト削減、品質向上の帰結として、顧客価値を向上する。

また上記以外の副次的な恩恵として、製品群の保守のサポートや、アーキテクチャの複雑化対応といったものも実現します。

ソフトウェアプロダクトライン開発のプロセス

SPLEは、ソフトウェアプラットフォームを開発するドメイン開発プロセスと、個別プロダクトを開発するアプリケーション開発プロセスの二つのプロセスを独立で運用します。

ドメイン開発プロセスでは、プロダクトマネジメントの活動で、プロダクトライン(製品系列)のマーケティング、企画、ポートフォリオ管理を行います。プロダクトマネジメントは、プロダクトラインの製品ロードマップをドメイン開発プロセスに対し出力します。SPLEの製品ロードマップは、将来にわたってのプロダクトラインの共通フィーチャ、可変フィーチャの要件の情報を含みます。
そしてプロダクトマネジメントの結果に従って、ドメインの要求開発、設計、実現(Realisation。詳細設計と実装)、テストをインクリメンタル・反復的に実施して、ソフトウェアプラットフォームを蓄積・整備していきます。

アプリケーション開発プロセスでは、通常のプロダクト開発を行います。要求開発では、ドメイン要求とアプリケーション要求を両方分析し、ソフトウェアプラットフォームの活用が増えるように要件定義を行います。以後の設計、実現、テストについても、ソフトウェアプラットフォームの資産を活用して、開発生産性を高めていきます。

ソフトウェアプロダクトライン開発を支えるテストアプローチ

SPLEにおいてソフトウェアテストは重要な役割を果たします。
特にソフトウェアプラットフォームに対するテストは、次の二方面から開発生産性を支えます。

  • プラットフォームの品質確保を支え、それによってプロダクトラン全体の生産性向上を支える。
  • 資産として共有されることで、アプリケーションに対するテストを効率化する。

一方で、SPLEのような共通資産を活用するアプローチでは、可変性の管理、可変性への備え、共通資産と個別プロダクトの連携といった、様々なテストアプローチの工夫が求められます。
以降に、SPLEに求められるテストアプローチを解説します。

全体最適が得られるようにドメインテストとアプリケーションテストを分担させる

ドメインテストとアプリケーションテストの分担の適切さは、プロダクトライン全体の生産性に影響します。

特に定番の課題となるのが、プラットフォームに対し、ドメインテストをどの程度詳細に実施するかです。

まずドメインテストは簡易的な確認しかせず、必要なテストの責務をアプリケーションテストのみで対象仕様とすると、個々のプロダクトごとに大きなテスト期間・リソースが必要になり、プロダクトライン全体での効率化を悪化させます。

逆にドメインテストで詳細なテストをして、そのプラットフォーム部分のテストをアプリケーションテストでは省略するアプローチでは、次のような要因でコストが過剰にかかることになります。

  • ドメインテストで多種多様な変異体のテストをしなくてはならない。
  • アプリケーションの実行環境や依存コンポーネントが存在しない状態でテストしなければならない場面が増える。Test Doubleで代替できることもあるが、SPLEがフィットする大規模な組込み製品といったタイプでは現実的でないことが多い。

上記のような制約があることから、ドメインテストとアプリケーションテストは、無理なく共有資産化の効果を得られる分担のバランス取りが求められます。具体的には次のような方針で分担する必要があります。

  • ドメインテストは次の方針に従う。
    • コードレベルのテスト(例えばユニットテスト)は網羅的に作成する。
    • 共通部分に対しテストを作成する。プロダクトごとの可変部分については、テストがやりやすいように、再利用可能なテスト資産をアプリケーション開発に対して提供する。
  • アプリケーションテストは、資産として提供されたドメインテストを再利用する形で、アプリケーション固有のテストを作成する。

ドメインテストは段階的に育て洗練させる

前述で少し触れましたが、ドメインテストは、アプリケーションの実行環境や依存コンポーネントが存在しない状態でテストしなければならない場合があります。これは複雑な製品ではTest Doubleによる対応が難しい制約があります。
この制約に対応するため、ドメインテストは次のような段階的な洗練を行う必要があります。

  • 【最初のアプリケーション開発初期】ユニットテストや、小中規模の仮想環境でのテストといった、限定的なテストを実施する。
  • 【最初のアプリケーション開発中記】アプリケーションのプロトタイピング環境を流用し、それを使って共通部分に対するテストを充実させる
  • 【最初のアプリケーション開発後期、次のアプリケーション開発開始期】最初のアプリケーションの環境をベースに、テストを充実させる。

テストをプロダクトコードのパラダイムに合わせる

SPLEのプラットフォームは共通化の促進のため、特別なパラダイムを適用する場合があります。この適用は、プラットフォーム全体に適用することもあれば、プラットフォームとアプリケーションの境界レイヤに限定して提供する場合もあります。
適用されるパラダイムを以下に示します。

  • ジェネレーティブなコード。コード生成ツールやモデル駆動開発ツールを使って、アプリケーションに合わせたコードを自動生成する。
  • メタプログラミング。高位ロジックでアプリケーションに合わせたコードを実現する。
  • プリプロセス。プリプロセッサ処理でアプリケーションにあわせたコードを実現する。

プラットフォームのテストは、プラットフォームのコンポーネント資産とセットで利用されるため、そのテストは、プラットフォームと同じパラダイムに遵守するのが基本です。

例えば様々なアプリケーションに柔軟に対応するため、プラットフォームの資産をジェネレーティブにすることは珍しくありません。その際は、テストもジェネレーティブにしなければなりません。すなわち、プラットフォームを生成できるようなパラメータ設定を、テストにも適用できるようにする必要があります。

可変性はプロダクトマネジメントの管理下に置く。テスト単独で対処しない

SPLEは、可変性をプロダクトマネジメントの管理下に置く必要があります。具体的には、プロダクトライン全体の視座でフィーチャや可変性を把握し、それに基づいてプラットフォームの可変性を開発する必要があります。
これは、際限のない無数の選択肢・バリエーションを、費用対効果に見合う可変性スコープに絞り込むためです。

テストでは、品質リスクに基づいてテストを作ることから、プロダクトマネジメントのスコープ外の可変性をテスト使用する場面が出てきますが、これは不吉な兆候です。

もしスコープ外のテストを作らなければならない理由が、プロダクトマネジメントの不備ならば、プロダクトマネジメントを立て直して、ドメインの要件分析、開発、テストと一通りのドメイン開発プロセスをまわすのが妥当です。プロダクトマネジメントの不備をテストでごまかすと、プロダクトライン開発全体に悪影響を及ぼすリスクを高めます。

一方、プロダクトマネジメントが適切なのに、スコープ外のテストを作ろうとする場合も問題を起こします。その場合、根拠が不明なテストが生まれ、アプリケーション開発を阻害するためです。

なおスコープが曖昧になりがちなポイントに、時間軸の可変性があります。これは、将来追加される可能性のある可変性です。ただこういったものも、基本的にプロダクトマネジメントの管理下におくべきものになります。

自動化されたリグレッションテストおよびテスト自動化容易性を充実させる

ドメイン開発でもアプリケーション開発でも、ユニットテスト結合テストにて、自動化されたリグレッションテストを満遍なくコンポーネントに配備することが重要です。
というのも、SPLDではドメイン開発プロセスとアプリケーション開発プロセスが独立で動くことで、変更の割り込みがよく発生するためです。例えばプロダクトラインの複数のプロダクトを並行開発しているときに、あるプロダクトでプラットフォームのバグが見つかり、プラットフォームのデバッグと、プラットフォームを共有している他のアプリケーションへのデバッグの取り込みが発生する、といったことは珍しくありません。プロセスが独立で動いていることから、この変更の割り込みはリリース間際でテストが十分に行えないタイミングで発生することもあります。

そこで重要になるのが、自動化されたリグレッションテストをプラットフォームにもプロダクトにもいき渡しておくことです。そのテストがあると、変更の割り込みの受け入れが容易になります。

また、自動化されたリグレッションテストをいきわたらせるために、テスト自動化容易性をいきわたらせるのも重要です。それにより、プラットフォーム側から十分なリグレッションテストを提供できなくとも、アプリケーション開発の中でリグレッションテストを構築できるようになります。

テストのモジュール性とトレーサビリティを確保する

テストの再利用を容易にするためには、テストのモジュール性の改善が必要です。保守がしやすいよう責務割り当てが適切で、外部に不必要な依存性を持たないモジュール性設計をテストコードでも推進することで、プラットフォームのテストを共有するのも、アプリケーションのテストをプラットフォームに取り込むのも容易になります。

また、テストのインプットとなっている要件や設計とのトレーサビリティの明確化も重要です。可変性設計、変異性設計ではフィーチャを単位としますが、フィーチャごとにテストを紐づけることで、フィーチャの取捨選択においてどのテストを選出すればよいか明確になります。

持続可能なテストウェアやテストシステムを利用する

SPLEのプラットフォーム資産は、持続可能な状態にして長く共有できると費用対効果が高まります。そのためプラットフォーム資産を構成するテストウェアやテストシステムを構築するのが重要です。

例えばSPLEのような共通資産化戦略で良く問題になるのが、依存しているプラットフォームやフレームワークの転換です。使用しているフレームワークが廃れ別のフレームワークに主流が入れ替わるというのような状況はフロントエンドを中心に珍しくなく、それによりフレームワークに依存する資産がまとめて陳腐化する、といった状況は複数見てきました。資産化戦略では、枯れて安定した技術スタックを選ぶべきなのと、変化が起きるの当たり前として資産化戦略を組む必要があります。

また本質的にSPLEと紐づいた要素ではありませんが、SPLEで使用するツールの維持コスト・ライセンスコストで悩まされる現場も見てきました。例えばSPLEのプラットフォームにモデル駆動開発を導入している場面で、そのモデル駆動開発ツールのライセンス料が高額かつロックインが協力なため、時がたつほどSPLEの費用対効果が目減りしていく状況に遭遇したことがあります。SPLEでは、長いライフサイクルで費用対効果を評価し、技術スタックを構築すべきです。

アプリケーションごとのテストの集積でなく、プロダクトラインに対する包括的なテストを設計する

SPLEでのテスト設計アプローチに、アプリケーションごとのテストを集めて、プラットフォームのテストとするものがあります。このテスト設計アプローチは弊害が多く、保守を阻害するテストの重複が多数発生するほか、テスト対象とテストのトレーサビリティ構造がツリーでなくセミラティスとなり、トレーサビリティの維持が難しくなります。

そのため、SPLEのテスト設計アプローチは、変異性を包含するプロダクトラインに対してテスト設計するのが無難です。
なお個々のアプリーケーションでないと実現できないテスト条件(環境条件など)が発生するのは少なくありません。その際は、プロダクトラインに対する包括的なテストを、チャンピオン的なアプリケーションに対するテストで実現しつつ、そこでカバーできない個々のテスト条件を、それぞれのアプリケーション条件でテストすべきです。

保守性が高まるように内部可変性を設計する

SPLEでは外部可変性の設計が解説されることが多いのですが、内部可変性の設計も重要です。特にプロダクトコードについてはテスト容易性が高まるように内部可変性設計を行い、テストコードではテストの保守が容易になるように内部可変性設計を行うのが重要です。

共通資産固有のテスト観点を使う

SPLEのプラットフォームに対するテストでは、共有資産なりのテスト観点が求められます。
具体的には次のようなものを追加のテスト観点として分析する必要があります。

  • プラットフォーム資産とアプリケーションを紐づけるアダプターやジェネレータのテスト
    • 例えばプラットフォーム資産をジェネレーティブ人するならば、ジェネレータのテストをよく考える必要があります
  • 可変性制約に対するテスト。
    • 選択しないフィーチャ、選択できないフィーチャが存在しないことのテストや、可変性制約を実現不能にする仕組みのテストが求められます。