创建高级自定义脚手架
此示例演示如何创建设置环境变量的自定义脚手架。在测试之前,该脚手架将保存当前 UserName
变量。
创建 UserNameEnvironmentVariableFixture 类定义
在您的工作文件夹下的文件中,创建一个从 matlab.unittest.fixtures.Fixture
类继承的新类 UserNameEnvironmentVariableFixture
。因为您希望向该脚手架传递用户名,所以创建一个 UserName
属性来在不同方法之间传递数据。
properties (SetAccess = private) UserName end
定义脚手架构造函数
在 UserNameEnvironmentVariableFixture.m
文件的 methods
块中,创建一个构造函数方法来验证输入并定义 SetupDescription
。让构造函数接受字符向量并设置该脚手架的 UserName
属性。
methods function fixture = UserNameEnvironmentVariableFixture(name) validateattributes(name, {'char'}, {'row'}, '','UserName') fixture.UserName = name; fixture.SetupDescription = sprintf( ... 'Set the UserName environment variable to "%s".',... fixture.UserName); end end
实现设置方法
Fixture
类的子类必须实现 setup
方法。使用此方法保存原始 UserName
变量。此方法还定义 TeardownDescription
并注册拆解任务:测试后将 UserName
设置为原始状态。
在 UserNameEnvironmentVariableFixture.m
文件的 methods
块中定义 setup
方法。
methods function setup(fixture) originalUserName = getenv('UserName'); fixture.assertNotEmpty(originalUserName, ... 'An existing UserName environment variable must be defined.') fixture.addTeardown(@setenv, 'UserName', originalUserName) fixture.TeardownDescription = sprintf(... 'Restored the UserName environment variable to "%s".',... originalUserName); setenv('UserName', fixture.UserName) end end
实现 isCompatible 方法
如果构造函数可配置,派生自 Fixture
的类必须实现 isCompatible
方法。因为您可以通过构造函数配置 UserName
属性,所以 UserNameEnvironmentVariableFixture
必须实现 isCompatible
。
isCompatible
方法是通过同一类的两个实例调用的。本例中,它是通过 UserNameEnvironmentVariableFixture
的两个实例调用的。如果这两个实例的 UserName
属性相等,则测试框架将这两个实例视为是兼容的。
在 UserNameEnvironmentVariableFixture.m
内的新 methods
块中,定义一个返回逻辑值 1
(true
) 或逻辑值 0
(false
) 的 isCompatible
方法。
methods (Access = protected) function bool = isCompatible(fixture, other) bool = strcmp(fixture.UserName, other.UserName); end end
脚手架类定义总结
以下是 UserNameEnvironmentVariableFixture.m
的完整内容。
classdef UserNameEnvironmentVariableFixture < ... matlab.unittest.fixtures.Fixture properties (SetAccess = private) UserName end methods function fixture = UserNameEnvironmentVariableFixture(name) validateattributes(name, {'char'}, {'row'}, '','UserName') fixture.UserName = name; fixture.SetupDescription = sprintf( ... 'Set the UserName environment variable to "%s".',... fixture.UserName); end function setup(fixture) originalUserName = getenv('UserName'); fixture.assertNotEmpty(originalUserName, ... 'An existing UserName environment variable must be defined.') fixture.addTeardown(@setenv, 'UserName', originalUserName) fixture.TeardownDescription = sprintf(... 'Restored the UserName environment variable to "%s".',... originalUserName); setenv('UserName', fixture.UserName) end end methods (Access = protected) function bool = isCompatible(fixture, other) bool = strcmp(fixture.UserName, other.UserName); end end end
将自定义脚手架应用于单个测试类
在您的工作文件夹下的文件中,创建以下测试类 ExampleTest.m
。
classdef ExampleTest < matlab.unittest.TestCase methods(TestMethodSetup) function mySetup(testCase) testCase.applyFixture(... UserNameEnvironmentVariableFixture('David')); end end methods (Test) function t1(~) fprintf(1, 'Current UserName: "%s"', getenv('UserName')) end end end
该测试对 ExampleTest
类中的每个测试使用 UserNameEnvironmentVariableFixture
。
在命令提示符下运行测试。
run(ExampleTest);
Running ExampleTest Current UserName: "David". Done ExampleTest __________
将自定义脚手架应用为共享脚手架
在您的工作文件夹中,使用共享脚手架创建三个测试类。使用共享脚手架允许跨类共享 UserNameEnvironmentVariableFixture
。
按如下所示创建 testA.m
。
classdef (SharedTestFixtures = {... UserNameEnvironmentVariableFixture('David')}) ... testA < matlab.unittest.TestCase methods (Test) function t1(~) fprintf(1, 'Current UserName: "%s"', getenv('UserName')) end end end
按如下所示创建 testB.m
。
classdef (SharedTestFixtures = {... UserNameEnvironmentVariableFixture('Andy')}) ... testB < matlab.unittest.TestCase methods (Test) function t1(~) fprintf(1, 'Current UserName: "%s"', getenv('UserName')) end end end
按如下所示创建 testC.m
。
classdef (SharedTestFixtures = {... UserNameEnvironmentVariableFixture('Andy')}) ... testC < matlab.unittest.TestCase methods (Test) function t1(~) fprintf(1, 'Current UserName: "%s"', getenv('UserName')) end end end
在命令提示符下运行这些测试。
runtests({'testA','testB','testC'});
Setting up UserNameEnvironmentVariableFixture Done setting up UserNameEnvironmentVariableFixture: Set the UserName environment variable to "David". __________ Running testA Current UserName: "David". Done testA __________ Tearing down UserNameEnvironmentVariableFixture Done tearing down UserNameEnvironmentVariableFixture: Restored the UserName environment variable to "Kim". __________ Setting up UserNameEnvironmentVariableFixture Done setting up UserNameEnvironmentVariableFixture: Set the UserName environment variable to "Andy". __________ Running testB Current UserName: "Andy". Done testB __________ Running testC Current UserName: "Andy". Done testC __________ Tearing down UserNameEnvironmentVariableFixture Done tearing down UserNameEnvironmentVariableFixture: Restored the UserName environment variable to "Kim". __________
请记住,如果脚手架的 UserName
属性匹配,则它们是兼容的。testA
和 testB
中的测试使用了不兼容的共享脚手架,因为 'David'
不等于 'Andy'
。因此,该框架在对 testA
和 testB
的各次调用中调用脚手架的 teardown
和 setup
方法。不过,testC
中的共享测试脚手架与 testB
中的脚手架兼容,因此该框架在 testC
之前不重复脚手架拆解和设置。
在设置方法中调用 addTeardown 的替代方法
在 setup
方法中使用 addTeardown
方法的替代方法是实现单独的 teardown
方法。实现 UserNameEnvironmentVariableFixture.m
中的以下 setup
和 teardown
方法,而不是上述的 setup
方法。
替代
UserNameEnvironmentVariableFixture
类定义
setup
方法不包含对 addTeardown
的调用或 TeardownDescription
的定义。这些任务转移到了 teardown
方法。替代类定义包含一个额外属性 OriginalUser
,该属性允许在各方法之间传递信息。
另请参阅
matlab.unittest.fixtures.Fixture