diff --git a/README.md b/README.md
index 1041371..1e655e6 100644
--- a/README.md
+++ b/README.md
@@ -4,7 +4,7 @@
[](https://matlab.mathworks.com/open/github/v1?repo=mathworks/test-framework-extensions&project=TestFrameworkExtensions.prj)
[](https://github.com/mathworks/test-framework-extensions/actions/workflows/testext-ci.yml)
-The Test Framework Extensions toolbox provides a number of custom [constraints](https://www.mathworks.com/help/matlab/ref/matlab.unittest.constraints.constraint-class.html) and [fixtures](https://www.mathworks.com/help/matlab/ref/matlab.unittest.fixtures.fixture-class.html) to aid the testing of MATLAB code.
+The Test Framework Extensions toolbox provides a number of custom [constraints](https://www.mathworks.com/help/matlab/ref/matlab.unittest.constraints.constraint-class.html), [fixtures](https://www.mathworks.com/help/matlab/ref/matlab.unittest.fixtures.fixture-class.html), and [plugins](https://www.mathworks.com/help/matlab/ref/matlab.unittest.plugins.testrunnerplugin-class.html) to aid the testing of MATLAB code.
### Constraints
* `DatetimeTolerance` - allow non-exact matching of datetimes and durations.
@@ -24,7 +24,13 @@ The Test Framework Extensions toolbox provides a number of custom [constraints](
* `SimulinkModelFixture` - load a Simulink model and close it on teardown.
* `SuppressParpoolAutocreateFixture` - suppress the automatic creation of parpools and restore the original setting in teardown.
-The documentation provides examples of how to use these constraints and fixtures.
+### Plugins
+* `FailOnSpecificWarningsPlugin` - fail tests that issue selected warnings.
+
+### Alias
+* `Testable` - alias for [`matlab.uitest.TestCase`](https://www.mathworks.com/help/matlab/ref/matlab.uitest.testcase-class.html)
+
+The documentation provides examples of how to use these constraints, fixtures, and plugins.
See also the [database testing framework](https://www.mathworks.com/matlabcentral/fileexchange/77101-database-testing-framework).
diff --git a/buildfile.m b/buildfile.m
index 0c0756f..ea29afa 100644
--- a/buildfile.m
+++ b/buildfile.m
@@ -32,7 +32,7 @@
% Test task
plan("test") = TestTask( test, ...
SourceFiles=tbx, ...
- Strict=true, ...
+ Strict=false, ...
Dependencies="check" );
% Documentation task
diff --git a/resources/project/Root.type.Files/tbx.type.File/testext.type.File/plugins.type.File.xml b/resources/project/Root.type.Files/tbx.type.File/testext.type.File/plugins.type.File.xml
new file mode 100644
index 0000000..4356a6a
--- /dev/null
+++ b/resources/project/Root.type.Files/tbx.type.File/testext.type.File/plugins.type.File.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/resources/project/Root.type.Files/tbx.type.File/testext.type.File/plugins.type.File/1.type.DIR_SIGNIFIER.xml b/resources/project/Root.type.Files/tbx.type.File/testext.type.File/plugins.type.File/1.type.DIR_SIGNIFIER.xml
new file mode 100644
index 0000000..4356a6a
--- /dev/null
+++ b/resources/project/Root.type.Files/tbx.type.File/testext.type.File/plugins.type.File/1.type.DIR_SIGNIFIER.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/resources/project/Root.type.Files/tbx.type.File/testext.type.File/plugins.type.File/FailOnSpecificWarningsPlugin.m.type.File.xml b/resources/project/Root.type.Files/tbx.type.File/testext.type.File/plugins.type.File/FailOnSpecificWarningsPlugin.m.type.File.xml
new file mode 100644
index 0000000..99772b4
--- /dev/null
+++ b/resources/project/Root.type.Files/tbx.type.File/testext.type.File/plugins.type.File/FailOnSpecificWarningsPlugin.m.type.File.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/resources/project/Root.type.Files/tbx.type.File/testextdoc.type.File/Alias.md.type.File.xml b/resources/project/Root.type.Files/tbx.type.File/testextdoc.type.File/Alias.md.type.File.xml
new file mode 100644
index 0000000..4356a6a
--- /dev/null
+++ b/resources/project/Root.type.Files/tbx.type.File/testextdoc.type.File/Alias.md.type.File.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/resources/project/Root.type.Files/tbx.type.File/testextdoc.type.File/Constraints.md.type.File.xml b/resources/project/Root.type.Files/tbx.type.File/testextdoc.type.File/Constraints.md.type.File.xml
new file mode 100644
index 0000000..4356a6a
--- /dev/null
+++ b/resources/project/Root.type.Files/tbx.type.File/testextdoc.type.File/Constraints.md.type.File.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/resources/project/Root.type.Files/tbx.type.File/testextdoc.type.File/FailOnSpecificWarningsPlugin.md.type.File.xml b/resources/project/Root.type.Files/tbx.type.File/testextdoc.type.File/FailOnSpecificWarningsPlugin.md.type.File.xml
new file mode 100644
index 0000000..7825d83
--- /dev/null
+++ b/resources/project/Root.type.Files/tbx.type.File/testextdoc.type.File/FailOnSpecificWarningsPlugin.md.type.File.xml
@@ -0,0 +1,2 @@
+
+
diff --git a/resources/project/Root.type.Files/tbx.type.File/testextdoc.type.File/Fixtures.md.type.File.xml b/resources/project/Root.type.Files/tbx.type.File/testextdoc.type.File/Fixtures.md.type.File.xml
new file mode 100644
index 0000000..4356a6a
--- /dev/null
+++ b/resources/project/Root.type.Files/tbx.type.File/testextdoc.type.File/Fixtures.md.type.File.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/resources/project/Root.type.Files/tbx.type.File/testextdoc.type.File/Plugins.md.type.File.xml b/resources/project/Root.type.Files/tbx.type.File/testextdoc.type.File/Plugins.md.type.File.xml
new file mode 100644
index 0000000..4356a6a
--- /dev/null
+++ b/resources/project/Root.type.Files/tbx.type.File/testextdoc.type.File/Plugins.md.type.File.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/resources/project/Root.type.Files/tests.type.File/plugins.type.File.xml b/resources/project/Root.type.Files/tests.type.File/plugins.type.File.xml
new file mode 100644
index 0000000..4356a6a
--- /dev/null
+++ b/resources/project/Root.type.Files/tests.type.File/plugins.type.File.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/resources/project/Root.type.Files/tests.type.File/plugins.type.File/1.type.DIR_SIGNIFIER.xml b/resources/project/Root.type.Files/tests.type.File/plugins.type.File/1.type.DIR_SIGNIFIER.xml
new file mode 100644
index 0000000..4356a6a
--- /dev/null
+++ b/resources/project/Root.type.Files/tests.type.File/plugins.type.File/1.type.DIR_SIGNIFIER.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/resources/project/Root.type.Files/tests.type.File/plugins.type.File/FailOnSpecificWarningsPluginTest.m.type.File.xml b/resources/project/Root.type.Files/tests.type.File/plugins.type.File/FailOnSpecificWarningsPluginTest.m.type.File.xml
new file mode 100644
index 0000000..378b613
--- /dev/null
+++ b/resources/project/Root.type.Files/tests.type.File/plugins.type.File/FailOnSpecificWarningsPluginTest.m.type.File.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/resources/project/Root.type.Files/tests.type.File/testresources.type.File/failOnSpecificWarningsPlugin.type.File.xml b/resources/project/Root.type.Files/tests.type.File/testresources.type.File/failOnSpecificWarningsPlugin.type.File.xml
new file mode 100644
index 0000000..b8927b2
--- /dev/null
+++ b/resources/project/Root.type.Files/tests.type.File/testresources.type.File/failOnSpecificWarningsPlugin.type.File.xml
@@ -0,0 +1,2 @@
+
+
diff --git a/resources/project/Root.type.Files/tests.type.File/testresources.type.File/failOnSpecificWarningsPlugin.type.File/1.type.DIR_SIGNIFIER.xml b/resources/project/Root.type.Files/tests.type.File/testresources.type.File/failOnSpecificWarningsPlugin.type.File/1.type.DIR_SIGNIFIER.xml
new file mode 100644
index 0000000..b8927b2
--- /dev/null
+++ b/resources/project/Root.type.Files/tests.type.File/testresources.type.File/failOnSpecificWarningsPlugin.type.File/1.type.DIR_SIGNIFIER.xml
@@ -0,0 +1,2 @@
+
+
diff --git a/resources/project/Root.type.Files/tests.type.File/testresources.type.File/failOnSpecificWarningsPlugin.type.File/fixtures.type.File.xml b/resources/project/Root.type.Files/tests.type.File/testresources.type.File/failOnSpecificWarningsPlugin.type.File/fixtures.type.File.xml
new file mode 100644
index 0000000..b8927b2
--- /dev/null
+++ b/resources/project/Root.type.Files/tests.type.File/testresources.type.File/failOnSpecificWarningsPlugin.type.File/fixtures.type.File.xml
@@ -0,0 +1,2 @@
+
+
diff --git a/resources/project/Root.type.Files/tests.type.File/testresources.type.File/failOnSpecificWarningsPlugin.type.File/fixtures.type.File/1.type.DIR_SIGNIFIER.xml b/resources/project/Root.type.Files/tests.type.File/testresources.type.File/failOnSpecificWarningsPlugin.type.File/fixtures.type.File/1.type.DIR_SIGNIFIER.xml
new file mode 100644
index 0000000..b8927b2
--- /dev/null
+++ b/resources/project/Root.type.Files/tests.type.File/testresources.type.File/failOnSpecificWarningsPlugin.type.File/fixtures.type.File/1.type.DIR_SIGNIFIER.xml
@@ -0,0 +1,2 @@
+
+
diff --git a/resources/project/Root.type.Files/tests.type.File/testresources.type.File/failOnSpecificWarningsPlugin.type.File/fixtures.type.File/TargetWarningSharedFixture.m.type.File.xml b/resources/project/Root.type.Files/tests.type.File/testresources.type.File/failOnSpecificWarningsPlugin.type.File/fixtures.type.File/TargetWarningSharedFixture.m.type.File.xml
new file mode 100644
index 0000000..eb4136b
--- /dev/null
+++ b/resources/project/Root.type.Files/tests.type.File/testresources.type.File/failOnSpecificWarningsPlugin.type.File/fixtures.type.File/TargetWarningSharedFixture.m.type.File.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/resources/project/Root.type.Files/tests.type.File/testresources.type.File/failOnSpecificWarningsPlugin.type.File/scenarioTests.type.File.xml b/resources/project/Root.type.Files/tests.type.File/testresources.type.File/failOnSpecificWarningsPlugin.type.File/scenarioTests.type.File.xml
new file mode 100644
index 0000000..b8927b2
--- /dev/null
+++ b/resources/project/Root.type.Files/tests.type.File/testresources.type.File/failOnSpecificWarningsPlugin.type.File/scenarioTests.type.File.xml
@@ -0,0 +1,2 @@
+
+
diff --git a/resources/project/Root.type.Files/tests.type.File/testresources.type.File/failOnSpecificWarningsPlugin.type.File/scenarioTests.type.File/1.type.DIR_SIGNIFIER.xml b/resources/project/Root.type.Files/tests.type.File/testresources.type.File/failOnSpecificWarningsPlugin.type.File/scenarioTests.type.File/1.type.DIR_SIGNIFIER.xml
new file mode 100644
index 0000000..b8927b2
--- /dev/null
+++ b/resources/project/Root.type.Files/tests.type.File/testresources.type.File/failOnSpecificWarningsPlugin.type.File/scenarioTests.type.File/1.type.DIR_SIGNIFIER.xml
@@ -0,0 +1,2 @@
+
+
diff --git a/resources/project/Root.type.Files/tests.type.File/testresources.type.File/failOnSpecificWarningsPlugin.type.File/scenarioTests.type.File/ExpectedTargetWarningScenarioTest.m.type.File.xml b/resources/project/Root.type.Files/tests.type.File/testresources.type.File/failOnSpecificWarningsPlugin.type.File/scenarioTests.type.File/ExpectedTargetWarningScenarioTest.m.type.File.xml
new file mode 100644
index 0000000..eb4136b
--- /dev/null
+++ b/resources/project/Root.type.Files/tests.type.File/testresources.type.File/failOnSpecificWarningsPlugin.type.File/scenarioTests.type.File/ExpectedTargetWarningScenarioTest.m.type.File.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/resources/project/Root.type.Files/tests.type.File/testresources.type.File/failOnSpecificWarningsPlugin.type.File/scenarioTests.type.File/SecondWarningScenarioTest.m.type.File.xml b/resources/project/Root.type.Files/tests.type.File/testresources.type.File/failOnSpecificWarningsPlugin.type.File/scenarioTests.type.File/SecondWarningScenarioTest.m.type.File.xml
new file mode 100644
index 0000000..eb4136b
--- /dev/null
+++ b/resources/project/Root.type.Files/tests.type.File/testresources.type.File/failOnSpecificWarningsPlugin.type.File/scenarioTests.type.File/SecondWarningScenarioTest.m.type.File.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/resources/project/Root.type.Files/tests.type.File/testresources.type.File/failOnSpecificWarningsPlugin.type.File/scenarioTests.type.File/SharedFixtureWarningScenarioTest.m.type.File.xml b/resources/project/Root.type.Files/tests.type.File/testresources.type.File/failOnSpecificWarningsPlugin.type.File/scenarioTests.type.File/SharedFixtureWarningScenarioTest.m.type.File.xml
new file mode 100644
index 0000000..eb4136b
--- /dev/null
+++ b/resources/project/Root.type.Files/tests.type.File/testresources.type.File/failOnSpecificWarningsPlugin.type.File/scenarioTests.type.File/SharedFixtureWarningScenarioTest.m.type.File.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/resources/project/Root.type.Files/tests.type.File/testresources.type.File/failOnSpecificWarningsPlugin.type.File/scenarioTests.type.File/TargetWarningScenarioTest.m.type.File.xml b/resources/project/Root.type.Files/tests.type.File/testresources.type.File/failOnSpecificWarningsPlugin.type.File/scenarioTests.type.File/TargetWarningScenarioTest.m.type.File.xml
new file mode 100644
index 0000000..eb4136b
--- /dev/null
+++ b/resources/project/Root.type.Files/tests.type.File/testresources.type.File/failOnSpecificWarningsPlugin.type.File/scenarioTests.type.File/TargetWarningScenarioTest.m.type.File.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/resources/project/Root.type.Files/tests.type.File/testresources.type.File/failOnSpecificWarningsPlugin.type.File/scenarioTests.type.File/TestClassSetupWarningScenarioTest.m.type.File.xml b/resources/project/Root.type.Files/tests.type.File/testresources.type.File/failOnSpecificWarningsPlugin.type.File/scenarioTests.type.File/TestClassSetupWarningScenarioTest.m.type.File.xml
new file mode 100644
index 0000000..eb4136b
--- /dev/null
+++ b/resources/project/Root.type.Files/tests.type.File/testresources.type.File/failOnSpecificWarningsPlugin.type.File/scenarioTests.type.File/TestClassSetupWarningScenarioTest.m.type.File.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/resources/project/Root.type.Files/tests.type.File/testresources.type.File/failOnSpecificWarningsPlugin.type.File/scenarioTests.type.File/TestClassTeardownWarningScenarioTest.m.type.File.xml b/resources/project/Root.type.Files/tests.type.File/testresources.type.File/failOnSpecificWarningsPlugin.type.File/scenarioTests.type.File/TestClassTeardownWarningScenarioTest.m.type.File.xml
new file mode 100644
index 0000000..eb4136b
--- /dev/null
+++ b/resources/project/Root.type.Files/tests.type.File/testresources.type.File/failOnSpecificWarningsPlugin.type.File/scenarioTests.type.File/TestClassTeardownWarningScenarioTest.m.type.File.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/resources/project/Root.type.Files/tests.type.File/testresources.type.File/failOnSpecificWarningsPlugin.type.File/scenarioTests.type.File/UnrelatedWarningScenarioTest.m.type.File.xml b/resources/project/Root.type.Files/tests.type.File/testresources.type.File/failOnSpecificWarningsPlugin.type.File/scenarioTests.type.File/UnrelatedWarningScenarioTest.m.type.File.xml
new file mode 100644
index 0000000..eb4136b
--- /dev/null
+++ b/resources/project/Root.type.Files/tests.type.File/testresources.type.File/failOnSpecificWarningsPlugin.type.File/scenarioTests.type.File/UnrelatedWarningScenarioTest.m.type.File.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/resources/project/Root.type.Files/tests.type.File/testresources.type.File/failOnSpecificWarningsPlugin.type.File/scenarioTests.type.File/WarningFreeScenarioTest.m.type.File.xml b/resources/project/Root.type.Files/tests.type.File/testresources.type.File/failOnSpecificWarningsPlugin.type.File/scenarioTests.type.File/WarningFreeScenarioTest.m.type.File.xml
new file mode 100644
index 0000000..eb4136b
--- /dev/null
+++ b/resources/project/Root.type.Files/tests.type.File/testresources.type.File/failOnSpecificWarningsPlugin.type.File/scenarioTests.type.File/WarningFreeScenarioTest.m.type.File.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/resources/project/Root.type.ProjectPath/6d5d1258-7d50-4f83-a71c-6f87186394b7.type.Reference.xml b/resources/project/Root.type.ProjectPath/6d5d1258-7d50-4f83-a71c-6f87186394b7.type.Reference.xml
new file mode 100644
index 0000000..686e785
--- /dev/null
+++ b/resources/project/Root.type.ProjectPath/6d5d1258-7d50-4f83-a71c-6f87186394b7.type.Reference.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/resources/project/Root.type.ProjectPath/d54dd5af-6a8b-4769-936a-dcd20d2644e4.type.Reference.xml b/resources/project/Root.type.ProjectPath/d54dd5af-6a8b-4769-936a-dcd20d2644e4.type.Reference.xml
new file mode 100644
index 0000000..42196be
--- /dev/null
+++ b/resources/project/Root.type.ProjectPath/d54dd5af-6a8b-4769-936a-dcd20d2644e4.type.Reference.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/tbx/testext/Contents.m b/tbx/testext/Contents.m
index 86fa31a..715a451 100644
--- a/tbx/testext/Contents.m
+++ b/tbx/testext/Contents.m
@@ -1,5 +1,5 @@
% Test Framework Extensions
-% Version 1.0.6 (R2026a) 13-Jul-2026
+% Version 1.0.7 (R2026a) 22-Jul-2026
%
% Constraints
%
@@ -21,8 +21,12 @@
% SimulinkModelFixture
% SuppressParpoolAutocreateFixture
%
+% Plugins
+%
+% FailOnSpecificWarningsPlugin
+%
% Alias
%
% Testable
-% Copyright 2026 The MathWorks, Inc.
\ No newline at end of file
+% Copyright 2026 The MathWorks, Inc.
diff --git a/tbx/testext/plugins/FailOnSpecificWarningsPlugin.m b/tbx/testext/plugins/FailOnSpecificWarningsPlugin.m
new file mode 100644
index 0000000..4d58b07
--- /dev/null
+++ b/tbx/testext/plugins/FailOnSpecificWarningsPlugin.m
@@ -0,0 +1,273 @@
+classdef FailOnSpecificWarningsPlugin < matlab.unittest.plugins.QualifyingPlugin & ...
+ matlab.unittest.plugins.Parallelizable
+ %FailOnSpecificWarningsPlugin - Fail tests that issue selected warnings
+ % PLUGIN = FailOnSpecificWarningsPlugin(IDENTIFIERS) creates a
+ % plugin that fails tests when code issues a warning whose identifier
+ % is listed in IDENTIFIERS. Warnings verified with VERIFYWARNING are
+ % ignored.
+ %
+ % FailOnSpecificWarningsPlugin functions:
+ % FailOnSpecificWarningsPlugin - Create plugin that fails on warnings
+ %
+ % FailOnSpecificWarningsPlugin properties:
+ % WarningIdentifiers - Warning identifiers that fail tests
+ %
+ % See also matlab.unittest.TestRunner, verifyWarning
+
+ % Copyright 2026 The MathWorks, Inc.
+
+ properties ( SetAccess = immutable )
+ WarningIdentifiers string % Warning identifiers that fail tests.
+ end % properties ( SetAccess = immutable )
+
+ properties ( Access = private )
+ Logger
+ LocalWarnings
+ TestClassSetupWarnings
+ SharedTestFixtureWarningsStack
+ end % properties ( Access = private )
+
+ methods
+
+ function plugin = FailOnSpecificWarningsPlugin(identifiers)
+
+ arguments
+ identifiers {mustBeText}
+ end % arguments
+
+ identifiers = string(identifiers);
+ identifiers = identifiers(:).';
+ validateWarningIdentifiers(identifiers);
+
+ plugin.WarningIdentifiers = identifiers;
+ end % constructor
+
+ end % methods
+
+ methods ( Hidden, Sealed )
+
+ function tf = supportsParallelThreadPool_(~)
+
+ tf = true;
+
+ end % supportsParallelThreadPool_
+
+ end % methods ( Hidden, Sealed )
+
+ methods ( Hidden, Access = protected )
+
+ function runTestSuite(plugin, pluginData)
+
+ import matlab.unittest.internal.ExpectedWarningsNotifier
+ import matlab.unittest.internal.constraints.WarningLogger
+
+ plugin.Logger = WarningLogger;
+ plugin.resetSharedTestFixtureWarningsStack;
+
+ expectedWarningsListener = ExpectedWarningsNotifier.createExpectedWarningsListener( ...
+ @plugin.recordExpectedWarning); %#ok
+
+ runTestSuite@matlab.unittest.plugins.QualifyingPlugin(plugin, pluginData);
+
+ end % runTestSuite
+
+ function fixture = createSharedTestFixture(plugin, pluginData)
+
+ fixture = createSharedTestFixture@matlab.unittest.plugins.QualifyingPlugin(plugin, pluginData);
+ plugin.initializeSharedFixtureWarningStackForNewSharedTestFixture;
+
+ end % createSharedTestFixture
+
+ function setupSharedTestFixture(plugin, pluginData)
+
+ plugin.startLoggingWarnings;
+ cleanup = matlab.unittest.internal.Teardownable;
+ cleanup.addTeardown(@()plugin.stopLoggingWarningsInSharedTestFixtureSetup);
+ setupSharedTestFixture@matlab.unittest.plugins.QualifyingPlugin(plugin, pluginData);
+
+ end % setupSharedTestFixture
+
+ function teardownSharedTestFixture(plugin, pluginData)
+
+ setupWarnings = plugin.peekSharedTestFixtureWarningsStack;
+ plugin.popSharedTestFixtureWarningsStack;
+
+ plugin.startLoggingWarnings;
+ teardownSharedTestFixture@matlab.unittest.plugins.QualifyingPlugin(plugin, pluginData);
+ teardownWarnings = plugin.stopLoggingWarnings;
+
+ plugin.assertWarningFree(pluginData, [setupWarnings, teardownWarnings]);
+
+ end % teardownSharedTestFixture
+
+ function setupTestClass(plugin, pluginData)
+
+ plugin.startLoggingWarnings;
+ cleanup = matlab.unittest.internal.Teardownable;
+ cleanup.addTeardown(@()plugin.stopLoggingWarningsInTestClassSetup);
+ setupTestClass@matlab.unittest.plugins.QualifyingPlugin(plugin, pluginData);
+
+ end % setupTestClass
+
+ function teardownTestClass(plugin, pluginData)
+
+ plugin.startLoggingWarnings;
+ teardownTestClass@matlab.unittest.plugins.QualifyingPlugin(plugin, pluginData);
+ teardownWarnings = plugin.stopLoggingWarnings;
+
+ warnings = [plugin.TestClassSetupWarnings, teardownWarnings];
+ plugin.verifyWarningFree(pluginData, warnings);
+
+ end % teardownTestClass
+
+ function setupTestMethod(plugin, pluginData)
+
+ plugin.startLoggingWarnings;
+ setupTestMethod@matlab.unittest.plugins.QualifyingPlugin(plugin, pluginData);
+
+ end % setupTestMethod
+
+ function teardownTestMethod(plugin, pluginData)
+
+ teardownTestMethod@matlab.unittest.plugins.QualifyingPlugin(plugin, pluginData);
+ plugin.verifyWarningFree(pluginData, plugin.stopLoggingWarnings);
+
+ end % teardownTestMethod
+
+ end % methods ( Hidden, Access = protected )
+
+ methods ( Access = private )
+
+ function startLoggingWarnings(plugin)
+
+ import matlab.internal.diagnostic.Warning
+
+ plugin.LocalWarnings = Warning.empty;
+ plugin.Logger.clear;
+ plugin.Logger.start;
+
+ end % startLoggingWarnings
+
+ function warnings = stopLoggingWarnings(plugin)
+
+ plugin.Logger.stop;
+ plugin.makeWarningsLocal;
+ plugin.keepOnlySpecifiedWarnings;
+ warnings = plugin.LocalWarnings;
+
+ end % stopLoggingWarnings
+
+ function stopLoggingWarningsInSharedTestFixtureSetup(plugin)
+
+ warnings = plugin.stopLoggingWarnings;
+ plugin.replaceArrayAtTopOfSharedFixtureStack(warnings);
+
+ end % stopLoggingWarningsInSharedTestFixtureSetup
+
+ function stopLoggingWarningsInTestClassSetup(plugin)
+
+ plugin.TestClassSetupWarnings = plugin.stopLoggingWarnings;
+
+ end % stopLoggingWarningsInTestClassSetup
+
+ function recordExpectedWarning(plugin, expectedWarnings)
+
+ plugin.makeWarningsLocal;
+ plugin.removeExpectedWarningsFromLocalWarnings(expectedWarnings);
+
+ end % recordExpectedWarning
+
+ function makeWarningsLocal(plugin)
+
+ plugin.LocalWarnings = [plugin.LocalWarnings, plugin.Logger.Warnings];
+ plugin.Logger.clear;
+
+ end % makeWarningsLocal
+
+ function removeExpectedWarningsFromLocalWarnings(plugin, expectedWarnings)
+
+ plugin.LocalWarnings(ismember(plugin.LocalWarnings, expectedWarnings)) = [];
+
+ end % removeExpectedWarningsFromLocalWarnings
+
+ function keepOnlySpecifiedWarnings(plugin)
+
+ identifiers = string({plugin.LocalWarnings.identifier});
+ plugin.LocalWarnings(~ismember(identifiers, plugin.WarningIdentifiers)) = [];
+
+ end % keepOnlySpecifiedWarnings
+
+ function assertWarningFree(plugin, pluginData, warnings)
+
+ import matlab.unittest.internal.plugins.IsWarningFree
+ import matlab.unittest.internal.plugins.WarningHistory
+
+ history = WarningHistory(pluginData.Name, warnings);
+ plugin.assertUsing(pluginData.QualificationContext, history, IsWarningFree);
+
+ end % assertWarningFree
+
+ function verifyWarningFree(plugin, pluginData, warnings)
+
+ import matlab.unittest.internal.plugins.IsWarningFree
+ import matlab.unittest.internal.plugins.WarningHistory
+
+ history = WarningHistory(pluginData.Name, warnings);
+ plugin.verifyUsing(pluginData.QualificationContext, history, IsWarningFree);
+
+ end % verifyWarningFree
+
+ function resetSharedTestFixtureWarningsStack(plugin)
+
+ plugin.SharedTestFixtureWarningsStack = {};
+
+ end % resetSharedTestFixtureWarningsStack
+
+ function initializeSharedFixtureWarningStackForNewSharedTestFixture(plugin)
+
+ import matlab.internal.diagnostic.Warning
+
+ plugin.SharedTestFixtureWarningsStack = [{Warning.empty(1, 0)}, ...
+ plugin.SharedTestFixtureWarningsStack];
+
+ end % initializeSharedFixtureWarningStackForNewSharedTestFixture
+
+ function replaceArrayAtTopOfSharedFixtureStack(plugin, warnings)
+
+ plugin.SharedTestFixtureWarningsStack{1} = warnings;
+
+ end % replaceArrayAtTopOfSharedFixtureStack
+
+ function warnings = peekSharedTestFixtureWarningsStack(plugin)
+
+ warnings = plugin.SharedTestFixtureWarningsStack{1};
+
+ end % peekSharedTestFixtureWarningsStack
+
+ function popSharedTestFixtureWarningsStack(plugin)
+
+ plugin.SharedTestFixtureWarningsStack(1) = [];
+
+ end % popSharedTestFixtureWarningsStack
+
+ end % methods ( Access = private )
+
+end % classdef
+
+function validateWarningIdentifiers(identifiers)
+
+if isempty(identifiers)
+ error("FailOnSpecificWarningsPlugin:EmptyIdentifiers", ...
+ "Specify at least one warning identifier.");
+end % if
+
+invalidIdentifiers = identifiers(strlength(identifiers) == 0 | ...
+ arrayfun(@(id)isempty(regexp(id, ...
+ "^[A-Za-z]\w*(?::[A-Za-z]\w*)+$", "once")), identifiers));
+
+if ~isempty(invalidIdentifiers)
+ error("FailOnSpecificWarningsPlugin:InvalidIdentifier", ...
+ "Invalid warning identifier: %s", invalidIdentifiers(1));
+end % if
+
+end % validateWarningIdentifiers
diff --git a/tbx/testextdoc/Alias.md b/tbx/testextdoc/Alias.md
new file mode 100644
index 0000000..cdd87a9
--- /dev/null
+++ b/tbx/testextdoc/Alias.md
@@ -0,0 +1,16 @@
+# Alias
+
+Convenience aliases for commonly used MATLAB testing classes.
+
+## Available Aliases
+
+* [`Testable`](Testable.md) - alias for
+ [`matlab.uitest.TestCase`](
+ https://www.mathworks.com/help/matlab/ref/matlab.uitest.testcase-class.html)
+
+## See Also
+
+* [Test Framework Extensions Toolbox](index.md)
+* [Constraints](Constraints.md)
+* [Fixtures](Fixtures.md)
+* [Plugins](Plugins.md)
diff --git a/tbx/testextdoc/Changelog.md b/tbx/testextdoc/Changelog.md
index f169d89..c340aed 100644
--- a/tbx/testextdoc/Changelog.md
+++ b/tbx/testextdoc/Changelog.md
@@ -1,5 +1,10 @@
# Release notes
+## Version 1.0.7
+
+* Added `FailOnSpecificWarningsPlugin`
+* Added landing pages for documentation categories
+
## Version 1.0.6
* Added `Testable` alias
diff --git a/tbx/testextdoc/Constraints.md b/tbx/testextdoc/Constraints.md
new file mode 100644
index 0000000..24f9a56
--- /dev/null
+++ b/tbx/testextdoc/Constraints.md
@@ -0,0 +1,31 @@
+# Constraints
+
+Custom constraints for verifying MATLAB test behavior and test data.
+
+## Available Constraints
+
+* [`DatetimeTolerance`](DatetimeTolerance.md) - allow non-exact
+ matching of datetimes and durations.
+* [`HasStringLengthLessThan`](HasStringLengthLessThan.md) - check
+ that string length is less than a set value.
+* [`IsEqualVector`](IsEqualVector.md) - are two vectors equal
+ irrespective of row or column orientation.
+* [`IsEquivalentText`](IsEquivalentText.md) - is text equal
+ irrespective of `string`, `char`, or `cellstr` type.
+* [`IsSamePathAs`](IsSamePathAs.md) - are paths equal irrespective
+ of data type, file separator, and Windows capitalization.
+* [`MatchesStatistically`](MatchesStatistically.md) - are at least
+ a certain percentage of elements equal within a tolerance.
+* [`NotifiesEvent`](NotifiesEvent.md) - check that a function or
+ method call notifies an event.
+* [`NotifiesPropertyEvent`](NotifiesPropertyEvent.md) - check that
+ a function or method call notifies a property event.
+* [`PassesEventData`](PassesEventData.md) - check that a function
+ or method call notifies an event with custom event data.
+
+## See Also
+
+* [Test Framework Extensions Toolbox](index.md)
+* [Fixtures](Fixtures.md)
+* [Plugins](Plugins.md)
+* [Alias](Alias.md)
diff --git a/tbx/testextdoc/FailOnSpecificWarningsPlugin.md b/tbx/testextdoc/FailOnSpecificWarningsPlugin.md
new file mode 100644
index 0000000..cf3275f
--- /dev/null
+++ b/tbx/testextdoc/FailOnSpecificWarningsPlugin.md
@@ -0,0 +1,54 @@
+# `FailOnSpecificWarningsPlugin`
+
+A custom MATLAB unit test plugin that fails tests when selected warning identifiers are issued.
+
+## Overview
+
+`FailOnSpecificWarningsPlugin` is a subclass of [`matlab.unittest.plugins.QualifyingPlugin`](https://www.mathworks.com/help/matlab/ref/matlab.unittest.plugins.qualifyingplugin-class.html) that records warnings during test execution and fails tests only for warning identifiers that you specify. Warnings verified with [`verifyWarning`](https://www.mathworks.com/help/matlab/ref/matlab.unittest.qualifications.verifiable.verifywarning.html) are treated as expected and do not fail the test.
+
+## Properties
+
+| Property | Access | Description |
+|----------------------|-----------|----------------------------------------------|
+| `WarningIdentifiers` | Read-only | Warning identifiers that cause test failure. |
+
+## Constructor
+
+### `FailOnSpecificWarningsPlugin(identifiers)`
+
+- **Description**: Constructs a plugin that fails tests when any warning identifier in `identifiers` is issued.
+- **Inputs**:
+ - `identifiers` (text): Warning identifier or vector of warning identifiers to fail on.
+
+```matlab
+plugin = FailOnSpecificWarningsPlugin("myComponent:DeprecatedWorkflow");
+plugin = FailOnSpecificWarningsPlugin([
+ "myComponent:DeprecatedWorkflow"
+ "myComponent:SlowFallback"
+]);
+```
+
+## Example
+
+```matlab
+import matlab.unittest.TestRunner
+
+suite = testsuite("myTestClass");
+runner = TestRunner.withTextOutput;
+runner.addPlugin(FailOnSpecificWarningsPlugin("myCode:UnexpectedWarning"));
+
+results = runner.run(suite);
+```
+
+## Plugin Behavior
+
+- **Fails a test if**:
+ A warning with one of the configured identifiers is issued during test method setup, test method execution, test method teardown, test class setup, test class teardown, shared fixture setup, or shared fixture teardown.
+- **Allows a test to pass if**:
+ No configured warning is issued, a warning has a different identifier, or the configured warning is expected with `verifyWarning`.
+
+## See Also
+
+- [`matlab.unittest.plugins.QualifyingPlugin`](https://www.mathworks.com/help/matlab/ref/matlab.unittest.plugins.qualifyingplugin-class.html)
+- [`matlab.unittest.TestRunner`](https://www.mathworks.com/help/matlab/ref/matlab.unittest.testrunner-class.html)
+- [`verifyWarning`](https://www.mathworks.com/help/matlab/ref/matlab.unittest.qualifications.verifiable.verifywarning.html)
diff --git a/tbx/testextdoc/FigureFixture.md b/tbx/testextdoc/FigureFixture.md
index 86e2f4f..d30447c 100644
--- a/tbx/testextdoc/FigureFixture.md
+++ b/tbx/testextdoc/FigureFixture.md
@@ -2,6 +2,8 @@
A custom MATLAB unit test fixture for managing the lifecycle of a `uifigure` during testing.
+**Note:** from R2026b onwards, you can use the [`UIFigureFixture`](https://www.mathworks.com/help/matlab/ref/matlab.unittest.fixtures.uifigurefixture-class.html) class provided with MATLAB instead of this custom fixture.
+
## Overview
`FigureFixture` is a subclass of [`matlab.unittest.fixtures.Fixture`](https://www.mathworks.com/help/matlab/ref/matlab.unittest.fixtures.fixture.html) designed to create and clean up a `uifigure` for use in unit tests. It enables tests to use a new figure, optionally configured via name-value arguments, and ensures the figure is deleted after the test completes.
@@ -57,4 +59,5 @@ end
## See Also
- [`matlab.unittest.fixtures.Fixture`](https://www.mathworks.com/help/matlab/ref/matlab.unittest.fixtures.fixture-class.html)
-- [`uifigure`](https://www.mathworks.com/help/matlab/ref/uifigure.html)
\ No newline at end of file
+- [`uifigure`](https://www.mathworks.com/help/matlab/ref/uifigure.html)
+- [`UIFigureFixture`](https://www.mathworks.com/help/matlab/ref/matlab.unittest.fixtures.uifigurefixture-class.html) (available from R2026b)
\ No newline at end of file
diff --git a/tbx/testextdoc/Fixtures.md b/tbx/testextdoc/Fixtures.md
new file mode 100644
index 0000000..7942d05
--- /dev/null
+++ b/tbx/testextdoc/Fixtures.md
@@ -0,0 +1,25 @@
+# Fixtures
+
+Custom fixtures for creating and restoring test state in MATLAB.
+
+## Available Fixtures
+
+* [`FigureFixture`](FigureFixture.md) - create a figure and close
+ it on teardown.
+* [`GridLayoutFixture`](GridLayoutFixture.md) - create a grid
+ layout and delete it on teardown.
+* [`PreferenceFixture`](PreferenceFixture.md) - override a MATLAB
+ preference and restore it on teardown.
+* [`SimulinkModelFixture`](SimulinkModelFixture.md) - load a
+ Simulink model and close it on teardown.
+* [`SuppressParpoolAutocreateFixture`](
+ SuppressParpoolAutocreateFixture.md) - suppress the automatic
+ creation of parpools and restore the original setting in
+ teardown.
+
+## See Also
+
+* [Test Framework Extensions Toolbox](index.md)
+* [Constraints](Constraints.md)
+* [Plugins](Plugins.md)
+* [Alias](Alias.md)
diff --git a/tbx/testextdoc/Plugins.md b/tbx/testextdoc/Plugins.md
new file mode 100644
index 0000000..cb57d6b
--- /dev/null
+++ b/tbx/testextdoc/Plugins.md
@@ -0,0 +1,16 @@
+# Plugins
+
+Custom plugins for changing how the MATLAB test runner behaves.
+
+## Available Plugins
+
+* [`FailOnSpecificWarningsPlugin`](
+ FailOnSpecificWarningsPlugin.md) - fail tests that issue
+ selected warnings.
+
+## See Also
+
+* [Test Framework Extensions Toolbox](index.md)
+* [Constraints](Constraints.md)
+* [Fixtures](Fixtures.md)
+* [Alias](Alias.md)
diff --git a/tbx/testextdoc/helptoc.md b/tbx/testextdoc/helptoc.md
index bc21d6d..c206067 100644
--- a/tbx/testextdoc/helptoc.md
+++ b/tbx/testextdoc/helptoc.md
@@ -1,8 +1,8 @@
# Test Framework Extensions
* [Test Framework Extensions](index.md)
- * [Release notes](changelog.md)
- * [Constraints]()
+ * [Release notes](Changelog.md)
+ * [Constraints](Constraints.md)
* [DatetimeTolerance](DatetimeTolerance.md)
* [HasStringLengthLessThan](HasStringLengthLessThan.md)
* [IsEqualVector](IsEqualVector.md)
@@ -12,11 +12,13 @@
* [NotifiesEvent](NotifiesEvent.md)
* [NotifiesPropertyEvent](NotifiesPropertyEvent.md)
* [PassesEventData](PassesEventData.md)
- * [Fixtures]()
+ * [Fixtures](Fixtures.md)
* [FigureFixture](FigureFixture.md)
* [GridLayoutFixture](GridLayoutFixture.md)
* [PreferenceFixture](PreferenceFixture.md)
* [SimulinkModelFixture](SimulinkModelFixture.md)
* [SuppressParpoolAutocreateFixture](SuppressParpoolAutocreateFixture.md)
- * [Alias]()
+ * [Plugins](Plugins.md)
+ * [FailOnSpecificWarningsPlugin](FailOnSpecificWarningsPlugin.md)
+ * [Alias](Alias.md)
* [Testable](Testable.md)
diff --git a/tbx/testextdoc/index.md b/tbx/testextdoc/index.md
index ca1c817..d86bb41 100644
--- a/tbx/testextdoc/index.md
+++ b/tbx/testextdoc/index.md
@@ -1,8 +1,8 @@
# Test Framework Extensions Toolbox
-The Test Framework Extensions toolbox provides custom [constraints](https://www.mathworks.com/help/matlab/ref/matlab.unittest.constraints.constraint-class.html) and [fixtures](https://www.mathworks.com/help/matlab/ref/matlab.unittest.fixtures.fixture-class.html) to aid the testing of MATLAB code.
+The Test Framework Extensions toolbox provides custom [constraints](https://www.mathworks.com/help/matlab/ref/matlab.unittest.constraints.constraint-class.html), [fixtures](https://www.mathworks.com/help/matlab/ref/matlab.unittest.fixtures.fixture-class.html), and [plugins](https://www.mathworks.com/help/matlab/ref/matlab.unittest.plugins.testrunnerplugin-class.html) to aid the testing of MATLAB code.
-### Constraints
+### [Constraints](Constraints.md)
* [`DatetimeTolerance`](DatetimeTolerance.md) - allow non-exact matching of datetimes and durations.
* [`HasStringLengthLessThan`](HasStringLengthLessThan.md) - check that string length is less than a set value.
* [`IsEqualVector`](IsEqualVector.md) - are two vectors equal irrespective of row or column orientation.
@@ -13,14 +13,17 @@ The Test Framework Extensions toolbox provides custom [constraints](https://www.
* [`NotifiesPropertyEvent`](NotifiesPropertyEvent.md) - check that a function or method call notifies a property event.
* [`PassesEventData`](PassesEventData.md) - check that a function or method call notifies an event with custom event data.
-### Fixtures
+### [Fixtures](Fixtures.md)
* [`FigureFixture`](FigureFixture.md) - create a figure and close it on teardown.
* [`GridLayoutFixture`](GridLayoutFixture.md) - create a grid layout and delete it on teardown.
* [`PreferenceFixture`](PreferenceFixture.md) - override a MATLAB preference and restore it on teardown.
-* [`SimulinkModelFixture`](PreferenceFixture.md) - load a Simulink model and close it on teardown.
+* [`SimulinkModelFixture`](SimulinkModelFixture.md) - load a Simulink model and close it on teardown.
* [`SuppressParpoolAutocreateFixture`](SuppressParpoolAutocreateFixture.md) - suppress the automatic creation of parpools and restore the original setting in teardown.
-### Alias
-* [`Testable`](Testable.md) - alias for `matlab.uitest.TestCase`
+### [Plugins](Plugins.md)
+* [`FailOnSpecificWarningsPlugin`](FailOnSpecificWarningsPlugin.md) - fail tests that issue selected warnings.
-The documentation provides examples of how to use these constraints and fixtures.
\ No newline at end of file
+### [Alias](Alias.md)
+* [`Testable`](Testable.md) - alias for [`matlab.uitest.TestCase`](https://www.mathworks.com/help/matlab/ref/matlab.uitest.testcase-class.html)
+
+The documentation provides examples of how to use these constraints, fixtures, and plugins.
diff --git a/tests/plugins/FailOnSpecificWarningsPluginTest.m b/tests/plugins/FailOnSpecificWarningsPluginTest.m
new file mode 100644
index 0000000..e4f7613
--- /dev/null
+++ b/tests/plugins/FailOnSpecificWarningsPluginTest.m
@@ -0,0 +1,134 @@
+classdef FailOnSpecificWarningsPluginTest < matlab.unittest.TestCase
+ %FailOnSpecificWarningsPluginTest Tests FailOnSpecificWarningsPlugin.
+
+ properties ( Constant )
+ TargetID = "FailOnSpecificWarningsPluginTest:Target"
+ OtherID = "FailOnSpecificWarningsPluginTest:Other"
+ SecondID = "FailOnSpecificWarningsPluginTest:Second"
+ end % properties ( Constant )
+
+ methods ( TestClassSetup )
+
+ function addProjectFoldersToPath(testCase)
+
+ testFolder = fullfile( ...
+ testroot(), "testresources", "failOnSpecificWarningsPlugin" );
+ scenarioTestFolder = fullfile( testFolder, "scenarioTests" );
+ fixtureFolder = fullfile( testFolder, "fixtures" );
+ testCase.applyFixture( ...
+ matlab.unittest.fixtures.PathFixture( scenarioTestFolder ) );
+ testCase.applyFixture( ...
+ matlab.unittest.fixtures.PathFixture( fixtureFolder ) );
+
+ end % addProjectFoldersToPath
+
+ end % methods ( TestClassSetup )
+
+ methods ( Test )
+
+ function warningFreeTestPasses(testCase)
+
+ results = testCase.runScenarioTest( ...
+ "WarningFreeScenarioTest", testCase.TargetID );
+
+ testCase.verifyFalse( any( [results.Failed] ) );
+
+ end % warningFreeTestPasses
+
+ function unrelatedWarningPasses(testCase)
+
+ results = testCase.runScenarioTest( ...
+ "UnrelatedWarningScenarioTest", testCase.TargetID );
+
+ testCase.verifyFalse( any( [results.Failed] ) );
+
+ end % unrelatedWarningPasses
+
+ function targetWarningFails(testCase)
+
+ results = testCase.runScenarioTest( ...
+ "TargetWarningScenarioTest", testCase.TargetID );
+
+ testCase.verifyTrue( any( [results.Failed] ) );
+
+ end % targetWarningFails
+
+ function multipleTargetWarningsFail(testCase)
+
+ results = testCase.runScenarioTest( ...
+ "SecondWarningScenarioTest", ...
+ [testCase.TargetID, testCase.SecondID] );
+
+ testCase.verifyTrue( any( [results.Failed] ) );
+
+ end % multipleTargetWarningsFail
+
+ function expectedTargetWarningPasses(testCase)
+
+ results = testCase.runScenarioTest( ...
+ "ExpectedTargetWarningScenarioTest", testCase.TargetID );
+
+ testCase.verifyFalse( any( [results.Failed] ) );
+
+ end % expectedTargetWarningPasses
+
+ function testClassSetupWarningFails(testCase)
+
+ results = testCase.runScenarioTest( ...
+ "TestClassSetupWarningScenarioTest", testCase.TargetID );
+
+ testCase.verifyTrue( any( [results.Failed] ) );
+
+ end % testClassSetupWarningFails
+
+ function testClassTeardownWarningFails(testCase)
+
+ results = testCase.runScenarioTest( ...
+ "TestClassTeardownWarningScenarioTest", testCase.TargetID );
+
+ testCase.verifyTrue( any( [results.Failed] ) );
+
+ end % testClassTeardownWarningFails
+
+ function sharedFixtureWarningFails(testCase)
+
+ results = testCase.runScenarioTest( ...
+ "SharedFixtureWarningScenarioTest", testCase.TargetID );
+
+ testCase.verifyTrue( any( [results.Failed] ) );
+
+ end % sharedFixtureWarningFails
+
+ function invalidIdentifierErrors(testCase)
+
+ testCase.verifyError( @() FailOnSpecificWarningsPlugin("not valid"), ...
+ "FailOnSpecificWarningsPlugin:InvalidIdentifier");
+
+ end % invalidIdentifierErrors
+
+ function emptyIdentifierErrors(testCase)
+
+ testCase.verifyError( @() FailOnSpecificWarningsPlugin(string.empty), ...
+ "FailOnSpecificWarningsPlugin:EmptyIdentifiers");
+
+ end % emptyIdentifierErrors
+
+ end % methods ( Test )
+
+ methods ( Access = private )
+
+ function results = runScenarioTest(~, scenarioClassName, warningIdentifiers)
+
+ import matlab.unittest.TestRunner
+
+ suite = testsuite(scenarioClassName);
+ runner = TestRunner.withNoPlugins;
+ runner.addPlugin(FailOnSpecificWarningsPlugin(warningIdentifiers));
+
+ results = runner.run(suite);
+
+ end % runScenarioTest
+
+ end % methods ( Access = private )
+
+end % classdef
diff --git a/tests/testresources/failOnSpecificWarningsPlugin/fixtures/TargetWarningSharedFixture.m b/tests/testresources/failOnSpecificWarningsPlugin/fixtures/TargetWarningSharedFixture.m
new file mode 100644
index 0000000..bed9240
--- /dev/null
+++ b/tests/testresources/failOnSpecificWarningsPlugin/fixtures/TargetWarningSharedFixture.m
@@ -0,0 +1,14 @@
+classdef TargetWarningSharedFixture < matlab.unittest.fixtures.Fixture
+
+ methods
+
+ function setup(~)
+
+ warning("FailOnSpecificWarningsPluginTest:Target", ...
+ "Shared fixture target warning.");
+
+ end % setup
+
+ end % methods
+
+end % classdef
diff --git a/tests/testresources/failOnSpecificWarningsPlugin/scenarioTests/ExpectedTargetWarningScenarioTest.m b/tests/testresources/failOnSpecificWarningsPlugin/scenarioTests/ExpectedTargetWarningScenarioTest.m
new file mode 100644
index 0000000..3a711c2
--- /dev/null
+++ b/tests/testresources/failOnSpecificWarningsPlugin/scenarioTests/ExpectedTargetWarningScenarioTest.m
@@ -0,0 +1,20 @@
+classdef ExpectedTargetWarningScenarioTest < matlab.unittest.TestCase
+
+ methods ( Test )
+
+ function testExpectedTargetWarning(testCase)
+
+ testCase.verifyWarning(@() issueTargetWarning, ...
+ "FailOnSpecificWarningsPluginTest:Target");
+
+ end % testExpectedTargetWarning
+
+ end % methods ( Test )
+
+end % classdef
+
+function issueTargetWarning
+
+warning("FailOnSpecificWarningsPluginTest:Target", "Expected target warning.");
+
+end % issueTargetWarning
diff --git a/tests/testresources/failOnSpecificWarningsPlugin/scenarioTests/SecondWarningScenarioTest.m b/tests/testresources/failOnSpecificWarningsPlugin/scenarioTests/SecondWarningScenarioTest.m
new file mode 100644
index 0000000..6017a8b
--- /dev/null
+++ b/tests/testresources/failOnSpecificWarningsPlugin/scenarioTests/SecondWarningScenarioTest.m
@@ -0,0 +1,15 @@
+classdef SecondWarningScenarioTest < matlab.unittest.TestCase
+
+ methods ( Test )
+
+ function testSecondWarning(testCase)
+
+ warning("FailOnSpecificWarningsPluginTest:Second", "Second warning.");
+
+ testCase.verifyTrue(true);
+
+ end % testSecondWarning
+
+ end % methods ( Test )
+
+end % classdef
diff --git a/tests/testresources/failOnSpecificWarningsPlugin/scenarioTests/SharedFixtureWarningScenarioTest.m b/tests/testresources/failOnSpecificWarningsPlugin/scenarioTests/SharedFixtureWarningScenarioTest.m
new file mode 100644
index 0000000..9b0361b
--- /dev/null
+++ b/tests/testresources/failOnSpecificWarningsPlugin/scenarioTests/SharedFixtureWarningScenarioTest.m
@@ -0,0 +1,14 @@
+classdef (SharedTestFixtures={TargetWarningSharedFixture}) ...
+ SharedFixtureWarningScenarioTest < matlab.unittest.TestCase
+
+ methods ( Test )
+
+ function testBody(testCase)
+
+ testCase.verifyTrue(true);
+
+ end % testBody
+
+ end % methods ( Test )
+
+end % classdef
diff --git a/tests/testresources/failOnSpecificWarningsPlugin/scenarioTests/TargetWarningScenarioTest.m b/tests/testresources/failOnSpecificWarningsPlugin/scenarioTests/TargetWarningScenarioTest.m
new file mode 100644
index 0000000..42bd684
--- /dev/null
+++ b/tests/testresources/failOnSpecificWarningsPlugin/scenarioTests/TargetWarningScenarioTest.m
@@ -0,0 +1,15 @@
+classdef TargetWarningScenarioTest < matlab.unittest.TestCase
+
+ methods ( Test )
+
+ function testTargetWarning(testCase)
+
+ warning("FailOnSpecificWarningsPluginTest:Target", "Target warning.");
+
+ testCase.verifyTrue(true);
+
+ end % testTargetWarning
+
+ end % methods ( Test )
+
+end % classdef
diff --git a/tests/testresources/failOnSpecificWarningsPlugin/scenarioTests/TestClassSetupWarningScenarioTest.m b/tests/testresources/failOnSpecificWarningsPlugin/scenarioTests/TestClassSetupWarningScenarioTest.m
new file mode 100644
index 0000000..e25f410
--- /dev/null
+++ b/tests/testresources/failOnSpecificWarningsPlugin/scenarioTests/TestClassSetupWarningScenarioTest.m
@@ -0,0 +1,24 @@
+classdef TestClassSetupWarningScenarioTest < matlab.unittest.TestCase
+
+ methods ( TestClassSetup )
+
+ function issueSetupWarning(~)
+
+ warning("FailOnSpecificWarningsPluginTest:Target", ...
+ "Test class setup target warning.");
+
+ end % issueSetupWarning
+
+ end % methods ( TestClassSetup )
+
+ methods ( Test )
+
+ function testBody(testCase)
+
+ testCase.verifyTrue(true);
+
+ end % testBody
+
+ end % methods ( Test )
+
+end % classdef
diff --git a/tests/testresources/failOnSpecificWarningsPlugin/scenarioTests/TestClassTeardownWarningScenarioTest.m b/tests/testresources/failOnSpecificWarningsPlugin/scenarioTests/TestClassTeardownWarningScenarioTest.m
new file mode 100644
index 0000000..133c736
--- /dev/null
+++ b/tests/testresources/failOnSpecificWarningsPlugin/scenarioTests/TestClassTeardownWarningScenarioTest.m
@@ -0,0 +1,24 @@
+classdef TestClassTeardownWarningScenarioTest < matlab.unittest.TestCase
+
+ methods ( TestClassTeardown )
+
+ function issueTeardownWarning(~)
+
+ warning("FailOnSpecificWarningsPluginTest:Target", ...
+ "Test class teardown target warning.");
+
+ end % issueTeardownWarning
+
+ end % methods ( TestClassTeardown )
+
+ methods ( Test )
+
+ function testBody(testCase)
+
+ testCase.verifyTrue(true);
+
+ end % testBody
+
+ end % methods ( Test )
+
+end % classdef
diff --git a/tests/testresources/failOnSpecificWarningsPlugin/scenarioTests/UnrelatedWarningScenarioTest.m b/tests/testresources/failOnSpecificWarningsPlugin/scenarioTests/UnrelatedWarningScenarioTest.m
new file mode 100644
index 0000000..9045520
--- /dev/null
+++ b/tests/testresources/failOnSpecificWarningsPlugin/scenarioTests/UnrelatedWarningScenarioTest.m
@@ -0,0 +1,15 @@
+classdef UnrelatedWarningScenarioTest < matlab.unittest.TestCase
+
+ methods ( Test )
+
+ function testUnrelatedWarning(testCase)
+
+ warning("FailOnSpecificWarningsPluginTest:Other", "Other warning.");
+
+ testCase.verifyTrue(true);
+
+ end % testUnrelatedWarning
+
+ end % methods ( Test )
+
+end % classdef
diff --git a/tests/testresources/failOnSpecificWarningsPlugin/scenarioTests/WarningFreeScenarioTest.m b/tests/testresources/failOnSpecificWarningsPlugin/scenarioTests/WarningFreeScenarioTest.m
new file mode 100644
index 0000000..7954032
--- /dev/null
+++ b/tests/testresources/failOnSpecificWarningsPlugin/scenarioTests/WarningFreeScenarioTest.m
@@ -0,0 +1,13 @@
+classdef WarningFreeScenarioTest < matlab.unittest.TestCase
+
+ methods ( Test )
+
+ function testWarningFree(testCase)
+
+ testCase.verifyTrue(true);
+
+ end % testWarningFree
+
+ end % methods ( Test )
+
+end % classdef