Main Content

使用设置和拆解函数编写测试

以下示例说明如何使用文件脚手架和刷新脚手架为两个 MATLAB® 图窗属性编写单元测试。

创建 axesPropertiesTest.m 文件

创建一个包含用于测试图窗属性的主函数的文件,并包括两个测试函数。一个函数用于验证 x 坐标轴范围是否正确,另一个用于验证曲面的面颜色是否正确。

在您的 MATLAB 路径上的一个文件夹中,创建 axesPropertiesTest.m。在此文件的主函数中,通过调用 localfunctions 函数让 functiontests 根据 axesPropertiesTest.m 中的每个局部函数创建一个测试数组。

function tests = axesPropertiesTest
tests = functiontests(localfunctions);
end

创建文件脚手架函数

文件脚手架函数是在您的测试文件中运行一次的设置和拆解代码。这些脚手架跨测试文件共享。在此示例中,文件脚手架函数创建一个临时文件夹并将其设置为当前工作文件夹。它们还创建并保存一个新图窗以进行测试。在测试完成后,该框架恢复原始工作文件夹并删除临时文件夹和保存的图窗。

在此示例中,辅助函数创建一个简单图窗 - 一个红色圆柱。在更实际的方案中,此代码是受测产品的一部分,计算成本很高,因而适宜仅创建图窗一次,并为每个测试函数加载结果的独立副本。但在此示例中,您希望作为 axesPropertiesTest 的局部函数创建此辅助函数。请注意,测试数组不包括该函数,这是因为其名称不以 ‘test’ 开头或结尾。

编写一个辅助函数,以创建一个简单的红色圆柱并将其添加为 axesPropertiesTest 的局部函数。

function f = createFigure
f = figure;
ax = axes('Parent',f);
cylinder(ax,10)
h = findobj(ax,'Type','surface');
h.FaceColor = [1 0 0];
end

您必须分别命名文件测试脚手架 setupOnceteardownOnce 的设置和拆解函数。这些函数接受测试框架自动向其传递函数测试用例对象的单个输入参量 testCase。此测试用例对象包含一个用于在设置、测试和拆解函数之间传递数据的 TestData 结构体。在此示例中,TestData 结构体使用分配的字段存储原始路径、临时文件夹名称和图窗文件名。

将设置和拆解函数创建为 axesPropertiesTest 的局部函数。

function setupOnce(testCase)
% Create and change to temporary folder
testCase.TestData.origPath = pwd;
testCase.TestData.tmpFolder = "tmpFolder" + ...
    string(datetime('now','Format',"yyyyMMdd'T'HHmmss"));
mkdir(testCase.TestData.tmpFolder)
cd(testCase.TestData.tmpFolder)
% Create and save a figure
testCase.TestData.figName = 'tmpFig.fig';
aFig = createFigure;
saveas(aFig,testCase.TestData.figName)
close(aFig)
end

function teardownOnce(testCase)
delete(testCase.TestData.figName)
cd(testCase.TestData.origPath)
rmdir(testCase.TestData.tmpFolder)
end

创建刷新脚手架函数

刷新脚手架是在文件中的每个测试函数之前和之后运行的函数级别设置和拆解代码。在此示例中,这些函数打开保存的图窗并查找句柄。测试后,该框架关闭图窗。

您必须分别命名刷新脚手架函数 setupteardown。与文件脚手架函数类似,这些函数采用单个输入参量 testCase。在此示例中,这些函数在包括图窗句柄和坐标区句柄的 TestData 结构体中创建一个新字段。这样可以在设置、测试和拆解函数之间传递信息。

将设置和拆解函数创建为 axesPropertiesTest 的局部函数。打开为每个测试保存的图窗以确保测试独立性。

function setup(testCase)
testCase.TestData.Figure = openfig(testCase.TestData.figName);
testCase.TestData.Axes = findobj(testCase.TestData.Figure, ...
    'Type','Axes');
end

function teardown(testCase)
close(testCase.TestData.Figure)
end

除了自定义的设置和拆解代码外,测试框架还提供某些类用于创建脚手架。有关详细信息,请参阅 matlab.unittest.fixtures

创建测试函数

每个测试都是一个局部函数,它遵从在函数名称开头或末尾包含 ‘test’ 的命名约定。测试数组不包括不遵从此约定的局部函数。与设置和拆解函数类似,各个测试函数必须接受单个输入参量 testCase。将此测试用例对象用于验证、断言、假设和致命断言。

