在TestCase.verifyEqual中混合Absolute和Relative Tolerances

Dav*_*ley 6 matlab unit-testing

我有一些用基于类的单元测试框架编写的测试用例,我确保我正在进行的分析梯度计算与数值计算版本相当接近.问题是,对于我正在运行的测试用例,梯度的比例变化很大.这意味着虽然我想使用AbsTolName-Value对,但在某些情况下,测试通常会因我认为可接受的误差范围而RelTol失败,而在我认为可接受的情况下也会失败.例如,

expected = [1e7 1e-7];
actual = [1e7+1 1e-5];

AbsTol = abs(expected-actual)
RelTol = abs((expected-actual)./expected)
Run Code Online (Sandbox Code Playgroud)

我认为这里的第一个元素是满足测试的,因为它在相对方面非常接近,而第二个元素在这里满足测试,因为它的绝对值接近,但我认为没有办法测试两个元素是否满足.我知道我可以在外面进行比较verifyEqual,但这似乎是因为丢失了测试框架中包含的漂亮诊断.

有没有办法创建一个单元测试,我可以指定我正在考虑逐个元素比较哪个 AbsTolRelTol满足?

And*_*ell 5

是的,你可以直接得到你想要的东西'verifyEqual',你只需要同时指定'AbsTol''RelTol'.这将为您提供元素OR运算以确定通过/失败.像这样的东西:

>> expected = [1e7 1e-7];
>> actual = [1e7+1 1e-5];

>> testCase = matlab.unittest.TestCase.forInteractiveUse;

>> testCase.verifyEqual(actual,expected,'RelTol',1e-3,'AbsTol',1e-3)
Interactive verification passed.

>> testCase.verifyEqual(actual,expected,'AbsTol',1e-3)
Interactive verification failed.

---------------------
Framework Diagnostic:
---------------------
verifyEqual failed.
--> The values are not equal using "isequaln".
--> The error was not within absolute tolerance.
--> Failure table:
            Index     Actual     Expected    Error    RelativeError    AbsoluteTolerance
            _____    ________    ________    _____    _____________    _________________

            1        10000001    10000000    1        1e-07            0.001            

Actual double:
       1.0e+07 *

       1.000000100000000   0.000000000001000
Expected double:
       1.0e+07 *

       1.000000000000000   0.000000000000010
>> 


>> testCase.verifyEqual(actual,expected,'RelTol',1e-3)
Interactive verification failed.

---------------------
Framework Diagnostic:
---------------------
verifyEqual failed.
--> The values are not equal using "isequaln".
--> The error was not within relative tolerance.
--> Failure table:
            Index    Actual    Expected     Error     RelativeError    RelativeTolerance
            _____    ______    ________    _______    _____________    _________________

            2        1e-05     1e-07       9.9e-06    99               0.001            

Actual double:
       1.0e+07 *

       1.000000100000000   0.000000000001000
Expected double:
       1.0e+07 *

       1.000000000000000   0.000000000000010
Run Code Online (Sandbox Code Playgroud)

需要注意的是verifyEqual的默认操作时都'AbsTol''RelTol'相同如下:

>> import matlab.unittest.constraints.IsEqualTo;
>> import matlab.unittest.constraints.AbsoluteTolerance;
>> import matlab.unittest.constraints.RelativeTolerance;
>> testCase.verifyThat(actual, IsEqualTo(expected, ...
       'Within', AbsoluteTolerance(abstol) | RelativeTolerance(reltol)));
Run Code Online (Sandbox Code Playgroud)

...但是如果要将其更改为AND操作,以便所有值都必须在两种容差类型中,则可以按如下方式执行此操作:

>> testCase.verifyThat(actual, IsEqualTo(expected, ...
       'Within', AbsoluteTolerance(abstol) & RelativeTolerance(reltol)));
Run Code Online (Sandbox Code Playgroud)

最后,可能有用的另一件事是,容差可以指定为单个标量值,也可以指定为与要比较的值相同的值.这允许您具有每个元素不同的容差配置文件.例如,在您的情况下,您可以为第一个元素设置绝对误差10,为第二个元素设置1e-3,它将以单个容差传递:

>> testCase.verifyEqual(actual,expected,'AbsTol',[10, 1e-3])
Interactive verification passed.
Run Code Online (Sandbox Code Playgroud)