2016-12-06 2 views
2

У меня есть несколько тестовых примеров, написанных на основе модульного тестирования модулей на основе классов, где я уверен, что расчет аналитического градиента, который я делаю, достаточно близок к численному вычислению версия. Проблема в том, что масштабы градиента довольно широко варьируются для тестовых случаев, которые я запускаю. Это означает, что, хотя я бы хотел использовать пару Name-Value AbsTol, тест обычно терпит неудачу в том, что я считаю приемлемым пределом ошибки в некоторых случаях, в то время как RelTol также потерпит неудачу в отношении того, что я считаю приемлемыми. Например,Смешивание абсолютных и относительных допусков в TestCase.verifyEqual

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

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

Я бы рассмотреть первый элемент здесь, чтобы удовлетворить тест, так как это очень близко в относительном выражении, а второй элемент здесь, чтобы удовлетворить тест, так как она близка в абсолютном выражении, но я не вижу никакой возможности чтобы проверить, выполнено ли для обоих элементов. Я знаю, что я мог бы провести сравнение за пределами verifyEqual, но это, похоже, связано с потерей хорошей диагностики, включенной в структуру тестирования.

Есть ли какой-нибудь способ, чтобы создать модульный тест, где я могу указать, что я рассматриваю такое элемент-поэлементное сравнение, где либоAbsTol или RelTol удовлетворяется?

ответ

3

Да, вы можете получить то, что хотите, непосредственно от 'verifyEqual', вам просто нужно указать и 'AbsTol', и 'RelTol'. Это даст вам элементную операцию OR для определения pass/fail. Что-то вроде этого:

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

Обратите внимание, что операция по умолчанию 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))); 

... но если вы хотите изменить что к AND операция, так что все значения должны быть в пределах допуска обоих типов, вы можете сделать это следующим образом:

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

Наконец, еще одна вещь, которая может быть helpf ul является то, что допуск может быть задан либо как одно скалярное значение, либо как значение того же размера, что и сравниваемые значения. Это позволяет вам иметь профили допуска, которые отличаются для каждого элемента. Например, в вашем случае вы можете сделать абсолютную погрешность 10 для первого элемента и 1e-3 для второго и она будет проходить с одним допуском:

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

Большой бонус обучения 'TestCase.forInteractiveUse' существует! –

Смежные вопросы