如何防止使用 "assertWarning" 的 Matlab 测试将警告文本打印到控制台?

How do I prevent a Matlab test with "assertWarning" from printing warning text to the console?

我正在尝试在 Matlab 中实现一个基本的测试框架,这是我第一次尝试测试驱动开发。我尝试创建的测试之一旨在验证我的函数在特定输入条件下是否会引发特定警告。我的代码按预期通过了与警告相关的测试,但是有一个巨大的烦恼。

当 运行 宁(并通过)涉及 "assertWarning" 或 "verifyWarning" 函数的测试时,应该触发的警告将打印到命令 window并在视觉上破坏了我的测试套件的打印输出。 有没有一种方法可以防止(期望的)警告仅在测试中 运行 时才打印到控制台,同时仍然验证警告是否已触发? 示例测试下面是导致这个烦人的警告打印输出的函数。

function testAcceleratorMax(testCase)
% Validate that acceleration input is forced to be <=1 and throws warning
state = [0,0,0,0]; input = [2,0];
xd = getPointMass2D_dot(state,input);
assert(isequal(xd,[0,0,1,0]),'Acceleration not ceiled correctly');
verifyWarning(testCase,@(x) getPointMass2D_dot(state,input),...
    'MATLAB:CommandedAccelOutOfBounds');
end

我不太了解你的代码做了什么,但你总是可以这样做:

A = eye(2);
B = [3 6; 4 8];
evalc('C=B\A'); % the warning gets suppressed. It also gets outputted by this function, but it can also output other command window prints
lastwarn; %grab the last warning

但是小心! evalc 评估进入内部的所有内容。这包括会破坏您的计算机的命令,例如 system('suda rm -rf/')*

*故意打错字。

我找到了一种方法来减少在 运行 测试套件时打印警告的烦恼。但是,这可能会导致一些后续问题。在测试套件的设置函数中,您可以将警告设置为简洁并关闭回溯(并在拆解函数中将它们重置为默认状态)。

function setup(testCase)
warning off verbose;
warning off backtrace;
end

function teardown(testCase)
warning on verbose;
warning on backtrace;
end

正如您在下面看到的,这减少了打印到控制台的大量警告文本。但是,如果在 TDD 过程中,您想要实际使用意外测试失败的回溯,则必须打开警告回溯。我想您可以在每个功能测试中手动关闭和打开回溯,但它似乎仍然不是最佳解决方案。

示例命令 window 关闭详细输出,关闭回溯:

> Running tests_getPointMass2D_dot  
> .....Warning: The acceleration commanded was set to the max accel allowed  
> .Warning: The acceleration commanded was set to the min accel allowed  
> .Warning: The steering commanded was set to the max steer allowed  
> .Warning: The steering commanded was set to the min steer allowed  
> .  
> Done tests_getPointMass2D_dot
> __________
> Totals:    9 Passed, 0 Failed, 0 Incomplete.   
> 0.19797 seconds testing time.

示例命令 window 输出详细,回溯:

