Main Content

このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。

クラスベースのテストでのパラメーターの使用

多くの場合、テスト データのみが異なる一連のテストを実行する必要があります。たとえば、異なる入力に対して関数が予期した出力を生成することをテストする場合があります。この場合、テスト ロジックは同じであり、テスト間の唯一の差異は各関数呼び出しの実際の値と予期した値です。パラメーター化されたテストでは、異なるデータ値を使用して反復的にテストを実行するコードを実装できます。メソッドをパラメーター化すると、テスト フレームワークはパラメーター値ごとにメソッドを自動的に呼び出します。したがって、各値に個別のメソッドを実装する必要はありません。

テスト フレームワークを使用すると、さまざまなレベルでテスト クラスをパラメーター化できます。さらに、複数のパラメーターを指定してテスト クラス メソッドを呼び出す場合、異なるパラメーターの組み合わせについてメソッドを呼び出す方法を指定できます。

パラメーター化されたテストを作成する方法

matlab.unittest.TestCase クラスから派生したクラスは、フレームワーク固有のプロパティとメソッドの属性を使用して、テストのパラメーター化を実装できます。クラスベースのテストでデータをパラメーターとして指定するには、適切なパラメーター化の属性をもつ properties ブロックを使用してデータを指定します。次に、1 つ以上のメソッドに入力引数としてパラメーター化プロパティを渡します。

たとえば、SampleTest クラスについて考えてみます。このクラスは、TestParameter 属性をもつ properties ブロック内にプロパティを指定するので、パラメーター化されたテストを定義します。このプロパティが Test メソッドに渡され、検定の実行に使用されます。

classdef SampleTest < matlab.unittest.TestCase
    properties (TestParameter)
        numericArray = {int16(1),single(zeros(1,4)),magic(3)};
        functionHandle = {@false,@() size([])};
    end
    methods (Test)
        function test1(testCase,numericArray)
            testCase.verifyNotEmpty(numericArray)
        end
        function test2(testCase,functionHandle)
            testCase.verifyWarningFree(functionHandle)
        end
    end
end

テスト クラスは 5 つの要素をもつパラメーター化テスト スイートになります。

suite = testsuite("SampleTest");
{suite.Name}'
ans =

  5×1 cell array

    {'SampleTest/test1(numericArray=int16_1)'          }
    {'SampleTest/test1(numericArray=1x4_single)'       }
    {'SampleTest/test1(numericArray=3x3_double)'       }
    {'SampleTest/test2(functionHandle=@false)'         }
    {'SampleTest/test2(functionHandle=function_handle)'}

パラメーター化プロパティに割り当てられた値は、空でない cell 配列、または、少なくとも 1 つのフィールドをもつスカラー構造体のいずれかでなければなりません。テスト フレームワークはプロパティ値を使用して、テスト スイートのパラメーター名と値を指定します。

  • プロパティ値が cell 配列である場合、テスト フレームワークは値、型、および次元を考慮して、cell 配列の要素からわかりやすいパラメーター名を生成します。

  • プロパティ値が構造体である場合、構造体のフィールドはパラメーター名を表し、構造体の値はパラメーター値を表します。スイート内のパラメーター名を完全に制御するには、cell 配列ではなく、構造体を使用してパラメーターを定義します。

パラメーター化プロパティの初期化方法

パラメーター化プロパティを定義するときに、MATLAB® でパラメーター名と値を生成できるようにプロパティを初期化しなければなりません。プロパティは、テスト クラスの読み込み時またはテスト スイートの作成時のいずれかに初期化できます。

  • クラスの読み込み時:MATLAB がテスト クラス定義を読み込むときにプロパティ値を決定できる場合、既定値を使用してプロパティを初期化します。既定値は properties ブロックで、または classdef ファイルのローカル関数を使用して指定できます。クラス定義内で値を割り当てる方法の詳細については、クラス定義内の式の評価を参照してください。

    クラスの読み込み時にパラメーター化プロパティを初期化する場合、プロパティに関連付けられているパラメーターはさまざまなテスト実行に対して固定されたままになります。パラメーター化されたテスト クラスからスイートを作成するたびに、フレームワークは同じパラメーター名と値を使用してテストを実行します。既定値をもつパラメーター化プロパティを使用する例については、基本的なパラメーター化テストの作成を参照してください。

  • スイートの作成時:クラスの読み込み時にパラメーターを決定できない場合、または決定しない場合、TestParameterDefinition 属性をもつ静的メソッドを使用してスイートの作成時にプロパティを初期化します。TestParameterDefinition メソッドでパラメーター化プロパティを初期化する場合、プロパティに関連付けられているパラメーターはさまざまなテスト実行に対して変化する場合があります。パラメーター化されたテスト クラスからスイートを作成するたびに、フレームワークは新しいパラメーター名と値を生成してテストを実行します。詳細については、Define Parameters at Suite Creation Timeを参照してください。

