В этом примере показано, как создать пользовательский плагин, который поддерживает запускающие тесты параллельно. Пользовательский плагин считает количество передачи и провальных утверждений для тестового набора. Расширять TestRunner
, плагин заменяет избранные методы matlab.unittest.plugins.TestRunnerPlugin
класс. Кроме того, чтобы поддержать запускающие тесты параллельно, плагин разделяет на подклассы matlab.unittest.plugins.Parallelizable
интерфейс. Чтобы запустить тесты параллельно, вам нужен Parallel Computing Toolbox™.
В файле в вашей текущей папке создайте parallelizable сменный класс AssertionCountingPlugin
, который наследовал от обоих TestRunnerPlugin
и Parallelizable
классы. Для полного кода для AssertionCountingPlugin
, см. Сменные Сводные данные Определения класса.
Чтобы отслеживать количество передачи и провальных утверждений, задайте четыре свойства только для чтения в properties
блок. Каждый рабочий MATLAB® на текущем параллельном пуле использует NumPassingAssertions
и NumFailingAssertions
отслеживать количество передачи и провальных утверждений при выполнении фрагмента TestSuite
массив. Клиент MATLAB использует FinalizedNumPassingAssertions
и FinalizedNumFailingAssertions
агрегировать результаты различных рабочих и сообщить об общем количестве передачи и провальных утверждений в конце сеанса тестирования.
properties (SetAccess = private) NumPassingAssertions NumFailingAssertions FinalizedNumPassingAssertions FinalizedNumFailingAssertions end
Расширять выполнение целого TestSuite
массив, замените runSession
метод TestRunnerPlugin
в methods
блокируйтесь с protected
доступ. Среда тестирования оценивает этот метод одно время на клиенте.
methods (Access = protected) function runSession(plugin, pluginData) suiteSize = numel(pluginData.TestSuite); fprintf('## Running a total of %d tests\n\n', suiteSize); plugin.FinalizedNumPassingAssertions = 0; plugin.FinalizedNumFailingAssertions = 0; runSession@matlab.unittest.plugins.TestRunnerPlugin(plugin, pluginData); fprintf('## Done running tests\n') plugin.printAssertionSummary() end end
runSession
информация об отображениях об общем количестве Test
элементы, инициализирует свойства, используемые плагином, чтобы сгенерировать вывод текста, и вызывает метод суперкласса инициировать целый тестовый прогон. После того, как среда завершает оценку метода суперкласса, runSession
отображается утверждение считают сводные данные путем вызова вспомогательного метода printAssertionSummary
(см., задают вспомогательные методы).
Добавьте прослушиватели AssertionPassed
и AssertionFailed
события, чтобы считать утверждения. Чтобы добавить эти прослушиватели, расширьте методы, используемые средой тестирования, чтобы создать содержание теста. Содержание теста включает TestCase
экземпляры для каждого Test
элемент, уровень класса TestCase
экземпляры для TestClassSetup
и TestClassTeardown
блоки метода и Fixture
экземпляры, используемые, когда TestCase
класс имеет SharedTestFixtures
атрибут.
Вызовите соответствующий метод суперкласса, когда вы замените методы создания. Методы создания возвращают содержимое, которое среда тестирования создает для каждого из их соответствующих контекстов. При реализации одного из этих методов с помощью incrementPassingAssertionsCount
и incrementFailingAssertionsCount
вспомогательные методы, добавляют прослушиватели, требуемые плагином к возвращенному Fixture
или TestCase
экземпляр.
Добавьте эти методы создания для methods
блокируйтесь с protected
доступ.
methods (Access = protected) function fixture = createSharedTestFixture(plugin, pluginData) fixture = createSharedTestFixture@... matlab.unittest.plugins.TestRunnerPlugin(plugin, pluginData); fixture.addlistener('AssertionPassed', ... @(~,~)plugin.incrementPassingAssertionsCount); fixture.addlistener('AssertionFailed', ... @(~,~)plugin.incrementFailingAssertionsCount); end function testCase = createTestClassInstance(plugin, pluginData) testCase = createTestClassInstance@... matlab.unittest.plugins.TestRunnerPlugin(plugin, pluginData); testCase.addlistener('AssertionPassed', ... @(~,~)plugin.incrementPassingAssertionsCount); testCase.addlistener('AssertionFailed', ... @(~,~)plugin.incrementFailingAssertionsCount); end function testCase = createTestMethodInstance(plugin, pluginData) testCase = createTestMethodInstance@... matlab.unittest.plugins.TestRunnerPlugin(plugin, pluginData); testCase.addlistener('AssertionPassed', ... @(~,~)plugin.incrementPassingAssertionsCount); testCase.addlistener('AssertionFailed', ... @(~,~)plugin.incrementFailingAssertionsCount); end end
Среда тестирования делит целый TestSuite
массив в различные группы и присваивает их рабочим для обработки. Каждый рабочий может запустить один или несколько фрагментов тестового набора. Чтобы настроить поведение рабочих, замените runTestSuite
метод TestRunnerPlugin
в methods
блокируйтесь с protected
доступ.
Расширьте TestRunner
отобразить идентификатор каждой тестовой группы, которую рабочий запускает наряду с количеством Test
элементы в группе. Кроме того, сохраните количество передачи и провальных утверждений в буфере так, чтобы клиент мог получить эти значения, чтобы привести к завершенным результатам. Как все сменные методы, runTestSuite
метод требует, чтобы вы вызвали соответствующий метод суперкласса в соответствующей точке. В этом случае вызовите метод суперкласса после инициализации свойств и прежде, чем хранить данные рабочего. Среда тестирования оценивает runTestSuite
на рабочих так же много раз как количество фрагментов тестового набора.
methods (Access = protected) function runTestSuite(plugin, pluginData) suiteSize = numel(pluginData.TestSuite); groupNumber = pluginData.Group; fprintf('### Running a total of %d tests in group %d\n', ... suiteSize, groupNumber); plugin.NumPassingAssertions = 0; plugin.NumFailingAssertions = 0; runTestSuite@matlab.unittest.plugins.TestRunnerPlugin(... plugin, pluginData); assertionStruct = struct('Passing', plugin.NumPassingAssertions, ... 'Failing', plugin.NumFailingAssertions); plugin.storeIn(pluginData.CommunicationBuffer, assertionStruct); end end
Хранить специфичные для теста данные, реализацию runTestSuite
содержит вызов storeIn
метод Parallelizable
интерфейс. Используйте storeIn
наряду с retrieveFrom
когда рабочие должны сообщить клиенту. В этом примере, после возврата из метода суперкласса, NumPassingAssertions
и NumFailingAssertions
содержите количество передачи и провальных утверждений, соответствующих группе тестов. Поскольку storeIn
принимает данные рабочего как только один входной параметр, assertionStruct
группирует количества утверждения с помощью двух полей.
Расширьте reportFinalizedSuite
агрегировать количества утверждения путем получения тестовых данных для каждого завершенного фрагмента тестового набора. Получать сохраненный assertionStruct
для фрагмента тестового набора вызовите retrieveFrom
метод в рамках reportFinalizedSuite
. Добавьте значения полей в соответствующие свойства класса и вызовите метод суперкласса. Среда тестирования оценивает этот метод на клиенте так же много раз как количество фрагментов тестового набора.
methods (Access = protected) function reportFinalizedSuite(plugin, pluginData) assertionStruct = plugin.retrieveFrom(pluginData.CommunicationBuffer); plugin.FinalizedNumPassingAssertions = ... plugin.FinalizedNumPassingAssertions + assertionStruct.Passing; plugin.FinalizedNumFailingAssertions = ... plugin.FinalizedNumFailingAssertions + assertionStruct.Failing; reportFinalizedSuite@matlab.unittest.plugins.TestRunnerPlugin(... plugin, pluginData); end end
В methods
блокируйтесь с private
доступ, задайте три вспомогательных метода. Эти методы постепенно увеличивают количество передачи или провальных утверждений в каждом рабочем фрагменте тестового набора, и распечатывают сводные данные количества утверждения.
methods (Access = private) function incrementPassingAssertionsCount(plugin) plugin.NumPassingAssertions = plugin.NumPassingAssertions + 1; end function incrementFailingAssertionsCount(plugin) plugin.NumFailingAssertions = plugin.NumFailingAssertions + 1; end function printAssertionSummary(plugin) fprintf('%s\n', repmat('_', 1, 30)) fprintf('Total Assertions: %d\n', plugin.FinalizedNumPassingAssertions + ... plugin.FinalizedNumFailingAssertions) fprintf('\t%d Passed, %d Failed\n', plugin.FinalizedNumPassingAssertions, ... plugin.FinalizedNumFailingAssertions) end end
Следующий код предоставляет полное содержимое AssertionCountingPlugin
.
classdef AssertionCountingPlugin < ... matlab.unittest.plugins.TestRunnerPlugin & ... matlab.unittest.plugins.Parallelizable properties (SetAccess = private) NumPassingAssertions NumFailingAssertions FinalizedNumPassingAssertions FinalizedNumFailingAssertions end methods (Access = protected) function runSession(plugin, pluginData) suiteSize = numel(pluginData.TestSuite); fprintf('## Running a total of %d tests\n\n', suiteSize); plugin.FinalizedNumPassingAssertions = 0; plugin.FinalizedNumFailingAssertions = 0; runSession@matlab.unittest.plugins.TestRunnerPlugin(plugin, pluginData); fprintf('## Done running tests\n') plugin.printAssertionSummary() end function fixture = createSharedTestFixture(plugin, pluginData) fixture = createSharedTestFixture@... matlab.unittest.plugins.TestRunnerPlugin(plugin, pluginData); fixture.addlistener('AssertionPassed', ... @(~,~)plugin.incrementPassingAssertionsCount); fixture.addlistener('AssertionFailed', ... @(~,~)plugin.incrementFailingAssertionsCount); end function testCase = createTestClassInstance(plugin, pluginData) testCase = createTestClassInstance@... matlab.unittest.plugins.TestRunnerPlugin(plugin, pluginData); testCase.addlistener('AssertionPassed', ... @(~,~)plugin.incrementPassingAssertionsCount); testCase.addlistener('AssertionFailed', ... @(~,~)plugin.incrementFailingAssertionsCount); end function testCase = createTestMethodInstance(plugin, pluginData) testCase = createTestMethodInstance@... matlab.unittest.plugins.TestRunnerPlugin(plugin, pluginData); testCase.addlistener('AssertionPassed', ... @(~,~)plugin.incrementPassingAssertionsCount); testCase.addlistener('AssertionFailed', ... @(~,~)plugin.incrementFailingAssertionsCount); end function runTestSuite(plugin, pluginData) suiteSize = numel(pluginData.TestSuite); groupNumber = pluginData.Group; fprintf('### Running a total of %d tests in group %d\n', ... suiteSize, groupNumber); plugin.NumPassingAssertions = 0; plugin.NumFailingAssertions = 0; runTestSuite@matlab.unittest.plugins.TestRunnerPlugin(... plugin, pluginData); assertionStruct = struct('Passing', plugin.NumPassingAssertions, ... 'Failing', plugin.NumFailingAssertions); plugin.storeIn(pluginData.CommunicationBuffer, assertionStruct); end function reportFinalizedSuite(plugin, pluginData) assertionStruct = plugin.retrieveFrom(pluginData.CommunicationBuffer); plugin.FinalizedNumPassingAssertions = ... plugin.FinalizedNumPassingAssertions + assertionStruct.Passing; plugin.FinalizedNumFailingAssertions = ... plugin.FinalizedNumFailingAssertions + assertionStruct.Failing; reportFinalizedSuite@matlab.unittest.plugins.TestRunnerPlugin(... plugin, pluginData); end end methods (Access = private) function incrementPassingAssertionsCount(plugin) plugin.NumPassingAssertions = plugin.NumPassingAssertions + 1; end function incrementFailingAssertionsCount(plugin) plugin.NumFailingAssertions = plugin.NumFailingAssertions + 1; end function printAssertionSummary(plugin) fprintf('%s\n', repmat('_', 1, 30)) fprintf('Total Assertions: %d\n', plugin.FinalizedNumPassingAssertions + ... plugin.FinalizedNumFailingAssertions) fprintf('\t%d Passed, %d Failed\n', plugin.FinalizedNumPassingAssertions, ... plugin.FinalizedNumFailingAssertions) end end end
В вашей текущей папке создайте файл с именем ExampleTest.m
содержа следующий параметризованный тестовый класс. Этот класс приводит к 300 Test
элементы, 100 из которых являются тестами утверждения, которые сравнивают псевдослучайные целые числа между 1 и 10.
classdef ExampleTest < matlab.unittest.TestCase properties (TestParameter) num1 = repmat({@()randi(10)}, 1, 10); num2 = repmat({@()randi(10)}, 1, 10); end methods(Test) function testAssert(testCase, num1, num2) testCase.assertNotEqual(num1(), num2()) end function testVerify(testCase, num1, num2) testCase.verifyNotEqual(num1(), num2()) end function testAssume(testCase, num1, num2) testCase.assumeNotEqual(num1(), num2()) end end end
В командной строке создайте тестовый набор из ExampleTest
класс.
import matlab.unittest.TestSuite import matlab.unittest.TestRunner suite = TestSuite.fromClass(?ExampleTest);
Создайте TestRunner
экземпляр без плагинов. Этот код создает тихого бегуна и дает вам контроль над установленными плагинами.
runner = TestRunner.withNoPlugins;
Добавьте AssertionCountingPlugin
бегуну и запущенный тесты параллельно. Можно также запустить те же тесты в последовательном режиме, если вы вызываете run
метод на бегуне.
runner.addPlugin(AssertionCountingPlugin) result = runner.runInParallel(suite);
Starting parallel pool (parpool) using the 'local' profile ... Connected to the parallel pool (number of workers: 6). ## Running a total of 300 tests Split tests into 18 groups and running them on 6 workers. ---------------- Finished Group 6 ---------------- ### Running a total of 18 tests in group 6 ---------------- Finished Group 1 ---------------- ### Running a total of 20 tests in group 1 ---------------- Finished Group 2 ---------------- ### Running a total of 20 tests in group 2 ---------------- Finished Group 3 ---------------- ### Running a total of 19 tests in group 3 ---------------- Finished Group 4 ---------------- ### Running a total of 19 tests in group 4 ---------------- Finished Group 5 ---------------- ### Running a total of 18 tests in group 5 ---------------- Finished Group 7 ---------------- ### Running a total of 18 tests in group 7 ---------------- Finished Group 8 ---------------- ### Running a total of 17 tests in group 8 ---------------- Finished Group 9 ---------------- ### Running a total of 17 tests in group 9 ----------------- Finished Group 10 ----------------- ### Running a total of 17 tests in group 10 ----------------- Finished Group 11 ----------------- ### Running a total of 16 tests in group 11 ----------------- Finished Group 12 ----------------- ### Running a total of 16 tests in group 12 ----------------- Finished Group 15 ----------------- ### Running a total of 15 tests in group 15 ----------------- Finished Group 14 ----------------- ### Running a total of 15 tests in group 14 ----------------- Finished Group 17 ----------------- ### Running a total of 14 tests in group 17 ----------------- Finished Group 16 ----------------- ### Running a total of 14 tests in group 16 ----------------- Finished Group 13 ----------------- ### Running a total of 15 tests in group 13 ----------------- Finished Group 18 ----------------- ### Running a total of 12 tests in group 18 ## Done running tests ______________________________ Total Assertions: 100 88 Passed, 12 Failed
addlistener
| matlab.unittest.TestCase
| matlab.unittest.TestResult
| matlab.unittest.TestRunner
| matlab.unittest.TestSuite
| matlab.unittest.fixtures.Fixture
| matlab.unittest.plugins.Parallelizable
| matlab.unittest.plugins.TestRunnerPlugin
| runInParallel