Main Content

スクリプト ベースのユニット テストの記述

次の例では、ユーザーが作成した関数をテストするスクリプトを記述する方法を説明します。このサンプル関数は直角三角形の角度を計算します。この関数をテストするためのスクリプトベースのユニット テストを作成します。

テストする関数 rightTri の作成

現在の MATLAB® フォルダーのファイル rightTri.m にこの関数を作成します。この関数は、三角形の 2 辺の長さを入力としてとり、対応する直角三角形の 3 つの角度を返します。入力する辺は三角形の短い 2 つの辺であり、斜辺ではありません。

function angles = rightTri(sides)

A = atand(sides(1)/sides(2));
B = atand(sides(2)/sides(1));
hypotenuse = sides(1)/sind(A);
C = asind(hypotenuse*sind(A)/sides(1));

angles = [A B C];

end

テスト スクリプトの作成

作業フォルダーで、新しいスクリプト rightTriTest.m を作成します。ユニット テストごとに、関数 rightTri の異なる出力をチェックします。テスト スクリプトは次の規則に従う必要があります。

  • テスト ファイル名の先頭または末尾は 'test' という語でなければなりません。この大文字小文字は区別されません。テスト ファイル名の先頭または末尾が 'test' という語でない場合、特定の状況でファイル内のテストが無視されることがあります。

  • 各ユニット テストはスクリプト ファイルの個別のセクションに配置します。各セクションの行は 2 個のパーセント記号 (%%) で始まり、同じ行のその後に続くテキストはテスト要素の名前になります。%% の後に続くテキストがない場合、MATLAB はテストに名前を割り当てます。MATLAB はテストの失敗を検出しても、残りのテストを実行します。

  • テスト スクリプトでは、共有変数セクションは最初の明示的なコード セクション (%% で始まる最初の行) の前に現れるコードで構成されます。ここで定義された変数がテストで共有されます。テスト中、これらの変数の値は変更できます。ただし、後続のテストでは、共有変数セクションで定義された値にリセットされます。

  • テストに必要な前提条件があれば共有変数セクション (最初のコード セクション) で定義します。入力または出力がこの前提条件に適合しない場合、MATLAB はいずれのテストも実行しません。MATLAB はテストを失敗および未完了としてマークします。

  • スクリプトをテストとして実行した場合、1 つのテストで定義された変数には、共有変数セクション (最初のコード セクション) で定義されている場合を除き、他のテストからアクセスすることはできません。同様に、他のワークスペースで定義された変数はテストにアクセスできません。

  • スクリプト ファイルにコード セクションが含まれていないと、MATLAB はスクリプト ファイルの内容全体から単一のテスト要素を生成します。テスト要素の名前はスクリプト ファイル名と同じです。この場合、MATLAB は失敗したテストを検出すると、スクリプト全体の実行を停止します。

rightTriTest.m で、4 つのテストを記述し、rightTri の出力をテストします。関数 assert を使用して異なる条件をテストします。共有変数セクションで、4 つの三角形の形状を定義し、関数 rightTri が直角三角形を返すという前提条件を定義します。

% test triangles
tri = [7 9];
triIso = [4 4];
tri306090 = [2 2*sqrt(3)];
triSkewed = [1 1500];

% preconditions
angles = rightTri(tri);
assert(angles(3) == 90,'Fundamental problem: rightTri not producing right triangle')

%% Test 1: sum of angles
angles = rightTri(tri);
assert(sum(angles) == 180)
 
angles = rightTri(triIso);
assert(sum(angles) == 180)
 
angles = rightTri(tri306090);
assert(sum(angles) == 180)
 
angles = rightTri(triSkewed);
assert(sum(angles) == 180)

%% Test 2: isosceles triangles
angles = rightTri(triIso);
assert(angles(1) == 45)
assert(angles(1) == angles(2))
 
%% Test 3: 30-60-90 triangle
angles = rightTri(tri306090);
assert(angles(1) == 30)
assert(angles(2) == 60)
assert(angles(3) == 90)

%% Test 4: Small angle approximation
angles = rightTri(triSkewed);
smallAngle = (pi/180)*angles(1); % radians
approx = sin(smallAngle);
assert(approx == smallAngle, 'Problem with small angle approximation')

テスト 1 では三角形の角度の合計をテストします。assert は合計が 180 度ではない場合にエラーをスローします。

テスト 2 では 2 辺が等しい場合、対応する角度が等しいことをテストします。角度が両方とも 45 度ではない場合に関数 assert はエラーをスローします。

テスト 3 では三角形の辺が 1sqrt(3) の場合、角度が 30 度、60 度および 90 度であることをテストします。この条件が true でない場合に assert はエラーをスローします。

テスト 4 では微小角の近似をテストします。この微小角近似では、微小角の場合、ラジアン単位の角度の正弦はその微小角に近似すると定義されています。この条件が true でない場合に assert はエラーをスローします。

テストの実行

