Generate Code Coverage Report in HTML Format
When you generate an HTML code coverage report using the CoverageReport
class, the report displays coverage metrics that let you
perform a detailed analysis of the source code covered by your tests. This topic
provides an overview of the supported types of code coverage, as well as an example
of how to generate and analyze a coverage report.
Statement Coverage for MATLAB Source Code
Statement coverage identifies the source code statements that are executed when the tests run. Use this type of coverage to see whether every statement in your source code is executed at least once.
To report statement coverage metrics, MATLAB® divides the source code into statements that are separated by a comma, semicolon, or newline character. For example, this code has three statements that are terminated by a comma, semicolon, and newline character, respectively.
b = 1, a = 2 * (b + 10); x = (b ~= 0) && (a/b > 18.5)
MATLAB divides control flow statements into smaller units for code coverage
reporting. For example, MATLAB reports coverage for five units in the following code: if x >
0
, elseif x < 0
, and three calls to the
disp
function. To achieve 100% statement coverage, you need
tests that execute each unit.
if x > 0 disp("x is positive.") elseif x < 0 disp("x is negative.") else disp("x is either zero or NaN.") end
A keyword followed by an expression forms a unit for which MATLAB reports coverage. Among keywords that do not require an expression,
MATLAB reports coverage for break
,
catch
, continue
,
return
, and try
,
and ignores keywords such as else
,
end
, and
otherwise
.
In general, MATLAB reports coverage for statements that perform some action on program
data or affect the flow of the program. It ignores code that defines functions,
classes, or class members (such as function [y1,...,yN] =
myfun(x1,...,xM)
or classdef MyClass
).
Function Coverage for MATLAB Source Code
Function coverage identifies the functions defined in the source code that are executed when the tests run. Use this type of coverage to see whether every function in your source code is called at least once.
For example, the following code contains three defined functions:
f
, root
, and square
. To
achieve 100% function coverage, you need tests that result in each of these
functions being called.
function f(x) if x >= 0 root else square end disp(x) function root x = sqrt(x); end function square x = x.^2; end end
Generate and Analyze HTML Coverage Report
This example shows how to generate and analyze an HTML code
coverage report for the QuadraticPolynomial
class definition
file. The class represents quadratic polynomials. Its constructor first
validates that the coefficients of the polynomial are numeric values and then
uses those values to initialize the class properties. The class includes the
solve
method to return the roots of the specified
quadratic polynomial, and the plot
method to plot the
polynomial around its axis of symmetry. To view the complete code for
QuadraticPolynomial
, see QuadraticPolynomial Class Definition.
In your current folder, save the QuadraticPolynomial
class definition in a file named QuadraticPolynomial.m
.
Then, create the QuadraticPolynomialTest
test class in
your current folder. Add two Test
methods to the class
that test the solve
method against real and imaginary
solutions.
classdef QuadraticPolynomialTest < 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
At the command prompt, create a test suite from the
QuadraticPolynomialTest
class.
suite = testsuite("QuadraticPolynomialTest");
Create a test runner with a plugin that outputs an HTML code coverage
report for the source code in the file
QuadraticPolynomial.m
.
import matlab.unittest.plugins.CodeCoveragePlugin runner = testrunner("textoutput"); runner.addPlugin(CodeCoveragePlugin.forFile("QuadraticPolynomial.m"))
Run the tests. The plugin generates a code coverage report in a temporary folder.
results = runner.run(suite);
Running QuadraticPolynomialTest .. Done QuadraticPolynomialTest __________ Code coverage report has been saved to: C:\TEMP\tp16c9a437_b675_4739_a5de_338f0063ddb5\index.html
Open the report, which displays statement and function coverage metrics,
and uses different colors to highlight the executed or missed statements and
functions. In this example, the function coverage is 75% because the tests
miss one of the four methods in the class (plot
).
Additionally, the statement coverage is low because the tests miss the code
that throws an error and the code within the plot
method.
You can achieve 100% statement and function coverage by adding a
Test
method that tests against nonnumeric inputs and
another Test
method that tests properties of a plotted
polynomial.
classdef QuadraticPolynomialTest < 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 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
QuadraticPolynomial Class Definition
This code provides the complete contents of the
QuadraticPolynomial
class.
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
See Also
matlab.unittest.plugins.CodeCoveragePlugin
| matlab.unittest.plugins.codecoverage.CoverageReport
| matlab.unittest.plugins.codecoverage.CoberturaFormat