Main Content

高度なパラメーター化テストの作成

この例では、TestClassSetupTestMethodSetup および Test methods ブロックでパラメーター化テストを作成する方法について説明します。この例のテスト クラスは乱数発生をテストします。

TestRand テスト クラスの作成

現在のフォルダー内のファイルに、乱数発生のさまざまな項目をテストする TestRand クラスを作成します。パラメーター化テストに使用するプロパティを定義します。

classdef TestRand < matlab.unittest.TestCase
    properties (ClassSetupParameter)
        generator = {'twister','combRecursive','multFibonacci'};
    end
    
    properties (MethodSetupParameter)
        seed = {0,123,4294967295};
    end
    
    properties (TestParameter)
        dim1 = struct('small',1,'medium',2,'large',3);
        dim2 = struct('small',2,'medium',3,'large',4);
        dim3 = struct('small',3,'medium',4,'large',5);
        type = {'single','double'};
    end
end

TestRand クラスの個々の properties ブロックは、特定のレベルのパラメーター化に対応しています。クラス セットアップレベルのパラメーター化では乱数発生器のタイプを定義しています。メソッド セットアップレベルのパラメーター化では乱数発生器のシードを定義し、テストレベルのパラメーター化では乱数値のデータ型とサイズを定義しています。

テスト クラスとテスト メソッドのセットアップ メソッドの定義

テスト クラスとテスト メソッド レベルでセットアップ メソッドを定義します。これらのメソッドは乱数発生器の初期状態を登録します。フレームワークがテストを実行した後、メソッドにより元の状態に戻されます。classSetup メソッドは乱数発生器のタイプを定義し、methodSetup メソッドは乱数発生器のシードを指定します。

classdef TestRand < matlab.unittest.TestCase
    properties (ClassSetupParameter)
        generator = {'twister','combRecursive','multFibonacci'};
    end
    
    properties (MethodSetupParameter)
        seed = {0,123,4294967295};
    end
    
    properties (TestParameter)
        dim1 = struct('small',1,'medium',2,'large',3);
        dim2 = struct('small',2,'medium',3,'large',4);
        dim3 = struct('small',3,'medium',4,'large',5);
        type = {'single','double'};
    end
    
    methods (TestClassSetup)
        function classSetup(testCase,generator)
            orig = rng;
            testCase.addTeardown(@rng,orig)
            rng(0,generator)
        end
    end
    
    methods (TestMethodSetup)
        function methodSetup(testCase,seed)
            orig = rng;
            testCase.addTeardown(@rng,orig)
            rng(seed)
        end
    end
end

逐次的なパラメーターの組み合わせを使用するテスト メソッドの定義

Test 属性と ParameterCombination = 'sequential' 属性を指定した methods ブロックに testSize メソッドを定義します。

classdef TestRand < matlab.unittest.TestCase
    properties (ClassSetupParameter)
        generator = {'twister','combRecursive','multFibonacci'};
    end
    
    properties (MethodSetupParameter)
        seed = {0,123,4294967295};
    end
    
    properties (TestParameter)
        dim1 = struct('small',1,'medium',2,'large',3);
        dim2 = struct('small',2,'medium',3,'large',4);
        dim3 = struct('small',3,'medium',4,'large',5);
        type = {'single','double'};
    end
    
    methods (TestClassSetup)
        function classSetup(testCase,generator)
            orig = rng;
            testCase.addTeardown(@rng,orig)
            rng(0,generator)
        end
    end
    
    methods (TestMethodSetup)
        function methodSetup(testCase,seed)
            orig = rng;
            testCase.addTeardown(@rng,orig)
            rng(seed)
        end
    end
    
    methods (Test, ParameterCombination = 'sequential')
        function testSize(testCase,dim1,dim2,dim3)
            testCase.verifySize(rand(dim1,dim2,dim3),[dim1 dim2 dim3])
        end
    end
end

このメソッドは、dim1dim2 および dim3 の対応する個々のパラメーター値について出力サイズをテストします。与えられた TestClassSetupTestMethodSetup のパラメーター化について、フレームワークは testSize メソッドを 3 回 ('small''medium' および 'large' のそれぞれの値につき 1 回) 呼び出します。たとえば、すべての 'medium' 値でテストするために、フレームワークは testCase.verifySize(rand(2,3,4),[2 3 4]) を使用します。

ペア単位のパラメーターの組み合わせを使用するテスト メソッドの定義

Test 属性と ParameterCombination = 'pairwise' 属性を指定した methods ブロックに testRepeatable メソッドを定義します。

