matlab.unittest.plugins.CodeCoveragePlugin - Plugin that provides access to code coverage information - MATLAB (original) (raw)

Namespace: matlab.unittest.plugins

Plugin that provides access to code coverage information

Description

To collect and access code coverage information for MATLAB® source code, add an instance of the matlab.unittest.plugins.CodeCoveragePlugin class to the test runner. As the test suite runs, the plugin collects information that shows the parts of the source code that were executed by the tests. You can access this information either programmatically or as a code coverage report.

The matlab.unittest.plugins.CodeCoveragePlugin class is a handle class.

Creation

Create a CodeCoveragePlugin instance using one of its static methods:

Properties

expand all

Level of coverage metrics to collect, returned as one of the values in this table. By default, the plugin collects statement and function coverage metrics.

Value of MetricLevel Types of Coverage Included
"statement" Statement and function coverage
"decision" (requires MATLAB Test™) Statement, function, and decision coverage
"condition" (requires MATLAB Test) Statement, function, decision, and condition coverage
"mcdc" (requires MATLAB Test) Statement, function, decision, condition, and modified condition/decision coverage (MC/DC)

To set this property, specify the MetricLevel name-value argument when you create a plugin using one of the static methods of theCodeCoveragePlugin class. For more information about coverage types, see Types of Code Coverage for MATLAB Source Code (MATLAB Test).

Attributes:

GetAccess public
SetAccess immutable

Methods

Examples

collapse all

Run a suite of tests and generate an interactive code coverage report in HTML format for your source code.

In a folder named sourceFolder in your current folder, create the quadraticSolver function. The function takes as inputs the coefficients of a quadratic polynomial and returns the roots of that polynomial. If the coefficients are specified as nonnumeric values, the function throws an error.

function r = quadraticSolver(a,b,c) % quadraticSolver returns solutions to the % quadratic equation ax^2 + bx + c = 0.

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

r(1) = (-b + sqrt(b^2 - 4ac)) / (2a); r(2) = (-b - sqrt(b^2 - 4ac)) / (2a);

end

To test the quadraticSolver function, create the SolverTest class in a folder named testsFolder in your current folder. Define three Test methods that test the function against real solutions, imaginary solutions, and nonnumeric inputs.

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

To run the tests and generate a code coverage report, first add sourceFolder to the path.

Create a test suite from testsFolder.

suite = testsuite("testsFolder");

Create a test runner and customize it using a plugin that generates an interactive code coverage report for the code in sourceFolder. Specify that the plugin writes its output to a folder named coverageReport in your current folder.

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

Run the tests. In this example, all the tests pass and the source code receives full coverage. The plugin generates an interactive code coverage report in the specified folder coverageReport, created in your current folder. By default, the main file of the report is index.html.

results = runner.run(suite);

Running SolverTest ... Done SolverTest


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

Open the main file of the report.

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

Run a suite of tests and generate a code coverage report in Cobertura XML format for your source code.

In a file in your current folder, create the quadraticSolver function. The function takes as inputs the coefficients of a quadratic polynomial and returns the roots of that polynomial. If the coefficients are specified as nonnumeric values, the function throws an error.

function r = quadraticSolver(a,b,c) % quadraticSolver returns solutions to the % quadratic equation ax^2 + bx + c = 0.

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

r(1) = (-b + sqrt(b^2 - 4ac)) / (2a); r(2) = (-b - sqrt(b^2 - 4ac)) / (2a);

end

To test the quadraticSolver function, create the SolverTest class in your current folder. Define three Test methods that test the function against real solutions, imaginary solutions, and nonnumeric inputs.

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

Create a test suite from the SolverTest class.

suite = testsuite("SolverTest");

Create a test runner and customize it using a plugin that generates a Cobertura XML code coverage report for the source code in the file quadraticSolver.m. Specify that the plugin writes its output to a file named coverageReport.xml in your current folder.

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)

Run the tests. In this example, all the tests pass and the source code receives full coverage. The plugin generates a Cobertura XML code coverage report in your current folder.

results = runner.run(suite);

Running SolverTest ... Done SolverTest


You can process the generated code coverage report on continuous integration (CI) platforms. You also can view its contents with commands such as open(reportFile) or disp(fileread(reportFile)).

Run a suite of tests and collect the code coverage result. Then, retrieve information about statement coverage from the result.

In a file named quadraticSolver.m in your current folder, create the quadraticSolver function. The function takes as inputs the coefficients of a quadratic polynomial and returns the roots of that polynomial. If the coefficients are specified as nonnumeric values, the function throws an error.

