Main Content

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

MATLAB ソース コードのステートメントおよび関数のカバレッジ メトリクスの収集

テストを実行すると、matlab.unittest.plugins.CodeCoveragePluginクラスのインスタンスをテスト ランナーに追加して、MATLAB® ソース コードのコード カバレッジ情報を収集してアクセスできます。MATLAB では、matlab.unittest.plugins.codecoverage.CoverageResultまたはmatlab.unittest.plugins.codecoverage.CoverageReport形式のオブジェクトを使用して作成されたプラグインにより、ステートメントおよび関数のカバレッジに関する情報が提供されます。ステートメントおよび関数のカバレッジの詳細については、Types of Code Coverage for MATLAB Source Codeを参照してください。

この例では、コード カバレッジ メトリクスを収集して、ファイル内のソース コードのステートメントと関数のカバレッジ情報を含むレポートを生成する方法について説明します。ファイルでは QuadraticPolynomial クラスを定義します。このクラスは 2 次多項式を表します。クラス コンストラクターは、まず多項式の係数が数値であることを確認し、次に、それらの値を使用してクラスのプロパティを初期化します。このクラスには、指定された 2 次多項式の根を返す solve メソッドと、その対称軸を中心に多項式をプロットする plot メソッドが含まれています。QuadraticPolynomial の完全なコードを確認するには、QuadraticPolynomial クラスの定義を参照してください。

コード カバレッジ情報の収集と解析

現在のフォルダーで、QuadraticPolynomial.m という名前のファイルに QuadraticPolynomial クラス定義を保存します。次に、現在のフォルダーに QuadraticPolynomialTest1 テスト クラスを作成します。クラス内の 2 つの Test メソッドにより、実数解と虚数解について solve メソッドをテストします。

classdef QuadraticPolynomialTest1 < matlab.unittest.TestCase
    methods (Test)
        function realSolution(testCase)
            p = QuadraticPolynomial(1,-3,2);
            actSolution = p.solve();
            expSolution = [1 2];
            testCase.verifyEqual(actSolution,expSolution)
        end
        function imaginarySolution(testCase)
            p = QuadraticPolynomial(1,2,10);
            actSolution = p.solve();
            expSolution = [-1-3i -1+3i];
            testCase.verifyEqual(actSolution,expSolution)
        end
    end
end

テストを実行してコード カバレッジ解析を実行するには、まずファイル QuadraticPolynomial.m 内のソース コードのステートメントおよび関数のカバレッジ情報へのプログラムによるアクセスを提供するプラグインを使用してテスト ランナーを作成します。

import matlab.unittest.plugins.CodeCoveragePlugin
import matlab.unittest.plugins.codecoverage.CoverageResult

runner = testrunner("textoutput");
format = CoverageResult;
p = CodeCoveragePlugin.forFile("QuadraticPolynomial.m",Producing=format);
addPlugin(runner,p)

QuadraticPolynomialTest1 クラスからテスト スイートを作成してテストを実行します。テストがパスします。

suite1 = testsuite("QuadraticPolynomialTest1");
run(runner,suite1);
Running QuadraticPolynomialTest1
..
Done QuadraticPolynomialTest1
__________

テストを実行すると、CoverageResult オブジェクトの Result プロパティに、カバレッジの結果が保持されます。カバレッジ結果からステートメント カバレッジの概要にアクセスします。返されるベクトルは、テストでファイル内の 17 個のステートメントのうち 8 個が実行され、ステートメント カバレッジが 47% であったことを示しています。エラーをスローするコードと plot メソッド内のコードがテストで実行されなかったため、ステートメント カバレッジは低くなっています。

result1 = format.Result;
statementSummary = coverageSummary(result1,"statement")
statementSummary = 1×2

     8    17

関数カバレッジの概要にアクセスします。概要は、テストで QuadraticPolynomial クラス内の 4 つのメソッドのうち 1 つ (plot) が実行されなかったため、関数カバレッジが 75% であることを示しています。

functionSummary = coverageSummary(result1,"function")
functionSummary = 1×2

     3     4

coverageSummary メソッドの追加の出力引数を使用して、各メソッドの実行回数を取得します。

[~,functionDescription] = coverageSummary(result1,"function")
functionDescription = struct with fields:
    function: [1×4 struct]