classdef TestRand < matlab.unittest.TestCase
    properties (ClassSetupParameter)
        generator = {'twister','combRecursive','multFibonacci'};
    end
    
    properties (MethodSetupParameter)
        seed = {0,123,4294967295};
    end
    
    properties (TestParameter)
        dim1 = struct('small',1,'medium',2,'large',3);
        dim2 = struct('small',2,'medium',3,'large',4);
        dim3 = struct('small',3,'medium',4,'large',5);
        type = {'single','double'};
    end
    
    methods (TestClassSetup)
        function classSetup(testCase,generator)
            orig = rng;
            testCase.addTeardown(@rng,orig)
            rng(0,generator)
        end
    end
    
    methods (TestMethodSetup)
        function methodSetup(testCase,seed)
            orig = rng;
            testCase.addTeardown(@rng,orig)
            rng(seed)
        end
    end
    
    methods (Test, ParameterCombination = 'sequential')
        function testSize(testCase,dim1,dim2,dim3)
            testCase.verifySize(rand(dim1,dim2,dim3),[dim1 dim2 dim3])
        end
    end
    
    methods (Test, ParameterCombination = 'pairwise')
        function testRepeatable(testCase,dim1,dim2,dim3)
            state = rng;
            firstRun = rand(dim1,dim2,dim3);
            rng(state)
            secondRun = rand(dim1,dim2,dim3);
            testCase.verifyEqual(firstRun,secondRun)
        end
    end
end

このメソッドは、乱数発生器の結果が再現可能であることを検証します。与えられた TestClassSetupTestMethodSetup のパラメーター化について、フレームワークは dim1dim2 および dim3 で指定されたパラメーター値の各ペアを確実にテストするように testRepeatable メソッドを 10 回呼び出します。パラメーターの組み合わせが網羅的であれば、フレームワークはメソッドを 3³ = 27 回呼び出します。

網羅的なパラメーターの組み合わせを使用するテスト メソッドの定義

Test 属性を指定した methods ブロックに、testClass メソッドを定義します。ParameterCombination 属性が指定されていないため、パラメーターの組み合わせは既定で網羅的です。

classdef TestRand < matlab.unittest.TestCase
    properties (ClassSetupParameter)
        generator = {'twister','combRecursive','multFibonacci'};
    end
    
    properties (MethodSetupParameter)
        seed = {0,123,4294967295};
    end
    
    properties (TestParameter)
        dim1 = struct('small',1,'medium',2,'large',3);
        dim2 = struct('small',2,'medium',3,'large',4);
        dim3 = struct('small',3,'medium',4,'large',5);
        type = {'single','double'};
    end
    
    methods (TestClassSetup)
        function classSetup(testCase,generator)
            orig = rng;
            testCase.addTeardown(@rng,orig)
            rng(0,generator)
        end
    end
    
    methods (TestMethodSetup)
        function methodSetup(testCase,seed)
            orig = rng;
            testCase.addTeardown(@rng,orig)
            rng(seed)
        end
    end
    
    methods (Test, ParameterCombination = 'sequential')
        function testSize(testCase,dim1,dim2,dim3)
            testCase.verifySize(rand(dim1,dim2,dim3),[dim1 dim2 dim3])
        end
    end
    
    methods (Test, ParameterCombination = 'pairwise')
        function testRepeatable(testCase,dim1,dim2,dim3)
            state = rng;
            firstRun = rand(dim1,dim2,dim3);
            rng(state)
            secondRun = rand(dim1,dim2,dim3);
            testCase.verifyEqual(firstRun,secondRun)
        end
    end
    
    methods (Test)
        function testClass(testCase,dim1,dim2,type)
            testCase.verifyClass(rand(dim1,dim2,type),type)
        end
    end
end

メソッドは rand からの出力のクラスが予期されたクラスと等しいことを検証します。与えられた TestClassSetupTestMethodSetup のパラメーター化について、フレームワークは dim1dim2 および type のパラメーター値の個々の組み合わせを確実にテストするように、testClass メソッドを 3×3×2 = 18 回呼び出します。

テスト クラスからのスイートの作成

コマンド プロンプトで、TestRand クラスからスイートを作成します。

suite = matlab.unittest.TestSuite.fromClass(?TestRand)
suite = 

  1×279 Test array with properties:

    Name
    ProcedureName
    TestClass
    BaseFolder
    Parameterization
    SharedTestFixtures
    Tags

