2016-03-11 4 views
1

Обратитесь к документации по методу testCase.verifyEqual here. В документации говорится, что можно использовать только одну из диагностических функций. Мое требование - мне нужно две диагностики одновременно - строки и дескрипторы функций. Ниже приведен простой пример того, чего я пытаюсь достичь,Использование обеих строк и функций в диагностике Matlab UnitTest?

classdef testArrays < matlab.unittest.TestCase 
    methods (Test) 
     function testArraysEquality(testCase) 
      a = 1:10; 
      b = 1:10; 
      incrementFunc = @(x)x+1; 
      failureCount; 
      for i=1:length(a) 
       testCase.verifyEqual(a(i),b(i),'AbsTol',10e-3,['Test failed array element# ' num2str(i) ' failure count ' num2str(incrementFunc(failureCount))]); 
      end 
      disp([num2str(failureCount) ' out of ' num2str(length(a)) ' test cases failed']); 
     end 
    end 
end 

Проблема заключается в том, что функция Anonymous не хранит значения. С другой стороны, с помощью функции «assignin», показанной ниже, значение может быть увеличено и сохранено, но не может быть возвращено для использования внутри disp(). Есть ли какая-нибудь работа для этого?

incrementFunc1 = @(x) assignin('caller', inputname(1), x+1); 
+0

Почему бы не просто создать логическое значение, где 'a == b', и вы можете распечатать диагностику о том, где различия используются' find (a ~ = b) '? 'testCase.verifyTrue (все (a == b), 'Различия в элементах:% s', sprintf ('% d', find (a ~ = b)))' – Suever

ответ

1

Вы можете включать в себя более чем один (а также более одного типа) диагностики в MATLAB Framework Test Unit, просто предоставляя диагностическую массив verifyEqual. Вы действительно можете сделать это в явном виде следующим образом:

import matlab.unittest.diagnostics.StringDiagnostic; 
import matlab.unittest.diagnostics.FunctionHandleDiagnostic; 
testCase.verifyEqual(a,e, [StringDiagnostic('some string'), FunctionHandleDiagnostic(@() someFunction)]); 

Однако метод Diagnostic.join предоставляется, чтобы сделать это проще:

import matlab.unittest.diagnostics.Diagnostic; 
testCase.verifyEqual(a,e, Diagnostic.join('some string', @() someFunction)); 

Для того, чтобы сделать инкремент позвонить вам, вероятно, будет необходимо добавить неудачный прослушиватель testCase для правильного наращивания. Обратите внимание, что люди/плагины могут фактически добавлять слушателей и выполнять эти диагностические операции в случае сбоев в дополнение к неудачным случаям. Таким образом, ваши диагностические сообщения не должны предполагать, что каждый раз, когда они вызывается, он находится в состоянии сбоя. Это относится не только к вашему инкрементному коду, но также к простому сообщению, которое вы предоставляете. Я хотел бы предложить, что вместо того, чтобы сказать:

Test элемент не удался массив # COUNT 3 Failure 2

вы должны сказать:

Испытано элемент массива счет # 3 неудачи 2

Диагностика рамки сообщит вам, не удалось или нет. В любом случае, вынос, не полагайтесь на вызов диагностики, чтобы определить количество сбоев. Что тогда? Взгляните на раздел «События» here. Вы должны явно прослушивать события проверки, чтобы добавить эту информацию в вашу диагностику.

Для первого решения я не уверен, почему вам необходимо указать количество сбоев при каждом сбое. Похоже, это было бы очень много. Если вам это не нужно, вы можете сделать что-то вроде этого:

classdef testArrays < matlab.unittest.TestCase 
    methods (Test) 
     function testArraysEquality(testCase) 
      a = 1:10; 
      b = 1:10; 
      failureCount = 0; 
      testCase.addlistener('VerificationFailed', @incrementFailureCount); 
      function incrementFailureCount(varargin) 
       % This is a nested function & has the scope and can see/modify 
       % the failureCount variable. This could also be done with a 
       % property on the class ans a method that increments it 
       failureCount = failureCount + 1; 
      end 
      for i=1:length(a) 
       testCase.verifyEqual(a(i),b(i),'AbsTol',10e-3,['Tested array element # ' num2str(i)]); 
      end 
      % I suggest using log instead of disp. If you want it to show up most of the time you can 
      % log it at Terse (1) verbosity. However, if you don't want to see it you can turn it off. 
      testCase.log(1, sprintf('%d out of %d test cases failed', failureCount, length(a))); 
     end 
    end 
end 

Это достаточно хорошо? Если вы действительно хотите показать количество сбоев в диагностике для каждого отказа, вы можете сделать это немного сложнее и требует другой вложенной функции (или доступа к свойствам).

classdef testArrays < matlab.unittest.TestCase 
    methods (Test) 
     function testArraysEquality(testCase) 
      import matlab.unittest.diagnostics.Diagnostic; 

      a = 1:10; 
      b = 1:10; 
      failureCount = 0; 
      testCase.addlistener('VerificationFailed', @incrementFailureCount); 
      function incrementFailureCount(varargin) 
       failureCount = failureCount + 1; 
      end 
      function displayFailureCount 
       fprintf(1, 'Failure Count: %d', failureCount); 
      end 
      for i=1:length(a) 
       testCase.verifyEqual(a(i),b(i),'AbsTol',10e-3, ... 
        Diagnostic.join(... 
         ['Tested array element #' num2str(i)], ... 
         @displayFailureCount)); 
      end 
      testCase.log(1, sprintf('%d out of %d test cases failed', failureCount, length(a))); 
     end 
    end 
end 

Помогло ли вам выполнить то, что вы пытаетесь сделать?

+0

Большое спасибо за подробный ответ @ Энди Кэмпбелл ,Именно то, что я искал. – Naveen

+0

Один вопрос после завершения. Если у меня есть два разных утверждения или проверка выражений в цикле, могу ли я добавить отдельных слушателей для двух утверждений? – Naveen

+0

Одна вещь, о которой нужно заботиться, - это порядок увольнения слушателей. Если какой-либо другой прослушиватель выполняет перед слушателем incrementFailureCount, тогда этот код не будет видеть самый последний счетчик ошибок. Что-то нужно знать. –