testDefaultXLim 函数验证 x 坐标轴范围是否足够大,以便显示圆柱。下限需要小于 -10,上限需要大于 10。这些值来自在辅助函数中生成的图窗 - 一个以原点为中心、单位半径为 10 的圆柱。此测试函数打开在 setupOnce 函数中创建并保存的图窗,查询坐标区范围并验证这些范围是否正确。鉴定函数 verifyLessThanOrEqualverifyGreaterThanOrEqual 采用在失败时显示的测试用例、实际值、预期值和可选诊断信息作为输入。

testDefaultXLim 函数创建为 axesPropertiesTest 的局部函数。

function testDefaultXLim(testCase)
xlim = testCase.TestData.Axes.XLim;
verifyLessThanOrEqual(testCase,xlim(1),-10, ...
    'Minimum x-limit was not small enough')
verifyGreaterThanOrEqual(testCase,xlim(2),10, ...
    'Maximum x-limit was not large enough')
end

surfaceColorTest 函数访问您在 setupOnce 函数中创建并保存的图窗。surfaceColorTest 查询圆柱的面颜色并验证其是否为红色。红色的 RGB 值为 [1 0 0]。鉴定函数 verifyEqual 采用在失败时显示的测试用例、实际值、预期值和可选诊断信息作为输入。通常,当对浮点值使用 verifyEqual 时,需要为比较指定容差。有关详细信息,请参阅 matlab.unittest.constraints

surfaceColorTest 函数创建为 axesPropertiesTest 的局部函数。

function surfaceColorTest(testCase)
h = findobj(testCase.TestData.Axes,'Type','surface');
co = h.FaceColor;
verifyEqual(testCase,co,[1 0 0],'Face color is incorrect')
end

现在,axesPropertiesTest.m 文件是完整的,包含主函数、辅助函数、文件脚手架函数、刷新脚手架函数和两个测试函数。此时,您可以运行测试。

运行测试

下一步是使用 runtests 函数运行测试。在此示例中,调用 runtests 将执行以下各步骤:

  1. 主函数创建一个测试数组。

  2. 文件脚手架设置记录工作文件夹,创建一个临时文件夹,将临时文件夹设置为工作文件夹,然后生成并保存图窗。

  3. 刷新脚手架设置将打开已保存的图窗并查找句柄。

  4. testDefaultXLim 测试运行。

  5. 刷新脚手架拆解将关闭图窗。

  6. 刷新脚手架设置将打开已保存的图窗并查找句柄。

  7. surfaceColorTest 测试运行。

  8. 刷新脚手架拆解将关闭图窗。

  9. 拆解文件脚手架将删除已保存的图窗,重新更改为原始路径并删除临时文件夹。

在命令提示符下,生成并运行测试套件。

results = runtests('axesPropertiesTest.m')
Running axesPropertiesTest
..
Done axesPropertiesTest
__________
results = 
  1×2 TestResult array with properties:

    Name
    Passed
    Failed
    Incomplete
    Duration
    Details

Totals:
   2 Passed, 0 Failed, 0 Incomplete.
   0.5124 seconds testing time.

创建测试结果表格

要访问表格可用的功能,先从 TestResult 对象创建一个表格。

rt = table(results)
rt=2×6 table
                     Name                      Passed    Failed    Incomplete    Duration      Details   
    _______________________________________    ______    ______    __________    ________    ____________

    {'axesPropertiesTest/testDefaultXLim' }    true      false       false       0.35239     {1×1 struct}
    {'axesPropertiesTest/surfaceColorTest'}    true      false       false       0.16001     {1×1 struct}

按持续时间升序排列测试结果。

sortrows(rt,'Duration')
ans=2×6 table
                     Name                      Passed    Failed    Incomplete    Duration      Details   
    _______________________________________    ______    ______    __________    ________    ____________

    {'axesPropertiesTest/surfaceColorTest'}    true      false       false       0.16001     {1×1 struct}
    {'axesPropertiesTest/testDefaultXLim' }    true      false       false       0.35239     {1×1 struct}

将测试结果导出为 Excel® 电子表格。

writetable(rt,'myTestResults.xls')

另请参阅

|

相关主题