在TestCase.verifyEqual中混合Absolute和Relative Tolerances

时间:2016-12-06 20:01:26

标签: matlab unit-testing

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

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

AbsTol = abs(expected-actual)
RelTol = abs((expected-actual)./expected)

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

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

1 个答案:

答案 0 :(得分: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

请注意,当'AbsTol''RelTol'同时,verifyEqual的默认操作与以下内容相同:

>> 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)));

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

>> testCase.verifyThat(actual, IsEqualTo(expected, ...
       'Within', AbsoluteTolerance(abstol) & RelativeTolerance(reltol)));

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

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