読書感想文:「JSTQB Foundation Level シラバス」

作成日:2023/02/03

面白かったポイントと考察

テストの 7 原則

7 原則のうち自分が気になった 3 つについて考察してみる。

「テストは欠陥があることは示せるが、欠陥がないことは示せない」と「全数テストは不可能」

小さなソフトウェアで完全に人間がコントロールできる場合は欠陥がないことは示せるかもしれない、全数テストも行えるかもしれない。 ただ、自分が現在のソフトウェアとしてイメージするものは、無数の組み合わせがあり複雑に入り組んだものである。そんなソフトウェアを完全にコントロールするのは、現実的でないように思える(というか実質的に不可能)。

自分はソフトウェアテストに向き合うまでバグゼロにこだわっていた気がする。その価値観が、このドキュメントを読んで変えることができたのは収穫だったなと思う。 人間の時間は無限ではない。効果の低い(「バグが発見できない」、「テスト対象のソフトウェアにとって重要ではない」)テストを行うより、テスト戦略に時間をかけたほうが建設的である。

早期テストで時間とコストを節約

バグ修正にかかるコストは、早期に発見するほど低くなる。反対に発見が遅れるほどコストが高くなる。自分が身を持って体験した例は以下の 4 つである。

  • ステージング環境でしか再現できないバグはデプロイの時間がオーバーヘッドになる
  • 終盤の受け入れテストで見つかったテストは原因を探す時間がオーバーヘッドになる
  • 仕様の勘違いなどコミュニケーションミスで見つかったバグは再実装にかかる時間や再認識合わせの時間がオーバーヘッドになる
  • リリース後に見つかったバグは再テストやリリースのための作業時間がオーバーヘッドになる

正直どれもダメージがでかくてストレスだった、、、

このコストを削減する取り組みの一つにテスト駆動開発があったりする。テストプロセスを開発の初期段階に持ってくることをシフトレフトと呼び、バグの早期発見によるコストの低減を狙う。 (現在テスト駆動開発のために筋トレ中)

トレーサビリティ

トレーサビリティとは「テストやドキュメントの追跡可能性」のことだと認識している(柔らかく言えば、「テストとソフトウェアの機能の結びつき」みたいな感じかなと)。例で言うと「この機能はこのテストで検証されているよね」「このテストはこの機能を検証しているよね」と説明できるような性質のことかなと思っている。

なぜこの性質が大事なのかというと、テストを人間が評価するためだと思っている。トレーサビリティの無いテストは形骸化し、テストの本来の目的であったバグの発見を難しくすると思う。結局最後に判断するのは人間なので自信をもって GO サインを出すためにも、「このテストが通っているからリグレッションが発生する確率は低いと思います!」と説明できるようにしておきたい。

テストレベル

テストはソフトウェアが完成した後の最終プロセスだけに行うではない。実際には開発プロセスごとに異なった役割をもつテストを行うことができる。 よく「単体テスト」とか「受け入れテスト」と呼ばれている概念はテストレベルのことである。テストレベルは役割(目的)ごとに分けられており、それぞれアプローチや責務が異なる。

例をあげると下記のようなアプローチがある。

  • 開発者による欠陥の早期発見を目的とする場合はローカルで実行できる「単体テスト」
  • ステークホルダーに対して品質を保証するときは本番環境で実行する「受け入れテスト」

各テストレベルに合った戦略を立てることで、テストケースも作りやすくなると思う。

静的テストと動的テスト

テスト技法の観点から、ソフトウェアのランタイムが不要な静的テストとソフトウェアのランタイムが必要な動的テストに分類できる。 静的テストはランタイムを必要としない性質から、バグを早期発見することができる。また、バグを早期に発見できるので開発プロセスの終盤で見つかるバグよりも修正コストが低い。

自分の理解では下記のソフトウェアが静的テストにあたる。

  • Code QLによる脆弱性チェック
  • ESLintによるコーディング規約違反チェック

静的テストはソフトウェアの振る舞いではなく、成果物に対して検証できる。シラバスにも記述されている通り、動的テストでは通らないパスに潜むバグを発見することに強みを持っている。

欠陥は、故障を引き起こすことなくきわめて長期間にわたって作業成果物に潜んでいることがある。この欠陥が潜んでいるパスはほとんど実行されることがないか、到達することが難しいので、このような欠陥を偶然検出できる動的テストを構築および実行することは容易ではない。静的テストでは、はるかに少ない工数で検出できる。(1)

一方で動的テストはソフトウェアのランタイム上で行うため、ユーザ視点での振る舞いに注目することができる。 自分の理解では下記のソフトウェアが動的テストにあたる。

  • Jestを使った単体テスト
  • Playwrightを使用した E2E テスト

静的テストと動的テストは相互補完の関係であるので、両方のテスト技法を組み合わせて検証することで、よりソフトウェアの信頼性を上げることができる。

コードレビュー

コードレビューも静的テストの一種である。 コードレビューはソフトウェアに対して下記などを行うことを目的とする。

  • バグの早期発見
  • 信頼の積み上げ
  • 合意形成(仕様や実装方法などの)
  • アイデアの創出
  • メンバーの学習

コードレビューには形式的なもの(チェックリストなど)と非形式的なものがある。 チームの状況や目的によって選択すると良い。例えば、下記のようなレビューのやり方が考えられる。

  • 考慮事項がはっきりと決まっている場合はチェックリストやドキュメントなどを使用しながらレビューを行う
  • チームの習熟度が低い場合はペアミーティングでレビューを行う

テスト戦略とテストアプローチ

テスト戦略とはテストに関する汎用的な考え方を定義したものである。テスト戦略を特定のプロジェクトにテーラリング(特化)したものがテストアプローチである。

テスト戦略の例として下記がある。

  • 分析的
    リスクに基づいて優先度付けをするリスクベースドテストなど
  • モデルベースド
    機能一覧表や状態遷移図などのモデルに基づいてテストを行うモデルベースドテストなど
  • 系統的
    事前に定義した一連のテストケースまたはテスト条件を体系的に使用するテスト
  • プロセス準拠
    業界固有の標準や外部ルールに基づいたテストなど
  • 指導ベース
    専門家などの指示に基づいたテストなど
  • リグレッション回避
    リグレッションを避けるテスト
  • 対処的
    過去の経験や知識に基づいて行われる探索的テストなど

上記を理解して、自分はよく行っている戦略は ① モデルベースドテスト、② リグレッション回避、③ 対処的の 3 つかなと思った。 要件定義を行い作成した機能一覧表をもとに行う戦略は「モデルベースド」、クリティカルパスを定義しリグレッションを見つけるための戦略は「リグレッション回避」、ためしにブラウザでソフトウェアを動作確認する戦略は「対処的」みたいな感じで戦略を分類できるのかなと思った。

これらのテスト戦略を基準に、どのテストレベル(段階)で行い、どのテストタイプ(何を評価するか)を選択し、どんなテスト技法(どうやってやるか)で行うかを適切に選択できると良いと思う。

参考文献

(1) 日本語翻訳版 Japan Software Testing Qualifications Board Version 2018V3.1.J03, p.47