function r = quadraticSolver(a,b,c) % quadraticSolver returns solutions to the % quadratic equation ax^2 + bx + c = 0.

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

r(1) = (-b + sqrt(b^2 - 4ac)) / (2a); r(2) = (-b - sqrt(b^2 - 4ac)) / (2a);

end

To test the quadraticSolver function, create the SolverTest class in a file named SolverTest.m in your current folder. Define three Test methods that test the function against real solutions, imaginary solutions, and nonnumeric inputs.

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 the classes used in this example.

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

Create a test suite from the SolverTest class.

suite = testsuite("SolverTest");

Create a test runner and customize it using a plugin that provides programmatic access to the code coverage information for the source code in the file quadraticSolver.m.

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

Run the tests. After the test run, the Result property of format holds the coverage result. In this example, all the tests pass.

Running SolverTest ... Done SolverTest


Access the statement coverage summary. The returned vector indicates that all four statements in the source code were executed by the tests.

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

Use the description of the code coverage analysis to retrieve the execution count for each statement.

[~,description] = coverageSummary(result,"statement")

description = struct with fields: statement: [1×4 struct]

disp([description.statement.ExecutionCount])

To collect code coverage information, you can add multiple plugins to a single test runner. For example, you can add a plugin to collect coverage results for MATLAB code in your current folder and another plugin to collect results for C/C++ generated code in your current folder. If you customize the test runner this way, you must specify a distinct coverage format for each plugin so that the plugins perform their analyses independently.

This example shows how to add two plugins to the test runner so that each plugin collects code coverage information for a different file. After running the tests, generate a code coverage report by combining the two coverage results. Open this example to access the required test and source files. When you open the example, your current folder contains tests defined in the BankAccountTest.m and DocPolynomTest.m files. Your current folder also contains the source files required by the tests.

openExample("matlab/GenerateCodeCoverageReportUsingPluginsExample")

****BankAccountTest Class Definition**

This code shows the contents of the BankAccountTest class definition file, which defines tests for the BankAccount class. For more information about the BankAccount class and to view the class code, see Developing Classes That Work Together.

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 Class Definition**

This code shows the contents of the DocPolynomTest class definition file, which defines tests for the DocPolynom class. For more information about the DocPolynom class and to view the class code, see 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

Run Tests and Generate Code Coverage Report

Import the classes used in this example.

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

Create a test runner that is configured for text output.

runner = testrunner("textoutput");

Add a plugin to the test runner that provides programmatic access to the code coverage information for the source code in the file BankAccount.m.

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

Add another plugin to the test runner that provides programmatic access to the code coverage information for the source code in the file DocPolynom.m.

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

Create a test suite from the BankAccountTest and DocPolynomTest test classes and run the tests. In this example, all the tests pass.

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

Running BankAccountTest ..... Done BankAccountTest


Running DocPolynomTest ... Done DocPolynomTest


After the test run, the Result properties of the format objects hold the coverage results collected by the corresponding plugins. To report on the total aggregated coverage for the test run, generate an interactive code coverage report from the union of the coverage results.

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

More About

expand all

When you create a plugin using one of the static methods of theCodeCoveragePlugin class, the plugin collects code coverage information for source code in files with a .m, .mlx, or.mlapp extension.

Version History

Introduced in R2014b

expand all

The method matlab.unittest.plugins.CodeCoveragePlugin.forPackage is now named matlab.unittest.plugins.CodeCoveragePlugin.forNamespace. The behavior of this method remains the same, and existing instances ofmatlab.unittest.plugins.CodeCoveragePlugin.forPackage in your code continue to work as expected. There are no plans to remove support for existing references to matlab.unittest.plugins.CodeCoveragePlugin.forPackage.

To programmatically access the results of code coverage analysis for your source code, create a CodeCoveragePlugin instance using a CoverageResult object.

To support specifying the coverage metrics to collect when performing a code coverage analysis, the matlab.unittest.plugins.CodeCoveragePlugin class has a new property named MetricLevel.

You can add multiple CodeCoveragePlugin instances to the test runner. If you customize the test runner this way, each plugin must report on a different set of files. For example, run your tests and simultaneously generate interactive code coverage reports for source code in two folders in your current folder.

suite = testsuite(pwd); runner = testrunner("textoutput"); import matlab.unittest.plugins.CodeCoveragePlugin p1 = CodeCoveragePlugin.forFolder(folderA); runner.addPlugin(p1) p2 = CodeCoveragePlugin.forFolder(folderB); runner.addPlugin(p2) results = runner.run(suite);

See Also

Classes

Topics