メモ

値をパラメーター化プロパティに割り当てた後は、変更しないでください。たとえば、既定値を使用してパラメーター化プロパティを初期化する場合、TestParameterDefinition メソッドを使用して既定値を上書きすることはできません。

1 つのパラメーターが複数のユニット テストで使用される可能性があります。同じパラメーターを使用するテストは、誤って相互に影響を与えることなく、個別に実行しなければなりません。また、テストの実行が同じテストの後続の再実行に影響してはなりません。テスト実行の独立性を確保するには、値オブジェクトでパラメーター化プロパティを初期化します。パラメーター値としてのハンドル オブジェクト (MATLAB グラフィックス オブジェクトなど) の使用は推奨されません。値オブジェクトおよびハンドル オブジェクトの動作の詳細については、ハンドル クラスと値クラスの比較を参照してください。

パラメーター化されたテストでハンドル オブジェクトをテストする必要がある場合は、関数ハンドルをパラメーター値として使用してそれらの関数ハンドルをテストで呼び出すことにより、間接的に作成することを検討してください。たとえば、パラメーター化されたテストを書き込んで、関数 figure と関数 uifigure で作成された Figure の既定の現在の点をテストします。

classdef FigureTest < matlab.unittest.TestCase
    properties (TestParameter)
        figureType = {@figure,@uifigure};
    end
    methods (Test)
        function defaultCurrentPoint(testCase,figureType)
            fig = figureType();
            testCase.addTeardown(@close,fig)
            cp = fig.CurrentPoint;
            testCase.verifyEqual(cp,[0 0])
        end
    end
end

パラメーター化レベルの指定

クラス セットアップ、メソッド セットアップおよびテストの 3 つのレベルでテスト クラスをパラメーター化できます。各レベルでパラメーター化するには、パラメーター化のプロパティに特定のプロパティ属性が必要です。たとえば、最上位レベルで、TestClassSetup メソッドは、ClassSetupParameter 属性をもつ properties ブロックに定義されたプロパティを使用してパラメーター化できます。最下位レベルで、Test メソッドは、TestParameter 属性をもつ properties ブロックに定義されたプロパティを使用してパラメーター化できます。

次の表に、さまざまなパラメーター化レベルと、各レベルに必須のメソッドの属性およびプロパティの属性を示します。

パラメーター化レベルパラメーター化定義アクセス可能なパラメーター化プロパティ
メソッドの属性プロパティの属性
クラス セットアップ レベルTestClassSetupClassSetupParameterClassSetupParameter
メソッド セットアップ レベルTestMethodSetupMethodSetupParameterMethodSetupParameter および ClassSetupParameter
テスト レベルTestTestParameterTestParameterMethodSetupParameter、および ClassSetupParameter

パラメーター化されたメソッドは、メソッドが定義されているレベルに応じてパラメーター化プロパティにアクセスできます。

  • パラメーター化された TestClassSetup メソッドは、ClassSetupParameter 属性をもつパラメーター化プロパティにのみアクセスできます。

  • パラメーター化された TestMethodSetup メソッドは、MethodSetupParameter 属性または ClassSetupParameter 属性をもつパラメーター化プロパティにのみアクセスできます。

  • パラメーター化された Test メソッドは、すべてのパラメーター化プロパティにアクセスできます。

異なるレベルでテスト クラスをパラメーター化する方法の例については、高度なパラメーター化テストの作成を参照してください。

パラメーターを組み合わせる方法の指定

複数のパラメーター化プロパティをメソッドに渡す場合、ParameterCombination メソッド属性を使用してパラメーターを組み合わせる方法を指定できます。テスト フレームワークは、指定された組み合わせについてメソッドを呼び出します。

次の表に、異なるパラメーターの組み合わせ方針を示します。

ParameterCombination 属性値メソッドの呼び出し
"exhaustive" (既定)

メソッドはパラメーター値のすべての組み合わせについて呼び出されます。ParameterCombination 属性が指定されていない場合、テスト フレームワークはこの既定の組み合わせを使用します。

"sequential"

メソッドは、対応するパラメーター値とともに呼び出されます。パラメーター化プロパティでは同じ数のパラメーター値を指定する必要があります。たとえば、メソッドに 2 つのパラメーター化プロパティが指定され、各プロパティが 3 つのパラメーター値を指定する場合、フレームワークはこのメソッドを 3 回呼び出します。

