Main Content

创建高级自定义脚手架

此示例说明如何创建一个自定义的脚手架,以更改数值的输出显示格式。您可以将该脚手架应用于单个测试类,也可以在多个测试类之间共享该脚手架。在测试后,脚手架会将显示格式还原为其原始状态。

创建 NumericFormatFixture

在当前文件夹内名为 NumericFormatFixture.m 的文件中,通过从 matlab.unittest.fixtures.Fixture 接口派生创建 NumericFormatFixture 类。鉴于您要向脚手架传递数值格式,请向您的类添加 Format 属性。

    properties (SetAccess=immutable)
        Format (1,1) string
    end

添加脚手架构造函数

在类的 methods 块中,定义一个构造函数,以设置 Format 属性。

    methods
        function fixture = NumericFormatFixture(fmt)
            fixture.Format = fmt;
        end
    end

实现 setup 方法

Fixture 接口的子类必须实现 setup 方法,该方法可在测试框架设置脚手架时对环境进行更改。要在框架拆解脚手架时还原环境,您可以在 setup 方法中调用 addTeardown 方法。

methods 块中,实现 setup 方法以将数值格式更改为在脚手架构造期间指定的格式,并在测试后将格式还原为其原始状态。要在框架设置和拆解脚手架时提供描述性信息,请在该方法中设置 SetupDescriptionTeardownDescription 属性。

    methods
        function setup(fixture)
            originalFormat = format;
            fixture.addTeardown(@format,originalFormat)
            format(fixture.Format)
            fixture.SetupDescription = "Set the numeric format to " + ...
                fixture.Format + ".";
            fixture.TeardownDescription =  ...
                "Restored the numeric format to " + ...
                originalFormat.NumericFormat + ".";
        end
    end

实现 isCompatible 方法

如果脚手架是可配置的(例如,如果其类构造函数接受输入参量),则在您的 Fixture 子类中实现 isCompatible 方法。在此示例中,由于您使用类构造函数设置 Format 属性,因此必须实现 isCompatible

测试框架调用 isCompatible 来确定相同 Fixture 子类的实例是否对应于相同的共享测试脚手架状态。关于脚手架兼容性的信息有助于框架确定何时执行拆解和设置操作。当两个 NumericFormatFixture 实例的 Format 属性相同时,它们会对环境进行相同的更改。通过在具有 protected 访问权限的 methods 块中实现 isCompatible 方法来指定此兼容性定义。

    methods (Access=protected)
        function tf = isCompatible(fixture1,fixture2)
            tf = fixture1.Format == fixture2.Format;
        end
    end

脚手架类定义

以下代码提供了 NumericFormatFixture 类的完整内容。

classdef NumericFormatFixture < matlab.unittest.fixtures.Fixture
    properties (SetAccess=immutable)
        Format (1,1) string
    end

    methods
        function fixture = NumericFormatFixture(fmt)
            fixture.Format = fmt;
        end

        function setup(fixture)
            originalFormat = format;
            fixture.addTeardown(@format,originalFormat)
            format(fixture.Format)
            fixture.SetupDescription = "Set the numeric format to " + ...
                fixture.Format + ".";
            fixture.TeardownDescription =  ...
                "Restored the numeric format to " + ...
                originalFormat.NumericFormat + ".";
        end
    end

    methods (Access=protected)
        function tf = isCompatible(fixture1,fixture2)
            tf = fixture1.Format == fixture2.Format;
        end
    end
end

将自定义脚手架应用于单个测试类

在当前文件夹内名为 ExampleTest.m 的文件中,创建 ExampleTest 类,以应用自定义脚手架,并验证数值是否以预期格式显示。为了简化此示例,实际值是通过调用 formattedDisplayText 函数生成的。在实际操作中,您要测试用户定义的代码。

classdef ExampleTest < matlab.unittest.TestCase
    methods (Test)
        function formatTest(testCase)
            testCase.applyFixture(NumericFormatFixture("bank"))
            actual = strtrim(formattedDisplayText(pi));
            expected = "3.14";
            testCase.verifyEqual(actual,expected)
        end
    end
end

运行 ExampleTest 类。测试框架可设置脚手架,以将显示格式更改为货币格式。一旦测试运行完毕,框架就会拆解脚手架,这会还原原始显示格式。在此示例中,测试通过。