Tests Include:
   17 Unique Parameterizations, 0 Shared Test Fixture Classes, 0 Tags.

与えられた TestClassSetupTestMethodSetup のパラメーター化について、フレームワークは 3+10+18 = 31 個のテスト要素を作成します。TestMethodSetup パラメーター化のそれぞれについて、これら 31 個の要素が呼び出され、TestClassSetup パラメーター化ごとに 3×31 = 93 個のテスト要素が作成されます。3 つの TestClassSetup パラメーター化があるため、スイートには合計で 3×93 = 279 個のテスト要素があります。

最初のテスト要素の名前をクエリします。

suite(1).Name
ans =

    'TestRand[generator=twister]/[seed=0]testClass(dim1=small,dim2=small,type=single)'

最初の要素の名前は以下の部分で構成されます。

  • テスト クラス: TestRand

  • クラス セットアップ プロパティとパラメーター名: [generator=twister]

  • メソッド セットアップ プロパティとパラメーター名: [seed=0]

  • テスト メソッド名: testClass

  • テスト メソッド プロパティとパラメーター名: (dim1=small,dim2=small,type=single)

セレクターを使用して作成したスイートの実行

コマンド プロンプトで、'twister' 発生器の 'single' 精度をテストするテスト要素を選択するためのセレクターを作成します。パラメーター名 'large' をもつプロパティを使用するテスト要素を除外して、スイートを作成します。

import matlab.unittest.selectors.HasParameter
s = HasParameter('Property','generator','Name','twister') & ...
    HasParameter('Property','type','Name','single') & ...
    ~HasParameter('Name','large');

suite2 = matlab.unittest.TestSuite.fromClass(?TestRand,s)
suite2 = 

  1×12 Test array with properties:

    Name
    ProcedureName
    TestClass
    BaseFolder
    Parameterization
    SharedTestFixtures
    Tags

Tests Include:
   9 Unique Parameterizations, 0 Shared Test Fixture Classes, 0 Tags.

まず TestRand クラスからスイート全体を生成する場合は、selectIf メソッドを使用して、フィルター処理された同じスイートを作成できます。

suite = matlab.unittest.TestSuite.fromClass(?TestRand);
suite2 = selectIf(suite,s);

フィルター処理されたテスト スイートを実行します。

suite2.run;
Running TestRand
.......... ..
Done TestRand
__________

セレクターを使用してスイートをメソッドから実行

パラメーター名 'large' または 'medium' をもつプロパティを使用するテスト要素を除外するセレクターを作成します。結果を testRepeatable メソッドからのテスト要素に制限します。

import matlab.unittest.selectors.HasParameter
s = ~(HasParameter('Name','large') | HasParameter('Name','medium'));

suite3 = matlab.unittest.TestSuite.fromMethod(?TestRand,'testRepeatable',s);
{suite3.Name}'
ans =

  9×1 cell array

    {'TestRand[generator=twister]/[seed=0]testRepeatable(dim1=small,dim2=small,dim3=small)'               }
    {'TestRand[generator=twister]/[seed=123]testRepeatable(dim1=small,dim2=small,dim3=small)'             }
    {'TestRand[generator=twister]/[seed=4294967295]testRepeatable(dim1=small,dim2=small,dim3=small)'      }
    {'TestRand[generator=combRecursive]/[seed=0]testRepeatable(dim1=small,dim2=small,dim3=small)'         }
    {'TestRand[generator=combRecursive]/[seed=123]testRepeatable(dim1=small,dim2=small,dim3=small)'       }
    {'TestRand[generator=combRecursive]/[seed=4294967295]testRepeatable(dim1=small,dim2=small,dim3=small)'}
    {'TestRand[generator=multFibonacci]/[seed=0]testRepeatable(dim1=small,dim2=small,dim3=small)'         }
    {'TestRand[generator=multFibonacci]/[seed=123]testRepeatable(dim1=small,dim2=small,dim3=small)'       }
    {'TestRand[generator=multFibonacci]/[seed=4294967295]testRepeatable(dim1=small,dim2=small,dim3=small)'}

テスト スイートを実行します。

suite3.run;
Running TestRand
.........
Done TestRand
__________

すべての倍精度テストの実行

コマンド プロンプトで、TestRand クラスからパラメーター名 'double' を使用するテスト要素をすべて実行します。

runtests('TestRand','ParameterName','double');
Running TestRand
.......... .......... .......... .......... ..........
.......... .......... .......... .
Done TestRand
__________

参考

| |

関連するトピック