"pairwise"

パラメーター値の各ペアについて少なくとも 1 回はメソッドが呼び出されます。網羅的な組み合わせと比較して、ペア単位の組み合わせは一般にテスト数が少ないので、テストの実行が高速になります。

たとえば、以下のテストではペア単位の組み合わせを使用して、さまざまな行列のサイズをテストします。

classdef ZerosTest < matlab.unittest.TestCase
    properties (TestParameter)
        rowCount = struct("r1",1,"r2",2,"r3",3);
        columnCount = struct("c1",2,"c2",3,"c3",4);
        type = {'single','double','uint16'};
    end
    methods (Test,ParameterCombination="pairwise")
        function testSize(testCase,rowCount,columnCount,type)
            testCase.verifySize(zeros(rowCount,columnCount,type), ...
                [rowCount columnCount])
        end
    end
end

クラスからテスト スイートを作成します。起こり得る結果の 1 つには、以下に示す 10 個の要素が含まれます。

suite = testsuite("ZerosTest");
{suite.Name}'
ans =

  10×1 cell array

    {'ZerosTest/testSize(rowCount=r1,columnCount=c1,type=single)'}
    {'ZerosTest/testSize(rowCount=r1,columnCount=c2,type=double)'}
    {'ZerosTest/testSize(rowCount=r1,columnCount=c3,type=uint16)'}
    {'ZerosTest/testSize(rowCount=r2,columnCount=c1,type=double)'}
    {'ZerosTest/testSize(rowCount=r2,columnCount=c2,type=single)'}
    {'ZerosTest/testSize(rowCount=r2,columnCount=c3,type=single)'}
    {'ZerosTest/testSize(rowCount=r3,columnCount=c1,type=uint16)'}
    {'ZerosTest/testSize(rowCount=r3,columnCount=c2,type=single)'}
    {'ZerosTest/testSize(rowCount=r3,columnCount=c3,type=double)'}
    {'ZerosTest/testSize(rowCount=r2,columnCount=c2,type=uint16)'}

テスト フレームワークでは、任意の 2 つのプロパティで指定されているパラメーター値のそれぞれの組み合わせについて、testSize メソッドが確実に呼び出されます。たとえば、rowCount プロパティと columnCount プロパティについて、以下の表に、パラメーター値の組み合わせに対応する TestSuite 配列インデックスを示します。すべての組み合わせは、少なくとも 1 つの Test 要素で表されます。

columnCount プロパティ
c1c2c3
rowCount プロパティr1123
r245、106
r3789

フレームワークでは、値のペアのそれぞれについて確実にテストが少なくとも 1 回作成されますが、スイートのサイズ、テスト スイートの要素の順序または特定セットは予測できません。

"n-wise"

メソッドは、パラメーター値の n 組ごとに 1 回以上呼び出されます (MATLAB Test™ が必要)。n を 2 ~ 10 の整数として指定できます。たとえば、属性を "4-wise" として指定すると、パラメーター値の 4 組ごとに 1 回以上メソッドが呼び出されます。

"2-wise" 属性値と "pairwise" 属性値は同義的に使用できます。"n-wise" のパラメーターの組み合わせではペア単位の組み合わせが一般化され、通常はテスト数が少なくなるため、網羅的な組み合わせと比較してテストの実行が高速になります。フレームワークでは、値の n 組ごとに確実にテストが少なくとも 1 回作成されますが、スイートのサイズ、テスト スイートの要素の順序または特定セットは予測できません。

クラス セットアップ レベル、メソッド セットアップ レベルおよびテスト レベルでパラメーターを組み合わせることができます。たとえば、2 つのメソッド属性 TestMethodSetup,ParameterCombination="sequential" を使用して、MethodSetupParameter 属性をもつ properties ブロックで定義されたメソッド セットアップ レベルのパラメーターについて逐次の組み合わせを指定できます。

テスト パラメーターを組み合わせる方法の例については、基本的なパラメーター化テストの作成高度なパラメーター化テストの作成を参照してください。

テストでの外部パラメーターの使用

パラメーター化されたテストを作成するときに、入力をクラスベースのテストに挿入してパラメーターを再定義できます。テスト ファイルの外部で定義されたデータを指定するには、テスト スイートの作成時に Parameter インスタンスを作成して名前と値の引数 ExternalParameter を使用します。詳細については、パラメーター化されたテストでの外部パラメーターの使用を参照してください。

参考

クラス

名前空間

関連するトピック