runtests("ExampleTest");
Running ExampleTest
.
Done ExampleTest
__________

将自定义脚手架应用为共享脚手架

在您当前文件夹中,创建三个测试类,每个测试类都使用 NumericFormatFixture 的一个实例作为共享测试脚手架。

在名为 TestA.m 的文件中,创建 TestA 类。

classdef (SharedTestFixtures={NumericFormatFixture("bank")}) ...
        TestA < matlab.unittest.TestCase
    methods (Test)
        function formatTest(testCase)
            actual = strtrim(formattedDisplayText(pi));
            expected = "3.14";
            testCase.verifyEqual(actual,expected)
        end
    end
end

在名为 TestB.m 的文件中,创建 TestB 类。

classdef (SharedTestFixtures={NumericFormatFixture("bank")}) ...
        TestB < matlab.unittest.TestCase
    methods (Test)
        function formatTest(testCase)
            actual = strtrim(formattedDisplayText(100/3));
            expected = "33.33";
            testCase.verifyEqual(actual,expected)
        end
    end
end

在名为 TestC.m 的文件中,创建 TestC 类。

classdef (SharedTestFixtures={NumericFormatFixture("hex")}) ...
        TestC < matlab.unittest.TestCase
    methods (Test)
        function formatTest(testCase)
            actual = strtrim(formattedDisplayText(1));
            expected = "3ff0000000000000";
            testCase.verifyEqual(actual,expected)
        end
    end
end

TestATestB 类分配有共享脚手架,它们可对环境作出相同的更改。而 TestC 类分配有强制实施不同数值格式的脚手架。根据此示例中 isCompatible 方法的实现,测试框架发现 TestATestB 上的脚手架是兼容的。但是,它发现 TestC 上的脚手架与其他脚手架不兼容。

关于脚手架兼容性的信息有助于框架确定何时执行拆解和设置操作。如果您将 TestATestBTestC 作为同一测试套件的一部分运行,当从 TestA 切换到 TestB 时,框架不会拆解脚手架,因为这两个类需要相同的环境。然而,当从 TestB 切换到 TestC 时,框架会拆解现有脚手架,并设置 TestC 所需的新脚手架。在此示例中,所有测试都通过。

runtests(["TestA" "TestB" "TestC"]);
Setting up NumericFormatFixture
Done setting up NumericFormatFixture: Set the numeric format to bank.
__________

Running TestA
.
Done TestA
__________

Running TestB
.
Done TestB
__________

Tearing down NumericFormatFixture
Done tearing down NumericFormatFixture: Restored the numeric format to short.
__________

Setting up NumericFormatFixture
Done setting up NumericFormatFixture: Set the numeric format to hex.
__________

Running TestC
.
Done TestC
__________

Tearing down NumericFormatFixture
Done tearing down NumericFormatFixture: Restored the numeric format to short.
__________

setup 方法中调用 addTeardown 的替代方法

setup 方法中调用 addTeardown 方法的替代方法是,实现单独的 teardown 方法。以下代码显示如何通过实现 setupteardown 方法来重新创建 NumericFormatFixture 类。请注意,替代类定义包含附加属性 OriginalFormat,用于将有关原始格式的信息传递给 teardown 方法。

classdef NumericFormatFixture < matlab.unittest.fixtures.Fixture
    properties (SetAccess=immutable)
        Format (1,1) string
    end

    properties (Access=private)
        OriginalFormat
    end

    methods
        function fixture = NumericFormatFixture(fmt)  
            fixture.Format = fmt;
        end

        function setup(fixture)
            fixture.OriginalFormat = format().NumericFormat;
            format(fixture.Format)
            fixture.SetupDescription = "Set the numeric format to " + ...
                fixture.Format + ".";
        end

        function teardown(fixture)
            format(fixture.OriginalFormat)
            fixture.TeardownDescription =  ...
                "Restored the numeric format to " + ...
                fixture.OriginalFormat + ".";
        end
    end

    methods (Access=protected)
        function tf = isCompatible(fixture1,fixture2)
            tf = fixture1.Format == fixture2.Format;
        end
    end
end

另请参阅

| |

相关主题