ホワイトボックステストとは?基本的な定義や、ブラックボックステストや単体テストとの関係、やり方についても解説

Autify, Inc.

システム開発の成功には欠かせないテスト工程。しかし、適切なテスト手法を選ぶことは容易ではありません。

例えば、新しいアプリをリリースする際、ユーザーが直面する不具合を未然に防ぐにはどうすればよいのでしょうか? ここで重要になるのが、「ブラックボックステスト」と「ホワイトボックステスト」の2つの手法です。

ブラックボックステストは、システムの外部から見た仕様確認を行うのに対し、ホワイトボックステストは、開発者の視点でプログラム内部の動作をチェックします。

これらのテストは、それぞれ異なる視点でシステムの品質を保証するため、どちらも欠かせない存在です。

この記事では、特にホワイトボックステストに焦点を当て、その概要とメリット・デメリット、主な手法と実施手順を詳しく解説します。

ホワイトボックステストを活用することで、コードの内部構造を深く理解し、潜在的なバグを早期に発見することが可能です。システムの信頼性を高めるための具体的なアプローチを、一緒に見ていきましょう。

ホワイトボックステストとは

ホワイトボックステストは、プログラムの内部構造を理解し、意図通りに動作しているかを確認するためのテスト手法です。

具体的には、開発者がプログラムのコードをもとに、条件分岐や例外処理などを網羅的にテストします。テストにより、記載ミスや処理ミスを早期に発見し、プログラムが設計通りに動作しているかを確認可能です。

また、詳細設計書に基づいてテスト技法を適用しながらテスト項目を作成することで、いわゆるエッジケースと呼ばれる極端な条件下での問題を見つけることができます。

システムの信頼性を向上できるので、ホワイトボックステストは品質保証に欠かせない工程です。

ホワイトボックステストの意義

ソフトウェア開発において、プログラムが正確に動作することを保証するためのテストは不可欠です。その中でも、ホワイトボックステストは特に重要な役割を果たします。

以下では、ホワイトボックステストの具体的な意義について詳しく見ていきましょう。

