diff --git a/ArchUnit.sln b/ArchUnit.sln
index abcde8c4..b511f6d0 100644
--- a/ArchUnit.sln
+++ b/ArchUnit.sln
@@ -48,6 +48,12 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InterfaceAssembly", "TestAs
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FilteredDirectoryUnavailableTypesAssembly", "TestAssemblies\FilteredDirectoryUnavailableTypesAssembly\FilteredDirectoryUnavailableTypesAssembly.csproj", "{AA695589-8CCC-4474-9A7F-01A6376C375A}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ArchUnitNET.MSTestV3Tests", "ArchUnitNET.MSTestV3Tests\ArchUnitNET.MSTestV3Tests.csproj", "{F9856A37-C0E0-453C-888F-D794856D3404}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ArchUnitNET.MSTestV4Tests", "ArchUnitNET.MSTestV4Tests\ArchUnitNET.MSTestV4Tests.csproj", "{9858F5A1-356B-4CF0-8E50-62F2E881CC36}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ArchUnitNET.MSTestV4", "ArchUnitNET.MSTestV4\ArchUnitNET.MSTestV4.csproj", "{50F0F64A-F4A2-47E5-82E9-B66F07CE4198}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -142,6 +148,18 @@ Global
{AA695589-8CCC-4474-9A7F-01A6376C375A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AA695589-8CCC-4474-9A7F-01A6376C375A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AA695589-8CCC-4474-9A7F-01A6376C375A}.Release|Any CPU.Build.0 = Release|Any CPU
+ {F9856A37-C0E0-453C-888F-D794856D3404}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {F9856A37-C0E0-453C-888F-D794856D3404}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {F9856A37-C0E0-453C-888F-D794856D3404}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {F9856A37-C0E0-453C-888F-D794856D3404}.Release|Any CPU.Build.0 = Release|Any CPU
+ {9858F5A1-356B-4CF0-8E50-62F2E881CC36}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {9858F5A1-356B-4CF0-8E50-62F2E881CC36}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {9858F5A1-356B-4CF0-8E50-62F2E881CC36}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {9858F5A1-356B-4CF0-8E50-62F2E881CC36}.Release|Any CPU.Build.0 = Release|Any CPU
+ {50F0F64A-F4A2-47E5-82E9-B66F07CE4198}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {50F0F64A-F4A2-47E5-82E9-B66F07CE4198}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {50F0F64A-F4A2-47E5-82E9-B66F07CE4198}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {50F0F64A-F4A2-47E5-82E9-B66F07CE4198}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/ArchUnitNET.MSTestV2/ArchUnitNET.MSTestV2.csproj b/ArchUnitNET.MSTestV2/ArchUnitNET.MSTestV2.csproj
index b9a5d45c..60f3d22d 100644
--- a/ArchUnitNET.MSTestV2/ArchUnitNET.MSTestV2.csproj
+++ b/ArchUnitNET.MSTestV2/ArchUnitNET.MSTestV2.csproj
@@ -3,7 +3,7 @@
netstandard2.0;net462
true
ArchUnit C# MSTestV2 Extension
- MSTestV2 Extension for the C# Version of ArchUnit (see: archunit.org)
+ MSTestV2 Extension (compatible with MSTestV3) for the C# Version of ArchUnit (see: archunit.org)
Apache-2.0
https://github.com/TNG/ArchUnitNET
test;arch;archunit;mstest;mstestv2
@@ -17,7 +17,6 @@
true
-
diff --git a/ArchUnitNET.MSTestV2Tests/ArchUnitNET.MSTestV2Tests.csproj b/ArchUnitNET.MSTestV2Tests/ArchUnitNET.MSTestV2Tests.csproj
index 661c89f7..57fc6d39 100644
--- a/ArchUnitNET.MSTestV2Tests/ArchUnitNET.MSTestV2Tests.csproj
+++ b/ArchUnitNET.MSTestV2Tests/ArchUnitNET.MSTestV2Tests.csproj
@@ -7,8 +7,8 @@
-
-
+
+
diff --git a/ArchUnitNET.MSTestV2Tests/RuleEvaluationTests.cs b/ArchUnitNET.MSTestV2Tests/RuleEvaluationTests.cs
index 621fa150..903301c5 100644
--- a/ArchUnitNET.MSTestV2Tests/RuleEvaluationTests.cs
+++ b/ArchUnitNET.MSTestV2Tests/RuleEvaluationTests.cs
@@ -31,14 +31,14 @@ public static void Setup(TestContext context)
public void ArchRuleAssertTest()
{
ArchRuleAssert.FulfilsRule(_architecture, _trueRule);
- Assert.ThrowsExactly(() =>
+ Assert.ThrowsException(() =>
ArchRuleAssert.FulfilsRule(_architecture, _falseRule)
);
Assert.AreEqual(
_expectedErrorMessage,
RemoveAssertionText(
Assert
- .ThrowsExactly(() =>
+ .ThrowsException(() =>
ArchRuleAssert.FulfilsRule(_architecture, _falseRule)
)
.Message
@@ -51,13 +51,13 @@ public void ArchRuleExtensionsTest()
{
_architecture.CheckRule(_trueRule);
_trueRule.Check(_architecture);
- Assert.ThrowsExactly(() => _architecture.CheckRule(_falseRule));
- Assert.ThrowsExactly(() => _falseRule.Check(_architecture));
+ Assert.ThrowsException(() => _architecture.CheckRule(_falseRule));
+ Assert.ThrowsException(() => _falseRule.Check(_architecture));
Assert.AreEqual(
_expectedErrorMessage,
RemoveAssertionText(
Assert
- .ThrowsExactly(() =>
+ .ThrowsException(() =>
_architecture.CheckRule(_falseRule)
)
.Message
@@ -67,7 +67,7 @@ public void ArchRuleExtensionsTest()
_expectedErrorMessage,
RemoveAssertionText(
Assert
- .ThrowsExactly(() => _falseRule.Check(_architecture))
+ .ThrowsException(() => _falseRule.Check(_architecture))
.Message
)
);
diff --git a/ArchUnitNET.MSTestV3Tests/ArchUnitNET.MSTestV3Tests.csproj b/ArchUnitNET.MSTestV3Tests/ArchUnitNET.MSTestV3Tests.csproj
new file mode 100644
index 00000000..d5463a71
--- /dev/null
+++ b/ArchUnitNET.MSTestV3Tests/ArchUnitNET.MSTestV3Tests.csproj
@@ -0,0 +1,22 @@
+
+
+
+ net9.0
+ false
+ TNG Technology Consulting GmbH
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ArchUnitNET.MSTestV3Tests/RuleEvaluationTests.cs b/ArchUnitNET.MSTestV3Tests/RuleEvaluationTests.cs
new file mode 100644
index 00000000..881a516c
--- /dev/null
+++ b/ArchUnitNET.MSTestV3Tests/RuleEvaluationTests.cs
@@ -0,0 +1,81 @@
+using ArchUnitNET.Domain;
+using ArchUnitNET.Fluent;
+using ArchUnitNET.Fluent.Extensions;
+using ArchUnitNET.Loader;
+using ArchUnitNET.MSTestV2;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using static ArchUnitNET.Fluent.ArchRuleDefinition;
+
+namespace ArchUnitNET.MSTestV3Tests
+{
+ [TestClass]
+ public class RuleEvaluationTests
+ {
+ private static Architecture _architecture;
+ private static string _expectedErrorMessage;
+ private static IArchRule _falseRule;
+ private static IArchRule _trueRule;
+
+ [ClassInitialize]
+ public static void Setup(TestContext context)
+ {
+ _architecture = new ArchLoader()
+ .LoadAssemblies(System.Reflection.Assembly.Load("ArchUnitNET.MSTestV3Tests"))
+ .Build();
+ _trueRule = Classes().That().Are(typeof(RuleEvaluationTests)).Should().Exist();
+ _falseRule = Classes().That().Are(typeof(RuleEvaluationTests)).Should().NotExist();
+ _expectedErrorMessage = _falseRule.Evaluate(_architecture).ToErrorMessage();
+ }
+
+ [TestMethod]
+ public void ArchRuleAssertTest()
+ {
+ ArchRuleAssert.FulfilsRule(_architecture, _trueRule);
+ Assert.ThrowsExactly(() =>
+ ArchRuleAssert.FulfilsRule(_architecture, _falseRule)
+ );
+ Assert.AreEqual(
+ _expectedErrorMessage,
+ RemoveAssertionText(
+ Assert
+ .ThrowsExactly(() =>
+ ArchRuleAssert.FulfilsRule(_architecture, _falseRule)
+ )
+ .Message
+ )
+ );
+ }
+
+ [TestMethod]
+ public void ArchRuleExtensionsTest()
+ {
+ _architecture.CheckRule(_trueRule);
+ _trueRule.Check(_architecture);
+ Assert.ThrowsExactly(() => _architecture.CheckRule(_falseRule));
+ Assert.ThrowsExactly(() => _falseRule.Check(_architecture));
+ Assert.AreEqual(
+ _expectedErrorMessage,
+ RemoveAssertionText(
+ Assert
+ .ThrowsExactly(() =>
+ _architecture.CheckRule(_falseRule)
+ )
+ .Message
+ )
+ );
+ Assert.AreEqual(
+ _expectedErrorMessage,
+ RemoveAssertionText(
+ Assert
+ .ThrowsExactly(() => _falseRule.Check(_architecture))
+ .Message
+ )
+ );
+ }
+
+ private static string RemoveAssertionText(string exceptionMessage)
+ {
+ return exceptionMessage.Replace("Assert.Fail failed. ", string.Empty);
+ }
+ }
+}
diff --git a/ArchUnitNET.MSTestV4/ArchRuleAssert.cs b/ArchUnitNET.MSTestV4/ArchRuleAssert.cs
new file mode 100644
index 00000000..585207f6
--- /dev/null
+++ b/ArchUnitNET.MSTestV4/ArchRuleAssert.cs
@@ -0,0 +1,23 @@
+using ArchUnitNET.Domain;
+using ArchUnitNET.Fluent;
+using ArchUnitNET.Fluent.Extensions;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+namespace ArchUnitNET.MSTestV4
+{
+ public static class ArchRuleAssert
+ {
+ ///
+ /// Verifies that the architecture meets the criteria of the archrule.
+ ///
+ /// The architecture to be tested
+ /// The rule to test the architecture with
+ public static void FulfilsRule(Architecture architecture, IArchRule archRule)
+ {
+ if (!archRule.HasNoViolations(architecture))
+ {
+ Assert.Fail(archRule.Evaluate(architecture).ToErrorMessage());
+ }
+ }
+ }
+}
diff --git a/ArchUnitNET.MSTestV4/ArchRuleExtensions.cs b/ArchUnitNET.MSTestV4/ArchRuleExtensions.cs
new file mode 100644
index 00000000..f0c3d4e5
--- /dev/null
+++ b/ArchUnitNET.MSTestV4/ArchRuleExtensions.cs
@@ -0,0 +1,28 @@
+using ArchUnitNET.Domain;
+using ArchUnitNET.Fluent;
+
+namespace ArchUnitNET.MSTestV4
+{
+ public static class ArchRuleExtensions
+ {
+ ///
+ /// Verifies that the architecture meets the criteria of the archrule.
+ ///
+ /// The rule to test the architecture with
+ /// The architecture to be tested
+ public static void Check(this IArchRule archRule, Architecture architecture)
+ {
+ ArchRuleAssert.FulfilsRule(architecture, archRule);
+ }
+
+ ///
+ /// Verifies that the architecture meets the criteria of the archrule.
+ ///
+ /// The architecture to be tested
+ /// The rule to test the architecture with
+ public static void CheckRule(this Architecture architecture, IArchRule archRule)
+ {
+ ArchRuleAssert.FulfilsRule(architecture, archRule);
+ }
+ }
+}
diff --git a/ArchUnitNET.MSTestV4/ArchUnitNET.MSTestV4.csproj b/ArchUnitNET.MSTestV4/ArchUnitNET.MSTestV4.csproj
new file mode 100644
index 00000000..862709ba
--- /dev/null
+++ b/ArchUnitNET.MSTestV4/ArchUnitNET.MSTestV4.csproj
@@ -0,0 +1,29 @@
+
+
+ netstandard2.0;net462
+ true
+ ArchUnit C# MSTestV4 Extension
+ MSTestV4 Extension for the C# Version of ArchUnit (see: archunit.org)
+ Apache-2.0
+ https://github.com/TNG/ArchUnitNET
+ test;arch;archunit;mstest;mstestv2
+ False
+ TNG Technology Consulting GmbH
+ TngTech.ArchUnitNET.MSTestV4
+ false
+ true
+ snupkg
+ README.md
+ true
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ArchUnitNET.MSTestV4Tests/ArchUnitNET.MSTestV4Tests.csproj b/ArchUnitNET.MSTestV4Tests/ArchUnitNET.MSTestV4Tests.csproj
new file mode 100644
index 00000000..f763d165
--- /dev/null
+++ b/ArchUnitNET.MSTestV4Tests/ArchUnitNET.MSTestV4Tests.csproj
@@ -0,0 +1,22 @@
+
+
+
+ net9.0
+ false
+ TNG Technology Consulting GmbH
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ArchUnitNET.MSTestV4Tests/MSTestSettings.cs b/ArchUnitNET.MSTestV4Tests/MSTestSettings.cs
new file mode 100644
index 00000000..8baf5232
--- /dev/null
+++ b/ArchUnitNET.MSTestV4Tests/MSTestSettings.cs
@@ -0,0 +1 @@
+[assembly: DoNotParallelize]
diff --git a/ArchUnitNET.MSTestV4Tests/RuleEvaluationTests.cs b/ArchUnitNET.MSTestV4Tests/RuleEvaluationTests.cs
new file mode 100644
index 00000000..950f3a8c
--- /dev/null
+++ b/ArchUnitNET.MSTestV4Tests/RuleEvaluationTests.cs
@@ -0,0 +1,81 @@
+using ArchUnitNET.Domain;
+using ArchUnitNET.Fluent;
+using ArchUnitNET.Fluent.Extensions;
+using ArchUnitNET.Loader;
+using ArchUnitNET.MSTestV4;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using static ArchUnitNET.Fluent.ArchRuleDefinition;
+
+namespace ArchUnitNET.MSTestV4Tests
+{
+ [TestClass]
+ public class RuleEvaluationTests
+ {
+ private static Architecture _architecture;
+ private static string _expectedErrorMessage;
+ private static IArchRule _falseRule;
+ private static IArchRule _trueRule;
+
+ [ClassInitialize]
+ public static void Setup(TestContext context)
+ {
+ _architecture = new ArchLoader()
+ .LoadAssemblies(System.Reflection.Assembly.Load("ArchUnitNET.MSTestV4Tests"))
+ .Build();
+ _trueRule = Classes().That().Are(typeof(RuleEvaluationTests)).Should().Exist();
+ _falseRule = Classes().That().Are(typeof(RuleEvaluationTests)).Should().NotExist();
+ _expectedErrorMessage = _falseRule.Evaluate(_architecture).ToErrorMessage();
+ }
+
+ [TestMethod]
+ public void ArchRuleAssertTest()
+ {
+ ArchRuleAssert.FulfilsRule(_architecture, _trueRule);
+ Assert.ThrowsExactly(() =>
+ ArchRuleAssert.FulfilsRule(_architecture, _falseRule)
+ );
+ Assert.AreEqual(
+ _expectedErrorMessage,
+ RemoveAssertionText(
+ Assert
+ .ThrowsExactly(() =>
+ ArchRuleAssert.FulfilsRule(_architecture, _falseRule)
+ )
+ .Message
+ )
+ );
+ }
+
+ [TestMethod]
+ public void ArchRuleExtensionsTest()
+ {
+ _architecture.CheckRule(_trueRule);
+ _trueRule.Check(_architecture);
+ Assert.ThrowsExactly(() => _architecture.CheckRule(_falseRule));
+ Assert.ThrowsExactly(() => _falseRule.Check(_architecture));
+ Assert.AreEqual(
+ _expectedErrorMessage,
+ RemoveAssertionText(
+ Assert
+ .ThrowsExactly(() =>
+ _architecture.CheckRule(_falseRule)
+ )
+ .Message
+ )
+ );
+ Assert.AreEqual(
+ _expectedErrorMessage,
+ RemoveAssertionText(
+ Assert
+ .ThrowsExactly(() => _falseRule.Check(_architecture))
+ .Message
+ )
+ );
+ }
+
+ private static string RemoveAssertionText(string exceptionMessage)
+ {
+ return exceptionMessage.Replace("Assert.Fail failed. ", string.Empty);
+ }
+ }
+}