使用设置和拆解函数编写测试
以下示例说明如何使用文件脚手架和刷新脚手架为两个 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
您必须分别命名文件测试脚手架 setupOnce
和 teardownOnce
的设置和拆解函数。这些函数接受测试框架自动向其传递函数测试用例对象的单个输入参量 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
创建刷新脚手架函数
刷新脚手架是在文件中的每个测试函数之前和之后运行的函数级别设置和拆解代码。在此示例中,这些函数打开保存的图窗并查找句柄。测试后,该框架关闭图窗。
您必须分别命名刷新脚手架函数 setup
和 teardown
。与文件脚手架函数类似,这些函数采用单个输入参量 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
函数中创建并保存的图窗,查询坐标区范围并验证这些范围是否正确。鉴定函数 verifyLessThanOrEqual
和 verifyGreaterThanOrEqual
采用在失败时显示的测试用例、实际值、预期值和可选诊断信息作为输入。
将 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
将执行以下各步骤:
主函数创建一个测试数组。
文件脚手架设置记录工作文件夹,创建一个临时文件夹,将临时文件夹设置为工作文件夹,然后生成并保存图窗。
刷新脚手架设置将打开已保存的图窗并查找句柄。
testDefaultXLim
测试运行。刷新脚手架拆解将关闭图窗。
刷新脚手架设置将打开已保存的图窗并查找句柄。
surfaceColorTest
测试运行。刷新脚手架拆解将关闭图窗。
拆解文件脚手架将删除已保存的图窗,重新更改为原始路径并删除临时文件夹。
在命令提示符下,生成并运行测试套件。
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')
另请参阅
matlab.unittest.fixtures
| matlab.unittest.constraints