(参考: https://jstqb.jp/dl/JSTQB-SyllabusFoundation_VersionV40.J01.pdf

ソフトウェアの実装そのものを考慮して欠陥を検出できる

ホワイトボックステストは、ソフトウェアの内部構造を直接検証することで、欠陥を効果的に発見できるテスト手法です。

この手法の強みは、ソフトウェアの仕様が曖昧だったり古かったりしても、実装そのものを考慮することで欠陥の検出が容易になる点にあります。

例えば、仕様書が古くなっていても、ホワイトボックステストでは実際のコードを解析し、内部のロジックや制御フローに基づいてテストを行います。

そのため、仕様書の不備に関わらず、実装上の不具合を見つけることが可能です。このように、ホワイトボックステストは、仕様の曖昧さや不完全さに影響されず、確実に欠陥を検出する能力を持っています。

カバレッジを客観的に測定できる

ホワイトボックステストのもう一つの重要な意義は、コードカバレッジを客観的に測定できる点です。

例えば、制御フローグラフを用いてテストケースの網羅性を確認することで、どの分岐やパスがテストされたかを視覚的に把握できます。また、不足しているテストケースを追加し、カバレッジを向上させることも可能です。

ブラックボックステストだけでは、コードカバレッジを測定することは困難です。しかしホワイトボックステストを併用することで、テストの網羅性を高め、ソフトウェアの信頼性を向上させるために必要な情報を得ることができます。

ホワイトボックステストのデメリット

ホワイトボックステストはソフトウェアの内部構造を精査し、コードレベルでの問題を発見する優れた手法ですが、その一方でデメリットも存在します。

その一つが「実装されていないものは検出できない」という点です。以下で詳しく解説していきます。

実装されていないものは検出できない

ホワイトボックステストは、実装されていないものは検出できないという欠点があります。

例えば、ソフトウェアが要件を正しく実装していない場合、このテストではその不備を見逃す可能性が高いです。要件の抜けがあると、ソフトウェアが正常に機能しているかどうかを十分に確認するのが難しくなります。

また、テストの際に開発者が自身のコードを重点的に見るため、他の視点が欠けがちになることも少なくありません。その結果、重要なバグや問題が見逃されるリスクが高まります。

このように、ホワイトボックステストはソフトウェアの内部動作を深く理解し、カバレッジを広げる点で有効ですが、要件漏れや開発者の視点偏重による課題も存在するため注意が必要です。

ホワイトボックステストが役に立つシチュエーション

ホワイトボックステストは、ソフトウェアの品質を確保するための強力なツールです。

特に、内部構造を理解しながらテストを行うため、特定の状況で非常に効果を発揮します。以下では、ホワイトボックステストがどのようなシチュエーションで役に立つかを詳しく説明します。

コードに対するテストの網羅性を定量的に検査したいとき

コードに対するテストの網羅性を定量的に検査したいとき、ホワイトボックステストが有用です。

ホワイトボックステストは、コードの内部構造や実装を知っている状態でテストを行うため、テストがどれだけコードをカバーしているかを評価できます。

具体的には、コードの各部分がどれだけの頻度で実行されているかを測定し、それに基づいてテストの網羅性を数値化することが可能です。

そのため、自動化されたテストが現在のコード実装のどの程度をカバーしているのかを明確に把握し、未カバーの部分を特定してテストを追加することができます。

ただし、ホワイトボックステストの限界として、実装されていないコードパスや不正確な仕様に基づくテストの不足を検出することができない点に留意する必要があります。

ホワイトボックステストとその他のテストとの違い

ホワイトボックステストは、ソフトウェアの内部構造を詳しく調査するために用いられるテスト手法です。しかし、他のテスト手法との違いを理解することも重要です。

次に、「ブラックボックステストとの違い」や「単体テスト・結合テストとの違い」について詳しく見ていきましょう。

これにより、各テスト手法の特性とホワイトボックステストが持つ独自の役割を明確にすることができます。

ブラックボックステストとの違い


ホワイトボックステストとブラックボックステストは、異なる視点とアプローチでソフトウェアをテストします。

ホワイトボックステストは、先述の文章でも説明している通り、ソフトウェアの内部構造やコードの流れに焦点を当てる手法です。テスト担当者は、コードの詳細を知り、内部のロジックやデータフローを確認しながらテストを行います。

一方、ブラックボックステストは、ソフトウェアの外部動作に焦点を当てる手法です。テスト担当者は、ソフトウェアの内部構造やコードの知識を必要とせず、入力に対する出力を確認します。

これにより、ユーザー体験に影響するエラーや機能の不備を発見することが可能です。テストケースは、ソフトウェアの要件や仕様に基づいて作成されます。

ホワイトボックステストは内部の詳細を、ブラックボックステストは外部からの動作を評価するところが相違点です。

単体テスト・結合テストとの違い

ソフトウェア開発におけるテスト手法には、単体テストと結合テストという2つの重要なアプローチがあります。これらのテスト手法は、異なる段階でソフトウェアの品質を確保するために使用されます。

単体テストは、ソフトウェアの最小単位である個々のモジュールや関数をテストする手法です。各モジュールが設計通りに動作することを確認し、コードの内部構造やロジックエラーを特定することが目的です。

主にホワイトボックステストの手法を用い、開発者がコードの詳細を理解しながらテストを行います。

結合テストは、単体テストをパスした個々のモジュールを組み合わせて、相互に連携して正しく動作するかを検証する手法です。

モジュール間のインターフェースやデータのやり取りをテストし、システム全体の一貫性を確保します。ホワイトボックステストとブラックボックステストの両方が使用され、モジュール間の詳細な連携を確認します。

ホワイトボックステストのやりかた

ホワイトボックステストは、ソフトウェアの内部構造やコードの流れを詳細に分析し、テストする手法です。主なテストの種類とそのカバレッジ基準について以下に解説します。

ホワイトボックステストの種類とカバレッジ

ホワイトボックステストでは、以下の主要なテスト技法があります。それぞれのテストは、コードの特定の側面をカバーするために使用されます。

ステートメントテスト

ステートメントテストは、ソフトウェア内のすべてのステートメント(文)が少なくとも一度は実行されることを確認します。これにより、ソフトウェアのすべての基本的な機能がテストされます。

ステートメントテストのカバレッジ (C0)

カバレッジ (C0)とは、カバレッジ基準として、ソフトウェア内の全てのステートメント(命令文)が実行されることを目指します。

def is_even(number):
    if number % 2 == 0 and number > 0:
        print("The number is even")
        return True
    else:
        print("The number is odd")
        return False
assert is_even(2) == True
assert is_even(3) == False

この例では、与えられた引数 number が偶数の場合に True を返す is_even 関数を実装しています。

ステートメントカバレッジ (C0) を達成するには、すべてのステートメントが少なくとも一度実行される必要があるので、奇数と偶数それぞれのテストケースが必要です。

一方、実装方法によっては、より少ないテストケースでカバレッジが100%になってしまう場合もあります。次の例を見てみましょう。

def is_even(number):
    return number % 2 == 0 and number > 0
assert is_even(2) == True

この場合、奇数もしくは偶数のテストケースがあれば、ステートメント(C0)カバレッジは100%になってしまいます。そのため、C0カバレッジが100%だからといって、必ずしも十分な量のテストコードがあるとは言い切れませんので、注意が必要です。

ブランチテスト

ブランチテストは、条件分岐(ブランチ)がすべての可能なパスを通ることを確認します。これにより、異なる条件に応じたソフトウェアの挙動をテストすることが可能です。

ブランチテストのカバレッジ (C1)

カバレッジ (C1)とは、カバレッジ基準として、全ての条件分岐が真と偽の両方のパスを通ることを目指します。

def is_even(number):
    if number % 2 == 0 and number > 0:
        print("The number is even")
        return True
    else:
        print("The number is odd")
        return False
assert is_even(2) == True
assert is_even(3) == False

この例では、is_even 関数の if 文に対して、真偽の両方のパスをカバーする必要があるため、奇数と偶数それぞれのテストケースが必要になります。

ただし、ステートメントカバレッジと同様、100%が必ずしもテストが十分であることを表さないため、注意が必要です。例えば、 number に文字列を渡した場合、2行目で除算ができないためエラーが起きますが、このテストが無くてもカバレッジ100%が達成できます。

条件テスト

条件テストは、条件式がすべての可能な結果を取ることを確認します。これにより、条件式が期待通りの挙動を示すかをテストします。

条件テストのカバレッジ (C2)

カバレッジ (C2)とは、カバレッジ基準として、全ての条件式がテストされることを目指します。

def is_even(number):
    if number % 2 == 0 and number > 0:
        print("The number is even")
        return True
    else:
        print(“The number is odd”)
        return False

assert is_even(2) == True
assert is_even(3) == False
assert is_even(0) == False

これまでの is_even 関数とは違い、 if 節の中に and で結合された複合条件が含まれています。そのため、C1カバレッジのテストケースに加え、「偶数だが0以下の数字」というテストケースが必要です。全ての条件をカバーすることで、カバレッジが100%となります。

ホワイトボックステストのやりかた

さまざまな言語でホワイトボックステストの網羅率を測定するライブラリがありますが、ここではRubyとSimpleCovを使った例を紹介します。

Ruby と simplecov を用いた例

Rubyとsimplecovを用いたホワイトボックステストを行うために、まずは環境構築を行います。今回はWindowsでの画面で説明いたしますが、MacOSと異なる部分は都度記述していきますので、ぜひ参考にしてください。

まずはRubyInstallerダウンロードサイトから「RubyInstaller」をダウンロードします。

Ruby のインストール

RubyInstallerのダウンロードサイトを開くと、以下の画面が表示されます。上部の「Download」ボタンをクリックし、ご自身の端末に適したRubyKitをダウンロードしてください。

インストールが完了したら、exeファイルを起動します。

起動すると、以下のようなポップアップが表示されるので、下のイメージの手順で進めてインストールしてください。

ここでインストールが開始されます。(時間がかかります)

これでRubyのインストールが完了します。MSYS2というツールも一緒にインストールできますが、今回はしなくても問題ありません。

SimpleCov のインストール

まずはSimpleCov用の作業フォルダを作成します。コマンドプロンプトで以下のコマンドを実行してください。(格納先は任意で大丈夫です)

mkdir SimpleCov

作成できたら、フォルダに移動しましょう。

cd SimpleCov

次に、Gemfileの作成を行います。以下のコマンドで作成可能です。Gemfileとは、Rubyで使用する道具をリストアップし、まとめてインストールできるようにしたものとなります。

bundle init

続いて、simplecov が使用できるように、Gemfileを開き、以下の行を追加します。エディタはVScodeなど、普段使用しているもので問題ありません。

後ほどRspecも使用するので、追記しておきましょう。

gem 'rspec'
gem 'simplecov', require: false, group: :test

ここまで準備できたら、Bundlerを使用してGemをインストールします。先ほどリストアップした道具をまとめてインストールする作業です。

bundle install

完了したら上記の表示がでて、コマンドが打てるようになっています。

SimpleCov の設定


まずはRSpecの初期化を行います。RspecはRuby言語用のテストフレームワークです。RubyやRailsと組み合わせて使用できるテスト自動化フレームワークで、カバレッジツールとの連携や、HTMLへの出力など、さまざまなテストに役立つ機能を提供します。

以下のコマンドから初期化可能です。

bundle exec rspec --init

上記の表示がでたら初期化完了です。続いて、spec/spec_helper.rbを開き、最初に以下の行を追加します。一番上に追加で大丈夫です。

この行を追加することで、simplecov を使用し、カバレッジ出力などができるようになります。

require 'simplecov'
SimpleCov.start

次は、libディレクトリを作成し、テスト対象となるRubyファイルを作成します。例えば、calculator.rbというファイルを作成し、以下の内容を追加します。

# lib/calculator.rb
class Calculator
  def add(a, b)
    a + b
  end
  def subtract(a, b)
    a - b
  end
end

次に、specディレクトリを作成し、テストファイルを作成します。例えば、calculator_spec.rbというファイルを作成し、以下の内容を追加します。

このとき、spec_helper.rbファイルもspecディレクトリに移動させておきましょう。

# spec/calculator_spec.rb
require 'spec_helper'
require 'calculator'
RSpec.describe Calculator do
  let(:calculator) { Calculator.new }
  describe '#add' do
    it 'adds two numbers' do
      expect(calculator.add(2, 3)).to eq(5)
    end
  end
  describe '#subtract' do
    it 'subtracts one number from another' do
      expect(calculator.subtract(5, 3)).to eq(2)
    end
  end
end

ここまで準備ができたら、テストを実行していきましょう。以下のコマンドを実行して、レポートを作成します。※フォルダを「spec」に移動してから実行してください。

bundle exec rspec

実行できると、以下の表示がでてきて、coverageフォルダが生成されます。その中のindex.htmlを見ると、テスト結果を参照することができます。

これでSimpleCovを活用したホワイトボックステストの実施ができました。SimpleCovはRuby用のコードカバレッジ分析ツールで、どのコードがどのくらいテストされたか分析するのに役立ちます。

まとめ

この記事では、システム開発におけるホワイトボックステストについて詳しく解説しました。

ホワイトボックステストは、プログラムの内部構造を理解し、意図通りに動作しているかを確認するための手法です。具体的には、開発者がコードをもとに条件分岐や例外処理などを網羅的にテストします。

この手法のメリットは、仕様書が曖昧でも、コードやロジックをもとにテストを行うため、実際の動作をベースに確認ができる点です。しかし、仕様書通りの実装になっていない場合には、正確なテストが行えないというデメリットもあります。そのため、ホワイトボックステストを使う場面を見極めることが重要です。

今回は、ホワイトボックステストを使うタイミングや実際にツールを使ったテスト手順など、具体的な情報をピックアップして解説しました。気になっている方は、本記事の内容や手順を参考に、まずはホワイトボックステストに触れてみることをおすすめします。