> Running tests_getPointMass2D_dot .....Warning: The acceleration
> commanded was set to the max accel allowed (Type "warning off
> MATLAB:CommandedAccelOutOfBounds" to suppress this warning.)
>  
> > In getPointMass2D_dot (line 43)   In tests_getPointMass2D_dot>testAcceleratorMax (line 55)   In
> matlab.unittest.FunctionTestCase/test (line 98)   In
> matlab.unittest.TestRunner/evaluateMethodCore (line 995)   In
> matlab.unittest.TestRunner/evaluateMethodsOnTestContent (line 936)  
> In matlab.unittest.TestRunner/runTestMethod (line 1287)   In
> matlab.unittest.TestRunner/runTest (line 1244)   In
> matlab.unittest.TestRunner/repeatTest (line 586)   In
> matlab.unittest.TestRunner/runSharedTestCase (line 548)   In
> matlab.unittest.TestRunner/runTestClass (line 1170)   In
> matlab.unittest.TestRunner/invokeTestContentOperatorMethod_ (line
> 1037)   In matlab.unittest.plugins.TestRunnerPlugin/runTestClass (line
> 378)   In
> matlab.unittest.plugins.testrunprogress.ConciseProgressPlugin/runTestClass
> (line 68)   In
> matlab.unittest.plugins.TestRunnerPlugin/invokeTestContentOperatorMethod_
> (line 658)   In matlab.unittest.TestRunner/evaluateMethodOnPlugins
> (line 895)   In matlab.unittest.TestRunner/runTestSuite (line 1102)  
> In matlab.unittest.TestRunner/invokeTestContentOperatorMethod_ (line
> 1037)   In matlab.unittest.plugins.TestRunnerPlugin/runTestSuite (line
> 229)   In
> matlab.unittest.plugins.FailureDiagnosticsPlugin/runTestSuite (line
> 95)   In
> matlab.unittest.plugins.TestRunnerPlugin/invokeTestContentOperatorMethod_
> (line 658)   In matlab.unittest.plugins.TestRunnerPlugin/runTestSuite
> (line 229)   In
> matlab.unittest.internal.plugins.ListenerAdderPlugin/runTestSuite
> (line 29)   In
> matlab.unittest.plugins.DiagnosticsRecordingPlugin/runTestSuite (line
> 165)   In
> matlab.unittest.plugins.TestRunnerPlugin/invokeTestContentOperatorMethod_
> (line 658)   In matlab.unittest.TestRunner/evaluateMethodOnPlugins
> (line 895)   In matlab.unittest.TestRunner/run (line 307)   In
> runtests (line 90)  .Warning: The acceleration commanded was set to
> the min accel allowed (Type "warning off
> MATLAB:CommandedAccelOutOfBounds" to suppress this warning.)
>  
> > In getPointMass2D_dot (line 47)   In tests_getPointMass2D_dot>testAcceleratorMin (line 64)   In
> matlab.unittest.FunctionTestCase/test (line 98)   In
> matlab.unittest.TestRunner/evaluateMethodCore (line 995)   In
> matlab.unittest.TestRunner/evaluateMethodsOnTestContent (line 936)  
> In matlab.unittest.TestRunner/runTestMethod (line 1287)   In
> matlab.unittest.TestRunner/runTest (line 1244)   In
> matlab.unittest.TestRunner/repeatTest (line 586)   In
> matlab.unittest.TestRunner/runSharedTestCase (line 548)   In
> matlab.unittest.TestRunner/runTestClass (line 1170)   In
> matlab.unittest.TestRunner/invokeTestContentOperatorMethod_ (line
> 1037)   In matlab.unittest.plugins.TestRunnerPlugin/runTestClass (line
> 378)   In
> matlab.unittest.plugins.testrunprogress.ConciseProgressPlugin/runTestClass
> (line 68)   In
> matlab.unittest.plugins.TestRunnerPlugin/invokeTestContentOperatorMethod_
> (line 658)   In matlab.unittest.TestRunner/evaluateMethodOnPlugins
> (line 895)   In matlab.unittest.TestRunner/runTestSuite (line 1102)  
> In matlab.unittest.TestRunner/invokeTestContentOperatorMethod_ (line
> 1037)   In matlab.unittest.plugins.TestRunnerPlugin/runTestSuite (line
> 229)   In
> matlab.unittest.plugins.FailureDiagnosticsPlugin/runTestSuite (line
> 95)   In
> matlab.unittest.plugins.TestRunnerPlugin/invokeTestContentOperatorMethod_
> (line 658)   In matlab.unittest.plugins.TestRunnerPlugin/runTestSuite
> (line 229)   In
> matlab.unittest.internal.plugins.ListenerAdderPlugin/runTestSuite
> (line 29)   In
> matlab.unittest.plugins.DiagnosticsRecordingPlugin/runTestSuite (line
> 165)   In
> matlab.unittest.plugins.TestRunnerPlugin/invokeTestContentOperatorMethod_
> (line 658)   In matlab.unittest.TestRunner/evaluateMethodOnPlugins
> (line 895)   In matlab.unittest.TestRunner/run (line 307)   In
> runtests (line 90)  .Warning: The steering commanded was set to the
> max steer allowed (Type "warning off MATLAB:CommandedSteerOutOfBounds"
> to suppress this warning.)
>  
> > In getPointMass2D_dot (line 54)   In tests_getPointMass2D_dot>testSteeringMax (line 73)   In
> matlab.unittest.FunctionTestCase/test (line 98)   In
> matlab.unittest.TestRunner/evaluateMethodCore (line 995)   In
> matlab.unittest.TestRunner/evaluateMethodsOnTestContent (line 936)  
> In matlab.unittest.TestRunner/runTestMethod (line 1287)   In
> matlab.unittest.TestRunner/runTest (line 1244)   In
> matlab.unittest.TestRunner/repeatTest (line 586)   In
> matlab.unittest.TestRunner/runSharedTestCase (line 548)   In
> matlab.unittest.TestRunner/runTestClass (line 1170)   In
> matlab.unittest.TestRunner/invokeTestContentOperatorMethod_ (line
> 1037)   In matlab.unittest.plugins.TestRunnerPlugin/runTestClass (line
> 378)   In
> matlab.unittest.plugins.testrunprogress.ConciseProgressPlugin/runTestClass
> (line 68)   In
> matlab.unittest.plugins.TestRunnerPlugin/invokeTestContentOperatorMethod_
> (line 658)   In matlab.unittest.TestRunner/evaluateMethodOnPlugins
> (line 895)   In matlab.unittest.TestRunner/runTestSuite (line 1102)  
> In matlab.unittest.TestRunner/invokeTestContentOperatorMethod_ (line
> 1037)   In matlab.unittest.plugins.TestRunnerPlugin/runTestSuite (line
> 229)   In
> matlab.unittest.plugins.FailureDiagnosticsPlugin/runTestSuite (line
> 95)   In
> matlab.unittest.plugins.TestRunnerPlugin/invokeTestContentOperatorMethod_
> (line 658)   In matlab.unittest.plugins.TestRunnerPlugin/runTestSuite
> (line 229)   In
> matlab.unittest.internal.plugins.ListenerAdderPlugin/runTestSuite
> (line 29)   In
> matlab.unittest.plugins.DiagnosticsRecordingPlugin/runTestSuite (line
> 165)   In
> matlab.unittest.plugins.TestRunnerPlugin/invokeTestContentOperatorMethod_
> (line 658)   In matlab.unittest.TestRunner/evaluateMethodOnPlugins
> (line 895)   In matlab.unittest.TestRunner/run (line 307)   In
> runtests (line 90)  .Warning: The steering commanded was set to the
> min steer allowed (Type "warning off MATLAB:CommandedSteerOutOfBounds"
> to suppress this warning.)
>  
> > In getPointMass2D_dot (line 58)   In tests_getPointMass2D_dot>testSteeringMin (line 82)   In
> matlab.unittest.FunctionTestCase/test (line 98)   In
> matlab.unittest.TestRunner/evaluateMethodCore (line 995)   In
> matlab.unittest.TestRunner/evaluateMethodsOnTestContent (line 936)  
> In matlab.unittest.TestRunner/runTestMethod (line 1287)   In
> matlab.unittest.TestRunner/runTest (line 1244)   In
> matlab.unittest.TestRunner/repeatTest (line 586)   In
> matlab.unittest.TestRunner/runSharedTestCase (line 548)   In
> matlab.unittest.TestRunner/runTestClass (line 1170)   In
> matlab.unittest.TestRunner/invokeTestContentOperatorMethod_ (line
> 1037)   In matlab.unittest.plugins.TestRunnerPlugin/runTestClass (line
> 378)   In
> matlab.unittest.plugins.testrunprogress.ConciseProgressPlugin/runTestClass
> (line 68)   In
> matlab.unittest.plugins.TestRunnerPlugin/invokeTestContentOperatorMethod_
> (line 658)   In matlab.unittest.TestRunner/evaluateMethodOnPlugins
> (line 895)   In matlab.unittest.TestRunner/runTestSuite (line 1102)  
> In matlab.unittest.TestRunner/invokeTestContentOperatorMethod_ (line
> 1037)   In matlab.unittest.plugins.TestRunnerPlugin/runTestSuite (line
> 229)   In
> matlab.unittest.plugins.FailureDiagnosticsPlugin/runTestSuite (line
> 95)   In
> matlab.unittest.plugins.TestRunnerPlugin/invokeTestContentOperatorMethod_
> (line 658)   In matlab.unittest.plugins.TestRunnerPlugin/runTestSuite
> (line 229)   In
> matlab.unittest.internal.plugins.ListenerAdderPlugin/runTestSuite
> (line 29)   In
> matlab.unittest.plugins.DiagnosticsRecordingPlugin/runTestSuite (line
> 165)   In
> matlab.unittest.plugins.TestRunnerPlugin/invokeTestContentOperatorMethod_
> (line 658)   In matlab.unittest.TestRunner/evaluateMethodOnPlugins
> (line 895)   In matlab.unittest.TestRunner/run (line 307)   In
> runtests (line 90)  . Done tests_getPointMass2D_dot
> __________
> 
> 
> Totals:    9 Passed, 0 Failed, 0 Incomplete.  
>    0.20351 seconds testing time.

虽然这可能不是最优雅的解决方案,但我找到了一种侵入性小得多的方法!

第 1 步:在测试套件设置功能中关闭您故意触发的特定警告。如果需要,您也可以在每个测试函数中单独执行此操作和步骤 2。即使警告已关闭并且不会打印到命令 window,您也可以使用 "lastwarn".

访问被抑制的警告
function setup(testCase)
warning('off','MATLAB:CommandedAccelOutOfBounds');
warning('off','MATLAB:CommandedSteerOutOfBounds');
end

第 2 步:在测试套件拆卸功能中重新打开特定警告,以在 运行 测试套件后将 matlab 重置为正确状态。

function teardown(testCase)
warning('on','MATLAB:CommandedAccelOutOfBounds');
warning('on','MATLAB:CommandedSteerOutOfBounds');
end

第 3 步:不要使用 "verifyWarning" 或 "assertWarning" 函数进行测试,而是使用 "lastwarn" 和 "strcmp"。

function testAcceleratorMax(testCase)
% Validate that acceleration input is forced to be <=1 and throws warning
state = [0,0,0,0]; input = [2,0];
xd = getPointMass2D_dot(state,input);
assert(isequal(xd,[0,0,1,0]),'Acceleration not ceiled correctly');
[~,warnID] = lastwarn; % Gets last warning, even though it was "off"
assert(strcmp(warnID,'MATLAB:CommandedAccelOutOfBounds'), 'Correct warning not thrown')
end