Main Content

本页翻译不是最新的。点击此处可查看最新英文版本。

matlab.unittest.plugins.CodeCoveragePlugin 类

命名空间: matlab.unittest.plugins

提供对代码覆盖率信息的访问的插件

描述

要收集和访问 MATLAB® 源代码的代码覆盖率信息,请将 matlab.unittest.plugins.CodeCoveragePlugin 类的实例添加到测试运行器中。当测试套件运行时,插件将收集信息,这些信息显示测试执行的源代码的对应部分。您可以通过编程方式或代码覆盖率报告来访问这些信息。

matlab.unittest.plugins.CodeCoveragePlugin 类是一个 handle 类。

创建对象

使用以下静态方法之一创建 CodeCoveragePlugin 实例:

  • 要创建一个插件来提供对文件中源代码的代码覆盖率信息的访问,请使用 forFile 静态方法。

  • 要创建一个插件来提供对文件夹中源代码的代码覆盖率信息的访问,请使用 forFolder 静态方法。

  • 要创建一个插件来提供对包中源代码的代码覆盖率信息的访问,请使用 forPackage 静态方法。

属性

全部展开

要收集的覆盖率度量的最高级别,以下表中的值形式之一返回。默认情况下,插件会收集语句和函数覆盖率度量。

MetricLevel 的值包括的覆盖率类型
"statement"语句和函数覆盖率

