MS Test
September 10, 2026 · View on GitHub
The "Philips MsTest" category of diagnostics suggests ways to improve your test code using the MsTest framework.
These provide guidelines to writing test code that runs reliably and correctly. This in turn improves the quality of your code.
⚠️ Important: Microsoft's Official MSTest Analyzers Available
Microsoft now provides official MSTest analyzers that cover most functionality of the Philips MSTest analyzers. We recommend migrating to Microsoft's official analyzers for overlapping functionality. See the Migration Guide below for details.
MSTest Analyzers Migration Guide
Microsoft now provides official MSTest analyzers as part of their testing framework. Many of the Philips MSTest analyzer rules have equivalent or superior counterparts in Microsoft's official analyzer package.
Overview
Microsoft's official MSTest analyzers are available via the MSTest.Analyzers NuGet package and provide comprehensive coverage of MSTest best practices. The official analyzers use rule IDs in the format MSTEST#### and include extensive documentation.
Recommendation
We recommend migrating to Microsoft's official MSTest analyzers for all overlapping functionality. Microsoft's analyzers are:
- Officially supported and maintained by the MSTest team
- Better integrated with the MSTest framework
- Actively updated with new MSTest features
- Include extensive documentation and code fixes
Rule Mapping
Direct Overlaps (Recommended Migration)
These Philips rules have direct equivalents in Microsoft's official analyzers:
| Philips Rule | Microsoft Rule | Description | Recommendation |
|---|---|---|---|
| PH2004 | MSTEST0006 | Avoid ExpectedException attribute | ✅ Migrate to MSTEST0006 |
| PH2005 | MSTEST0005 | TestContext usage validation | ✅ Migrate to MSTEST0005 |
| PH2013 | MSTEST0015 | Avoid Ignore attribute | ✅ Migrate to MSTEST0015 |
| PH2016 | MSTEST0008 | TestInitialize validation | ✅ Migrate to MSTEST0008 |
| PH2017 | MSTEST0010 | ClassInitialize validation | ✅ Migrate to MSTEST0010 |
| PH2018 | MSTEST0011 | ClassCleanup validation | ✅ Migrate to MSTEST0011 |
| PH2019 | MSTEST0009 | TestCleanup validation | ✅ Migrate to MSTEST0009 |
| PH2034 | MSTEST0030 | TestMethod requires TestClass | ✅ Migrate to MSTEST0030 |
| PH2036 | MSTEST0003 | TestMethod must be public | ✅ Migrate to MSTEST0003 |
| PH2038 | MSTEST0002 | TestClass must be public | ✅ Migrate to MSTEST0002 |
| PH2058 | MSTEST0026 | Avoid Assert conditional check | ✅ Migrate to MSTEST0026 |
| PH2059 | MSTEST0029 | Public methods should be TestMethod | ✅ Migrate to MSTEST0029 |
Partial Overlaps (Consider Migration)
These Philips rules have similar functionality in Microsoft's analyzers, often with broader coverage:
| Philips Rule | Microsoft Rule | Description | Recommendation |
|---|---|---|---|
| PH2003 | MSTEST0037 | Assert.AreEqual usage patterns | ⚠️ Consider MSTEST0037 (broader assert validation) |
| PH2008 | MSTEST0037 | Assert parameter types match | ⚠️ Consider MSTEST0037 (broader assert validation) |
| PH2009 | MSTEST0037 | Assert.IsTrue/IsFalse usage | ⚠️ Consider MSTEST0037 (broader assert validation) |
| PH2055 | MSTEST0037 | Avoid Assert.IsTrue(true) | ⚠️ Consider MSTEST0037 (broader assert validation) |
| PH2056 | MSTEST0037 | Avoid Assert.AreEqual(true, true) | ⚠️ Consider MSTEST0037 (broader assert validation) |
| PH2076 | MSTEST0025 | Assert.Fail alternatives | ⚠️ Consider MSTEST0025 (similar intent) |
Removed Rules
These Philips rules were removed from the codebase because Microsoft's official analyzers fully supersede them:
| Removed Rule | Replaced By | Reason |
|---|---|---|
| PH2033 | MSTEST0014 | DataRow validation — removed in #851 |
| PH2035 | MSTEST0014 | DataTestMethod parameter count — removed in #861 |
Philips-Specific Rules (Keep if Needed)
These rules provide functionality not available in Microsoft's official analyzers:
| Philips Rule | Description | Recommendation |
|---|---|---|
| PH2000 | Avoid test method prefix | 📌 Keep if naming convention is important |
| PH2010 | Avoid unnecessary parentheses | 📌 Keep if style preference matters (Note: Generic IDE rule IDE0047 also available) |
| PH2011 | Description attribute usage | 📌 Keep if using Description attributes |
| PH2012 | TestTimeout required | 📌 Keep if timeout enforcement is desired |
| PH2014 | Avoid Owner attribute | 📌 Keep if avoiding Owner attributes |
| PH2015 | Required Categories attribute | 📌 Keep if category enforcement is desired |
| PH2041 | Avoid MS Fakes | 📌 Keep if using something like Moq rather than MS Fakes |
Additional Microsoft Rules
Microsoft provides many additional rules not covered by Philips analyzers. Consider enabling these for comprehensive test analysis:
- MSTEST0001: Use Parallelize attribute for performance
- MSTEST0017: Assertion arguments in correct order
- MSTEST0018: DynamicData validation
- MSTEST0023: Don't negate boolean assertions
- MSTEST0024: Don't store static TestContext
- MSTEST0032: Review always-true assert conditions
- MSTEST0038: Avoid AreSame with value types
- MSTEST0040: Avoid asserts in async void
- And many more...
Migration Steps
1. Install Microsoft's MSTest Analyzers
<PackageReference Include="MSTest.Analyzers" PrivateAssets="all" />
2. Update .editorconfig
Disable overlapping Philips rules and enable Microsoft equivalents (all set to error for strictness):
# Disable overlapping Philips MSTest rules
dotnet_diagnostic.PH2004.severity = none # Use MSTEST0006 instead
dotnet_diagnostic.PH2005.severity = none # Use MSTEST0005 instead
dotnet_diagnostic.PH2013.severity = none # Use MSTEST0015 instead
dotnet_diagnostic.PH2016.severity = none # Use MSTEST0008 instead
dotnet_diagnostic.PH2017.severity = none # Use MSTEST0010 instead
dotnet_diagnostic.PH2018.severity = none # Use MSTEST0011 instead
dotnet_diagnostic.PH2019.severity = none # Use MSTEST0009 instead
dotnet_diagnostic.PH2034.severity = none # Use MSTEST0030 instead
dotnet_diagnostic.PH2036.severity = none # Use MSTEST0003 instead
dotnet_diagnostic.PH2038.severity = none # Use MSTEST0002 instead
dotnet_diagnostic.PH2058.severity = none # Use MSTEST0026 instead
dotnet_diagnostic.PH2059.severity = none # Use MSTEST0029 instead
# Consider disabling partial overlaps
dotnet_diagnostic.PH2003.severity = none # Consider MSTEST0037 instead
dotnet_diagnostic.PH2008.severity = none # Consider MSTEST0037 instead
dotnet_diagnostic.PH2009.severity = none # Consider MSTEST0037 instead
dotnet_diagnostic.PH2055.severity = none # Consider MSTEST0037 instead
dotnet_diagnostic.PH2056.severity = none # Consider MSTEST0037 instead
dotnet_diagnostic.PH2076.severity = none # Consider MSTEST0025 instead
# Enable most Microsoft MSTest rules as error
dotnet_diagnostic.MSTEST0001.severity = error
dotnet_diagnostic.MSTEST0002.severity = error
dotnet_diagnostic.MSTEST0003.severity = error
dotnet_diagnostic.MSTEST0004.severity = error
dotnet_diagnostic.MSTEST0005.severity = error
dotnet_diagnostic.MSTEST0006.severity = error
dotnet_diagnostic.MSTEST0007.severity = error
dotnet_diagnostic.MSTEST0008.severity = error
dotnet_diagnostic.MSTEST0009.severity = error
dotnet_diagnostic.MSTEST0010.severity = error
dotnet_diagnostic.MSTEST0011.severity = error
dotnet_diagnostic.MSTEST0012.severity = error
dotnet_diagnostic.MSTEST0013.severity = error
dotnet_diagnostic.MSTEST0014.severity = error
dotnet_diagnostic.MSTEST0015.severity = error
dotnet_diagnostic.MSTEST0016.severity = error
dotnet_diagnostic.MSTEST0017.severity = error
dotnet_diagnostic.MSTEST0018.severity = error
dotnet_diagnostic.MSTEST0019.severity = warning # Exception: not set to error
dotnet_diagnostic.MSTEST0020.severity = error
dotnet_diagnostic.MSTEST0021.severity = error
dotnet_diagnostic.MSTEST0022.severity = error
dotnet_diagnostic.MSTEST0023.severity = error
dotnet_diagnostic.MSTEST0024.severity = error
dotnet_diagnostic.MSTEST0025.severity = error
dotnet_diagnostic.MSTEST0026.severity = error
dotnet_diagnostic.MSTEST0027.severity = error
dotnet_diagnostic.MSTEST0028.severity = error
dotnet_diagnostic.MSTEST0029.severity = error
dotnet_diagnostic.MSTEST0030.severity = error
dotnet_diagnostic.MSTEST0031.severity = error
dotnet_diagnostic.MSTEST0032.severity = error
dotnet_diagnostic.MSTEST0033.severity = error
dotnet_diagnostic.MSTEST0034.severity = error
dotnet_diagnostic.MSTEST0035.severity = error
dotnet_diagnostic.MSTEST0036.severity = error
dotnet_diagnostic.MSTEST0037.severity = error
dotnet_diagnostic.MSTEST0038.severity = error
dotnet_diagnostic.MSTEST0039.severity = error
dotnet_diagnostic.MSTEST0040.severity = error
dotnet_diagnostic.MSTEST0041.severity = error
dotnet_diagnostic.MSTEST0042.severity = error
dotnet_diagnostic.MSTEST0043.severity = error
dotnet_diagnostic.MSTEST0044.severity = error
dotnet_diagnostic.MSTEST0045.severity = error
dotnet_diagnostic.MSTEST0046.severity = error
dotnet_diagnostic.MSTEST0047.severity = error
dotnet_diagnostic.MSTEST0048.severity = error
dotnet_diagnostic.MSTEST0049.severity = error
dotnet_diagnostic.MSTEST0050.severity = error
# Keep Philips-specific rules as needed
dotnet_diagnostic.PH2000.severity = error # Test method naming
dotnet_diagnostic.PH2012.severity = error # Test timeout required
dotnet_diagnostic.PH2015.severity = error # Required categories
Questions or Issues?
If you have questions about the migration or need help with specific scenarios, please:
- Check the Microsoft MSTest Analyzers documentation
- Review individual rule documentation linked in the mapping table above
- Open an issue in this repository for Philips-specific questions