関数 runtests を実行して rightTriTest.m の 4 つのテストを実行します。関数 runtests は各コード セクションの各テストを個別に実行します。テスト 1 が失敗しても、MATLAB は残りのテストを実行します。runtests を使用するのではなく、スクリプトとして rightTriTest を実行する場合、MATLAB はアサーション失敗を検出するとスクリプト全体の実行を中止します。また、関数 runtests を使用してテストを実行すると、MATLAB は参考になるテスト診断を提供します。

result = runtests('rightTriTest');
Running rightTriTest
..
================================================================================
Error occurred in rightTriTest/Test3_30_60_90Triangle and it did not run to completion.
    ---------
    Error ID:
    ---------
    'MATLAB:assertion:failed'
    --------------
    Error Details:
    --------------
    Error using rightTriTest (line 31)
    Assertion failed.
================================================================================
.
================================================================================
Error occurred in rightTriTest/Test4_SmallAngleApproximation and it did not run to completion.
    ---------
    Error ID:
    ---------
    ''
    --------------
    Error Details:
    --------------
    Error using rightTriTest (line 39)
    Problem with small angle approximation
================================================================================
.
Done rightTriTest
__________

Failure Summary:

     Name                                        Failed  Incomplete  Reason(s)
    ===========================================================================
     rightTriTest/Test3_30_60_90Triangle           X         X       Errored.
    ---------------------------------------------------------------------------
     rightTriTest/Test4_SmallAngleApproximation    X         X       Errored.

30-60-90 三角形および微小角近似のテストが浮動小数点数の比較で失敗しています。浮動小数点数を比較するときは、通常、比較の許容誤差を指定します。テスト 3 およびテスト 4 において、MATLAB は失敗したアサーションに対してエラーをスローし、テストを完了していません。したがって、テストは FailedIncomplete の両方がマークされます。

'Assertion failed' (テスト 3) よりも有用な診断情報 (Error Details) を提供するには、関数 assert にメッセージを渡すことを検討してください (テスト 4)。または、関数ベースのユニット テストを使用するようにもできます。

テストを修正して許容誤差を使用

rightTriTest.mrightTriTolTest.m という名前で保存し、テスト 3 およびテスト 4 で許容誤差を使用するよう修正します。テスト 3 およびテスト 4 において、角度が期待値と等しくなるという条件を使用をする代わりに、実際の値と期待値の差が指定された許容誤差以内であるという条件を使用します。スクリプトの共有変数セクションに許容誤差を定義し、どちらのテストからもアクセスできるようにします。

スクリプトベースのユニット テストの場合、2 つの値間の差異が、指定されている許容誤差未満であることを手動で検証します。関数ベースのユニット テストを記述する場合は、浮動小数点値を比較するときに組み込みの制約を使用して許容誤差を指定できます。

% test triangles
tri = [7 9];
triIso = [4 4];
tri306090 = [2 2*sqrt(3)];
triSkewed = [1 1500];

% Define an absolute tolerance
tol = 1e-10; 
 
% preconditions
angles = rightTri(tri);
assert(angles(3) == 90,'Fundamental problem: rightTri not producing right triangle')

%% Test 1: sum of angles
angles = rightTri(tri);
assert(sum(angles) == 180)
 
angles = rightTri(triIso);
assert(sum(angles) == 180)
 
angles = rightTri(tri306090);
assert(sum(angles) == 180)
 
angles = rightTri(triSkewed);
assert(sum(angles) == 180)

%% Test 2: isosceles triangles
angles = rightTri(triIso);
assert(angles(1) == 45)
assert(angles(1) == angles(2))
 
%% Test 3: 30-60-90 triangle
angles = rightTri(tri306090);
assert(abs(angles(1)-30) <= tol)
assert(abs(angles(2)-60) <= tol)
assert(abs(angles(3)-90) <= tol)

%% Test 4: Small angle approximation
angles = rightTri(triSkewed);
smallAngle = (pi/180)*angles(1); % radians
approx = sin(smallAngle);
assert(abs(approx-smallAngle) <= tol, 'Problem with small angle approximation')

テストを再実行します。

result = runtests('rightTriTolTest');
Running rightTriTolTest
....
Done rightTriTolTest
__________

すべてのテストがパスします。

テスト結果の表を作成します。

rt = table(result)
rt =

  4×6 table

                          Name                           Passed    Failed    Incomplete    Duration       Details   
    _________________________________________________    ______    ______    __________    _________    ____________

    {'rightTriTolTest/Test1_SumOfAngles'            }    true      false       false         0.02373    {1×1 struct}
    {'rightTriTolTest/Test2_IsoscelesTriangles'     }    true      false       false       0.0047332    {1×1 struct}
    {'rightTriTolTest/Test3_30_60_90Triangle'       }    true      false       false       0.0051982    {1×1 struct}
    {'rightTriTolTest/Test4_SmallAngleApproximation'}    true      false       false       0.0049869    {1×1 struct}

参考

|

関連するトピック