Main Content

matlabtest.selectors.DependsOn Class

Namespace: matlabtest.selectors

Select TestSuite array elements by source code dependency

Since R2023a

Description

The matlabtest.selectors.DependsOn class provides a selector for filtering a test suite based on the source code that tests depend on.

Creation

Description

selector = matlabtest.selectors.DependsOn(sources) creates a selector that selects TestSuite array elements whose test files depend on the specified source code.

example

selector = matlabtest.selectors.DependsOn(sources,Name=Value) specifies options using one or more name-value arguments. For example, selector = matlabtest.selectors.DependsOn(pwd,IncludingSubfolders=true) creates a selector that selects tests that depend on the source code in the current folder and its subfolders.

example

Input Arguments

expand all

Names of source files and folders, specified as a string vector, character vector, or cell vector of character vectors. You can specify paths relative to the current folder or full paths. If sources includes folders, the selector extracts the paths to the files in the folders.

The selector throws an error for these conditions:

  • You explicitly specify a missing file or folder in sources.

  • sources does not resolve to an existing file.

This argument sets the Sources property.

Example: pwd

Example: ["myFile.m" "myFolder"]

Example: ["folderA" "C:\work\folderB"]

Name-Value Arguments

Specify optional pairs of arguments as Name1=Value1,...,NameN=ValueN, where Name is the argument name and Value is the corresponding value. Name-value arguments must appear after other arguments, but the order of the pairs does not matter.

Example: selector = matlabtest.selectors.DependsOn(pwd,IncludingSubfolders=true)

Whether to include source code in the subfolders of sources, specified as a numeric or logical 0 (false) or 1 (true). By default, the selector ignores the source code defined in the subfolders of the folder specified in sources.

Maximum search depth for dependency analysis, specified as a positive integer scalar. The depth of a dependency is a measure of how directly a test depends on a source file. A file that is directly used by a test has a depth of one. A file directly used by such a file has a depth of two, and so on. By default, the selector considers all direct and transitive dependencies.

This argument sets the MaxDepth property.

Data Types: double | single | int8 | int16 | int32 | int64 | uint8 | uint16 | uint32 | uint64

Properties

expand all

Full paths to the source files that tests must depend on to be included in the filtered test suite, returned as a string column vector.

This property is set by the sources input argument. The property contains the full paths to the source files specified by sources.

Attributes:

GetAccess
public
SetAccess
immutable

Maximum search depth for dependency analysis, returned as a positive double scalar. By default, the selector considers all the direct and transitive dependencies.

This property is set by the MaxDepth name-value argument.

Attributes:

GetAccess
public
SetAccess
immutable

Examples

collapse all

Create filtered test suites by selecting tests using the DependsOn class.

Open the example to access the required files and folders. When you open the example, the tests subfolder of your current folder contains tests defined in the BankAccountTest.m and DocPolynomTest.m files. The source subfolder contains the source code required by the tests.

BankAccountTest Class Definition

This code shows the contents of the BankAccountTest class definition file, which uses a shared fixture to access the folder that defines the BankAccount class. For more information about the BankAccount class and to view the class code, see Developing Classes That Work Together.

classdef (SharedTestFixtures={ ...
        matlab.unittest.fixtures.PathFixture( ...
        fullfile("..","source"))}) ...
        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 uses a shared fixture to access the folder that defines the DocPolynom class. For more information about the DocPolynom class and to view the class code, see Representing Polynomials with Classes.

classdef (SharedTestFixtures={ ...
        matlab.unittest.fixtures.PathFixture( ...
        fullfile("..","source"))}) ...
        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

Create Test Suites

First, import the DependsOn class and add the source folder to the path.

import matlabtest.selectors.DependsOn
addpath("source")

Create a test suite from the tests subfolder of your current folder. Then, display the names of the TestSuite array elements. The test suite contains five tests from the BankAccountTest class and three tests from the DocPolynomTest class.

suite = testsuite("tests");
disp({suite.Name}')
    {'BankAccountTest/testConstructor'               }
    {'BankAccountTest/testConstructorNotEnoughInputs'}
    {'BankAccountTest/testDeposit'                   }
    {'BankAccountTest/testWithdraw'                  }
    {'BankAccountTest/testNotifyInsufficientFunds'   }
    {'DocPolynomTest/testConstructor'                }
    {'DocPolynomTest/testAddition'                   }
    {'DocPolynomTest/testMultiplication'             }

Select all the tests that depend on the DocPolynom class definition file. The filtered test suite contains the tests from the DocPolynomTest class because only these tests depend on the specified source code.

suite1 = suite.selectIf(DependsOn("source\DocPolynom.m"));
disp({suite1.Name}')
    {'DocPolynomTest/testConstructor'   }
    {'DocPolynomTest/testAddition'      }
    {'DocPolynomTest/testMultiplication'}

Select all the tests that do not depend on the DocPolynom class definition file. The filtered test suite contains the tests from the BankAccountTest class.

suite2 = suite.selectIf(~DependsOn("source\DocPolynom.m"));
disp({suite2.Name}')
    {'BankAccountTest/testConstructor'               }
    {'BankAccountTest/testConstructorNotEnoughInputs'}
    {'BankAccountTest/testDeposit'                   }
    {'BankAccountTest/testWithdraw'                  }
    {'BankAccountTest/testNotifyInsufficientFunds'   }

Select all the tests that depend on the current folder and any of its subfolders. The resulting test suite contains all the tests in the original test suite.

suite3 = suite.selectIf(DependsOn(pwd,IncludingSubfolders=true));
disp({suite3.Name}')
    {'BankAccountTest/testConstructor'               }
    {'BankAccountTest/testConstructorNotEnoughInputs'}
    {'BankAccountTest/testDeposit'                   }
    {'BankAccountTest/testWithdraw'                  }
    {'BankAccountTest/testNotifyInsufficientFunds'   }
    {'DocPolynomTest/testConstructor'                }
    {'DocPolynomTest/testAddition'                   }
    {'DocPolynomTest/testMultiplication'             }

Create a filtered test suite by selecting tests in a project that depend on the modified files in the project.

First, import the classes used in this example.

import matlab.unittest.TestSuite
import matlabtest.selectors.DependsOn

This example assumes that a project exists in the folder C:\work\myProject. Open the project and return the modified files in the project.

proj = openProject("C:\work\myProject");
modifiedFiles = listModifiedFiles(proj);

Create an array containing the names of the modified files.

sources = [modifiedFiles.Path];

Create a test suite from the test files in the project with the Test label. Then, create a filtered test suite that contains only the tests whose test files depend on the modified files.

suite = TestSuite.fromProject(proj);
filteredSuite = TestSuite.empty;
if ~isempty(sources)
    filteredSuite = suite.selectIf(DependsOn(sources));
end

Version History

Introduced in R2023a

expand all