"decision"(需要 MATLAB Test™

语句、函数和决策覆盖率

"condition"(需要 MATLAB Test

语句、函数、决策和条件覆盖率

"mcdc"(需要 MATLAB Test

语句、函数、决策、条件和修正条件/决策覆盖率 (MC/DC)

要设置此属性,请在使用 CodeCoveragePlugin 类的静态方法之一创建插件时指定 MetricLevel 名称-值参数。有关覆盖率类型的详细信息,请参阅Types of Code Coverage for MATLAB Source Code (MATLAB Test)

属性:

GetAccess
public
SetAccess
immutable

方法

全部展开

示例

全部折叠

运行一套测试,并为您的源代码生成 HTML 格式的代码覆盖率报告。

在当前文件夹内名为 sourceFolder 的文件夹中,创建 quadraticSolver 函数。该函数接受二次多项式的系数作为输入,并返回该多项式的根。如果系数指定为非数值,该函数将引发错误。

function roots = quadraticSolver(a,b,c)
% quadraticSolver returns solutions to the
% quadratic equation a*x^2 + b*x + c = 0.

if ~isa(a,"numeric") || ~isa(b,"numeric") || ~isa(c,"numeric")
    error("quadraticSolver:InputMustBeNumeric", ...
        "Coefficients must be numeric.")
end

roots(1) = (-b + sqrt(b^2 - 4*a*c)) / (2*a);
roots(2) = (-b - sqrt(b^2 - 4*a*c)) / (2*a);

end

要测试 quadraticSolver 函数,请在当前文件夹内名为 testsFolder 的文件夹中创建 SolverTest 类。针对实数解、虚数解和非数值输入定义三个 Test 方法来测试该函数。

classdef SolverTest < matlab.unittest.TestCase
    methods(Test)
        function realSolution(testCase)
            actSolution = quadraticSolver(1,-3,2);
            expSolution = [2 1];
            testCase.verifyEqual(actSolution,expSolution)
        end
        function imaginarySolution(testCase)
            actSolution = quadraticSolver(1,2,10);
            expSolution = [-1+3i -1-3i];
            testCase.verifyEqual(actSolution,expSolution)
        end
        function nonnumericInput(testCase)
            testCase.verifyError(@()quadraticSolver(1,"-3",2), ...
                "quadraticSolver:InputMustBeNumeric")
        end
    end
end

要运行测试并生成代码覆盖率报告,请首先将 sourceFolder 添加到路径中。

addpath("sourceFolder")

testsFolder 创建一个测试套件。

suite = testsuite("testsFolder");

创建一个测试运行器,并使用插件对其进行自定义,该插件为 sourceFolder 中的代码生成 HTML 代码覆盖率报告。指定插件将其输出写入当前文件夹中名为 coverageReport 的文件夹中。

import matlab.unittest.plugins.CodeCoveragePlugin
import matlab.unittest.plugins.codecoverage.CoverageReport
runner = testrunner("textoutput");
sourceCodeFolder = "sourceFolder";
reportFolder = "coverageReport";
reportFormat = CoverageReport(reportFolder);
p = CodeCoveragePlugin.forFolder(sourceCodeFolder,"Producing",reportFormat);
runner.addPlugin(p)

运行测试。在此示例中,所有测试都通过,源代码实现了完全覆盖。该插件在您当前文件夹中创建的指定文件夹 coverageReport 中生成一个 HTML 代码覆盖率报告。默认情况下,报告的主文件是 index.html

results = runner.run(suite);
Running SolverTest
...
Done SolverTest
__________

MATLAB code coverage report has been saved to:
 C:\work\coverageReport\index.html

打开报告的主文件。

open(fullfile("coverageReport","index.html"))

运行一套测试,并为您的源代码生成 Cobertura XML 格式的代码覆盖率报告。

在当前文件夹的一个文件中创建 quadraticSolver 函数。该函数接受二次多项式的系数作为输入,并返回该多项式的根。如果系数指定为非数值,该函数将引发错误。

function roots = quadraticSolver(a,b,c)
% quadraticSolver returns solutions to the
% quadratic equation a*x^2 + b*x + c = 0.

if ~isa(a,"numeric") || ~isa(b,"numeric") || ~isa(c,"numeric")
    error("quadraticSolver:InputMustBeNumeric", ...
        "Coefficients must be numeric.")
end

roots(1) = (-b + sqrt(b^2 - 4*a*c)) / (2*a);
roots(2) = (-b - sqrt(b^2 - 4*a*c)) / (2*a);

end

要测试 quadraticSolver 函数,请在当前文件夹中创建 SolverTest 类。针对实数解、虚数解和非数值输入定义三个 Test 方法来测试该函数。

classdef SolverTest < matlab.unittest.TestCase
    methods(Test)
        function realSolution(testCase)
            actSolution = quadraticSolver(1,-3,2);
            expSolution = [2 1];
            testCase.verifyEqual(actSolution,expSolution)
        end
        function imaginarySolution(testCase)
            actSolution = quadraticSolver(1,2,10);
            expSolution = [-1+3i -1-3i];
            testCase.verifyEqual(actSolution,expSolution)
        end
        function nonnumericInput(testCase)
            testCase.verifyError(@()quadraticSolver(1,"-3",2), ...
                "quadraticSolver:InputMustBeNumeric")
        end
    end
end

根据 SolverTest 类创建一个测试套件。

suite = testsuite("SolverTest");

创建一个测试运行器,并使用插件对其进行自定义,该插件为文件 quadraticSolver.m 中的源代码生成 Cobertura XML 代码覆盖率报告。指定插件将其输出写入当前文件夹中名为 coverageReport.xml 的文件。

import matlab.unittest.plugins.CodeCoveragePlugin
import matlab.unittest.plugins.codecoverage.CoberturaFormat
runner = testrunner("textoutput");
sourceCodeFile = "quadraticSolver.m";
reportFile = "coverageReport.xml";
reportFormat = CoberturaFormat(reportFile);
p = CodeCoveragePlugin.forFile(sourceCodeFile,"Producing",reportFormat);
runner.addPlugin(p)

运行测试。在此示例中,所有测试都通过,源代码实现了完全覆盖。该插件在您的当前文件夹中生成一个 Cobertura XML 代码覆盖率报告。

results = runner.run(suite);
Running SolverTest
...
Done SolverTest
__________

您可以在持续集成 (CI) 平台上处理生成的代码覆盖率报告。您还可以使用 open(reportFile)disp(fileread(reportFile)) 等命令查看其内容。

运行一套测试并收集代码覆盖率结果。然后,从结果中检索关于语句覆盖率的信息。

在当前文件夹内一个名为 quadraticSolver.m 的文件中创建 quadraticSolver 函数。该函数接受二次多项式的系数作为输入,并返回该多项式的根。如果系数指定为非数值,该函数将引发错误。

function roots = quadraticSolver(a,b,c)
% quadraticSolver returns solutions to the
% quadratic equation a*x^2 + b*x + c = 0.

if ~isa(a,"numeric") || ~isa(b,"numeric") || ~isa(c,"numeric")
    error("quadraticSolver:InputMustBeNumeric", ...
        "Coefficients must be numeric.")
end

roots(1) = (-b + sqrt(b^2 - 4*a*c)) / (2*a);
roots(2) = (-b - sqrt(b^2 - 4*a*c)) / (2*a);

end

要测试 quadraticSolver 函数,请在当前文件夹内名为 SolverTest.m 的文件中创建 SolverTest 类。针对实数解、虚数解和非数值输入定义三个 Test 方法来测试该函数。

classdef SolverTest < matlab.unittest.TestCase
    methods (Test)
        function realSolution(testCase)
            actSolution = quadraticSolver(1,-3,2);
            expSolution = [2 1];
            testCase.verifyEqual(actSolution,expSolution)
        end
        function imaginarySolution(testCase)
            actSolution = quadraticSolver(1,2,10);
            expSolution = [-1+3i -1-3i];
            testCase.verifyEqual(actSolution,expSolution)
        end
        function nonnumericInput(testCase)
            testCase.verifyError(@()quadraticSolver(1,"-3",2), ...
                "quadraticSolver:InputMustBeNumeric")
        end
    end
end

导入此示例中使用的类。

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

根据 SolverTest 类创建一个测试套件。

suite = testsuite("SolverTest");

创建一个测试运行器并使用一个插件对其进行自定义,该插件提供对文件 quadraticSolver.m 中源代码的代码覆盖率信息的编程访问。

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

运行测试。在测试运行后,formatResult 属性会保留覆盖率结果。在此示例中,所有测试都通过。

runner.run(suite);
Running SolverTest
...
Done SolverTest
__________

访问语句覆盖率摘要。返回的向量表明测试执行了源代码中的所有四个语句。

result = format.Result;
summary = coverageSummary(result,"statement")
summary = 1×2

     4     4

使用代码覆盖率分析的描述来检索每个语句的执行计数。

[~,description] = coverageSummary(result,"statement")
description = struct with fields:
    statement: [1×4 struct]

disp([description.statement.ExecutionCount])
   3   1   2   2

为了收集代码覆盖率信息,您可以向单个测试运行器添加多个插件。例如,您可以添加一个插件来收集当前文件夹中 MATLAB 代码的覆盖率结果,并添加另一个插件来收集当前文件夹中 C/C++ 生成代码的结果。如果您以这种方式自定义测试运行器,则必须为每个插件指定不同的覆盖率格式,以便各插件独立地执行其分析。

此示例说明如何向测试运行器添加两个插件,以便每个插件收集不同文件的代码覆盖率信息。在运行测试后,通过合并两个覆盖率结果来生成一个代码覆盖率报告。打开此示例以访问所需的测试和源文件。当您打开示例时,您的当前文件夹包含在 BankAccountTest.mDocPolynomTest.m 文件中定义的测试。您的当前文件夹还包含测试所需的源文件。

openExample("matlab/GenerateCodeCoverageReportUsingPluginsExample")

BankAccountTest 类定义

以下代码显示 BankAccountTest 类定义文件的内容,此文件定义 BankAccount 类的测试。有关 BankAccount 类的详细信息以及查看类代码,请参阅开发协同工作的类

classdef BankAccountTest < matlab.unittest.TestCase
    methods (Test)
        function testConstructor(testCase)
            b = BankAccount(1234,100);
            testCase.verifyEqual(b.AccountNumber,1234, ...
                "Constructor must correctly set account number.")
            testCase.verifyEqual(b.AccountBalance,100, ...
                "Constructor must correctly set account balance.")
        end

        function testConstructorNotEnoughInputs(testCase)
            import matlab.unittest.constraints.Throws
            testCase.verifyThat(@()BankAccount,Throws("MATLAB:minrhs"))
        end

        function testDeposit(testCase)
            b = BankAccount(1234,100);
            b.deposit(25)
            testCase.verifyEqual(b.AccountBalance,125)
        end

        function testWithdraw(testCase)
            b = BankAccount(1234,100);
            b.withdraw(25)
            testCase.verifyEqual(b.AccountBalance,75)
        end

        function testNotifyInsufficientFunds(testCase)
            callbackExecuted = false;
            function testCallback(~,~)
                callbackExecuted = true;
            end

            b = BankAccount(1234,100);
            b.addlistener("InsufficientFunds",@testCallback);

            b.withdraw(50)
            testCase.assertFalse(callbackExecuted, ...
                "The callback should not have executed yet.")
            b.withdraw(60)
            testCase.verifyTrue(callbackExecuted, ...
                "The listener callback should have fired.")
        end
    end
end

DocPolynomTest 类定义

以下代码显示 DocPolynomTest 类定义文件的内容,此文件定义 DocPolynom 类的测试。有关 DocPolynom 类的详细信息以及查看类代码,请参阅Representing Polynomials with Classes

classdef DocPolynomTest < matlab.unittest.TestCase
    properties
        TextToDisplay = "Equation under test: "
    end

    methods (Test)
        function testConstructor(testCase)
            p = DocPolynom([1 0 1]);
            testCase.verifyClass(p,?DocPolynom)
        end

        function testAddition(testCase)
            p1 = DocPolynom([1 0 1]);
            p2 = DocPolynom([5 2]);
            actual = p1 + p2;
            expected = DocPolynom([1 5 3]);
            diagnostic = [testCase.TextToDisplay ...
                "(x^2 + 1) + (5*x + 2) = x^2 + 5*x + 3"];
            testCase.verifyEqual(actual,expected,diagnostic)
        end

        function testMultiplication(testCase)
            p1 = DocPolynom([1 0 3]);
            p2 = DocPolynom([5 2]);
            actual = p1 * p2;
            expected = DocPolynom([5 2 15 6]);
            diagnostic = [testCase.TextToDisplay ...
                "(x^2 + 3) * (5*x + 2) = 5*x^3 + 2*x^2 + 15*x + 6"];
            testCase.verifyEqual(actual,expected,diagnostic)
        end
    end
end

运行测试并生成代码覆盖率报告

导入此示例中使用的类。

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

创建一个为文本输出配置的测试运行器。

runner = testrunner("textoutput");

向测试运行器添加一个插件,该插件提供对文件 BankAccount.m 中源代码的代码覆盖率信息的编程访问。

format1 = CoverageResult;
plugin1 = CodeCoveragePlugin.forFile("BankAccount.m",Producing=format1);
runner.addPlugin(plugin1)

向测试运行器添加另一个插件,该插件提供对文件 DocPolynom.m 中源代码的代码覆盖率信息的编程访问。

format2 = CoverageResult;
plugin2 = CodeCoveragePlugin.forFile("DocPolynom.m",Producing=format2);
runner.addPlugin(plugin2)

BankAccountTestDocPolynomTest 测试类创建一个测试套件,并运行测试。在此示例中,所有测试都通过。

suite = testsuite(["BankAccountTest" "DocPolynomTest"]);
runner.run(suite);
Running BankAccountTest
.....
Done BankAccountTest
__________

Running DocPolynomTest
...
Done DocPolynomTest
__________

在测试运行后,格式对象的 Result 属性保留由对应插件收集的覆盖率结果。要报告测试运行的总聚合覆盖率,请基于覆盖率结果的并集生成一个 HTML 代码覆盖率报告。

result1 = format1.Result;
result2 = format2.Result;
generateHTMLReport(result1 + result2)

详细信息

全部展开

版本历史记录

在 R2014b 中推出

全部展开