disp([functionDescription.function.ExecutionCount])
   2   2   0   2

コード カバレッジ レポートの生成

次に、カバレッジ結果から HTML コード カバレッジ レポートを生成します。レポートでは、ステートメントと関数のカバレッジに関する情報が、実行されたものと実行されなかったものに色分けされて表示されます。

generateHTMLReport(result1)

HTML コード カバレッジ レポートを操作できます。たとえば、[全体的なカバレッジの概要] セクションでは、[現在の表示] リストからカバレッジ タイプを選択してそのカバレッジ タイプに関する詳細情報を表示できます。次の図では、ステートメント カバレッジの [ソースの詳細] セクションが示されています。ここには、カバーされたステートメントまたは実行されなかったステートメントがすべて表示されています。

カバレッジを改善するための追加テストの実行

suite1 によって実行されなかったソース コードの部分を実行するテストを作成します。現在のフォルダーに QuadraticPolynomialTest2 という名前の別のテスト クラスを作成します。クラス内の 1 つの Test メソッドによって非数値入力についてテストし、もう 1 つの Test メソッドにより、プロットされた多項式のプロパティをテストします。

classdef QuadraticPolynomialTest2 < matlab.unittest.TestCase
    methods (Test)
        function nonnumericInput(testCase)
            testCase.verifyError(@()QuadraticPolynomial(1,"-3",2), ...
                "QuadraticPolynomial:InputMustBeNumeric")
        end
        function plotPolynomial(testCase)
            p = QuadraticPolynomial(1,-3,2);
            fig = figure;
            testCase.addTeardown(@close,fig)
            ax = axes(fig);
            p.plot(ax)
            actYLabelText = ax.YLabel.String;
            expYLabelText = '1.00x^2-3.00x+2.00';
            testCase.verifyEqual(actYLabelText,expYLabelText)
        end
    end
end

QuadraticPolynomialTest2 クラスからテスト スイートを作成してテストを実行します。テストがパスします。

suite2 = testsuite("QuadraticPolynomialTest2");
run(runner,suite2);
Running QuadraticPolynomialTest2
.
.
Done QuadraticPolynomialTest2
__________

この例では、各種テスト スイートを実行して同じソース コードを検定しました。これらのテスト実行の集計されたカバレッジの合計をレポートするには、テスト実行に対応するカバレッジの結果の結合から HTML レポートを生成します。レポートは、2 つのテスト スイートを合わせると、ソース コード内のステートメントと関数が完全に実行されたことを示しています。

result2 = format.Result;
generateHTMLReport(result1 + result2)

QuadraticPolynomial クラスの定義

以下のコードは、QuadraticPolynomial クラスの内容全体を示しています。

classdef QuadraticPolynomial
    properties
        A,B,C   % Coefficients of a*x^2 + b*x + c
    end

    methods
        function obj = QuadraticPolynomial(a,b,c)
            if ~isa(a,"numeric") || ~isa(b,"numeric") || ~isa(c,"numeric")
                error("QuadraticPolynomial:InputMustBeNumeric", ...
                    "Coefficients must be numeric.")
            else
                obj.A = a; obj.B = b; obj.C = c;
            end
        end

        function roots = solve(obj)
            % Return solutions to a*x^2 + b*x + c = 0
            delta = calculateDelta(obj);
            roots(1) = (-obj.B - sqrt(delta)) / (2*obj.A);
            roots(2) = (-obj.B + sqrt(delta)) / (2*obj.A);
        end

        function plot(obj,ax)
            % Plot a*x^2 + b*x + c around its axis of symmetry
            delta = calculateDelta(obj);
            x0 = -obj.B/(2*obj.A);
            x1 = abs(sqrt(delta))/obj.A;
            x = x0 + linspace(-x1,x1);
            y = obj.A*x.^2 + obj.B*x + obj.C;
            plot(ax,x,y)
            xlabel("x")
            ylabel(sprintf("%.2fx^2%+.2fx%+.2f",obj.A,obj.B,obj.C))
        end
    end

    methods (Access=private)
        function delta = calculateDelta(obj)
            delta = obj.B^2 - 4*obj.A*obj.C;
        end
    end
end

参考

クラス

関連するトピック