Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
b38b3da
Add [DependsOn] test dependencies with a DAG scheduler and chain file
Copilot Jul 26, 2026
91c6b9e
Move file-based test dependencies into testconfig.json, MTP-only
Copilot Jul 27, 2026
bdf1b64
Correct the configured-dependency acceptance expectations
Copilot Jul 27, 2026
e913940
Fix three review findings in the dependency scheduler
Copilot Jul 27, 2026
1d5d021
Address review findings: message severity, stale docs, terminology
Copilot Jul 27, 2026
4ad7b27
Reference the analyzer tracking issue from RFC 022 future work
Copilot Jul 27, 2026
392e522
Address review: conservative duplicate merge, empty chain, stale doc
Copilot Jul 27, 2026
15d2d6b
Make cycle diagnostics name only the tests and classes involved
Copilot Jul 27, 2026
ae028e2
Assert the positive outcome in the MethodLevel projection test
Copilot Jul 27, 2026
fcf3714
Fix configured wildcard self-edge, correct API record, cover VSTest t…
Copilot Jul 27, 2026
176970e
Complete cycle membership, harden config parsing, deflake overlap test
Copilot Jul 27, 2026
ad80cec
Render cycle paths from declared edges, not component order
Copilot Jul 27, 2026
12ce3f8
Pin the surviving edges in the whole-class self-edge test
Copilot Jul 27, 2026
1752708
Scope configured-dependency diagnostics to the whole run; drop stale …
Copilot Jul 27, 2026
975022d
Add unit coverage for the dependency configuration parser
Copilot Jul 27, 2026
6608de2
Use Any for the unmatched-dependent check
Copilot Jul 27, 2026
b8ec52a
Assert the malformed-reference warning names the offending reference
Copilot Jul 27, 2026
b3c231a
Keep name ordering as the graph's tie-breaker; document cross-assembl…
Evangelink Jul 27, 2026
ee10d09
Assert the wildcard edge's target, not just its count
Evangelink Jul 27, 2026
33ab2e4
Correct the inheritance docs and pin the behavior with tests
Evangelink Jul 27, 2026
daf6171
Compute class-level cycle membership with Tarjan, not leaf peeling
Evangelink Jul 27, 2026
4fd761a
Fix a vacuous cycle-message assertion and two stale descriptions
Evangelink Jul 27, 2026
7ff797a
Actually observe the faulted run, and document ProceedOnFailure's rea…
Evangelink Jul 27, 2026
45fee98
Restore the UTF-8 BOM on three C# files
Evangelink Jul 27, 2026
0107425
Account for dependency-skipped and cycle-broken tests in cleanup book…
Evangelink Jul 28, 2026
15a572c
Pin ProceedOnFailure's default in the setter test
Evangelink Jul 28, 2026
6403cb0
Merge branch 'main' into dev/amauryleve/test-ordering-dependencies
Evangelink Jul 28, 2026
c25286e
Merge remote-tracking branch 'origin/main' into dev/amauryleve/test-o…
Evangelink Jul 28, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ See full log [of v4.3.3...v4.4.0](https://github.com/microsoft/testfx/compare/v4

### Added

* Add `[DependsOn]` and equivalent `testconfig.json` declarations (`mstest:execution:dependencies`, with `chains` for straight sequences and `nodes` for fan-in/fan-out) to declare that a test runs after one or more other tests. Declarations form a directed acyclic graph rather than a flat order, so tests that share a prerequisite still run in parallel with each other; a test whose prerequisite does not pass is skipped (transitively) unless it sets `ProceedOnFailure`, and dependency cycles are reported before the run starts. The attribute works on both hosts; the `testconfig.json` declarations are Microsoft.Testing.Platform only. See [RFC 022](RFCs/022-Test-Dependencies.md)
* Add dedicated timeout configuration for `[GlobalTestInitialize]` / `[GlobalTestCleanup]` fixtures via the `timeout:globalTestInitialize` / `timeout:globalTestCleanup` `testconfig.json` keys (RunSettings XML: `GlobalTestInitializeTimeout` / `GlobalTestCleanupTimeout`). These fall back to the per-test `testInitialize` / `testCleanup` timeouts when unset, and global fixture timeout/cancellation diagnostics now use dedicated messages ("Global test initialize/cleanup method ...") in [#9985](https://github.com/microsoft/testfx/issues/9985)

### Changed
Expand Down
338 changes: 338 additions & 0 deletions docs/RFCs/022-Test-Dependencies.md

Large diffs are not rendered by default.

42 changes: 42 additions & 0 deletions docs/testconfig.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,48 @@
"type": "integer",
"description": "Seed used when 'randomizeTestOrder' is true, to make the randomized order reproducible."
},
"dependencies": {
"type": "object",
"description": "Declares test dependencies outside the test source, as an alternative to the [DependsOn] attribute. A test is referenced by 'Namespace.Class.Method', or 'Namespace.Class.*' for every test of a class. Merged with attribute-declared dependencies.",
"additionalProperties": false,
"properties": {
"chains": {
"type": "array",
"description": "Ordered sequences: within each chain, every test waits for the one before it.",
"items": {
"type": "array",
"description": "A chain needs at least two tests; a shorter one declares no dependency.",
"minItems": 2,
"items": { "type": "string" }
}
},
"nodes": {
"type": "array",
"description": "Explicit dependency nodes, allowing one test to wait for several prerequisites (fan-in) and several tests to wait for the same one (fan-out).",
"items": {
"type": "object",
"additionalProperties": false,
"required": [ "test", "dependsOn" ],
"properties": {
"test": {
"type": "string",
"description": "The test that runs after its prerequisites."
},
"dependsOn": {
"type": "array",
"description": "The tests that must run first. At least one is required; an empty list declares no dependency.",
"minItems": 1,
"items": { "type": "string" }
},
"proceedOnFailure": {
"type": "boolean",
"description": "When true, the test runs even if a prerequisite did not pass. Ordering is still enforced. Defaults to false, which skips the test."
}
}
}
}
}
},
"mapInconclusiveToFailed": {
"type": "boolean",
"description": "When true, inconclusive test outcomes are reported as failures. Defaults to false."
Expand Down
6 changes: 6 additions & 0 deletions src/Adapter/MSTest.TestAdapter/AdapterTestProperties.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ internal static class AdapterTestProperties
// Each entry is a single-character mode prefix ('R' for Read, 'W' for ReadWrite) followed by the resource key.
internal static readonly TestProperty ResourceLocksProperty = TestProperty.Register("MSTestDiscoverer.ResourceLocks", ResourceLocksLabel, typeof(string[]), TestPropertyAttributes.Hidden, typeof(TestCase));

// Each entry is a single-character 'proceed on failure' prefix ('P' when set, 'S' otherwise) followed by
// the target class full name, a line feed, and the target method name (either may be empty).
internal static readonly TestProperty DependenciesProperty = TestProperty.Register("MSTestDiscoverer.Dependencies", DependenciesLabel, typeof(string[]), TestPropertyAttributes.Hidden, typeof(TestCase));

internal static readonly TestProperty ExecutionIdProperty = TestProperty.Register("ExecutionId", ExecutionIdLabel, typeof(Guid), TestPropertyAttributes.Hidden, typeof(TestResult));

internal static readonly TestProperty ParentExecIdProperty = TestProperty.Register("ParentExecId", ParentExecIdLabel, typeof(Guid), TestPropertyAttributes.Hidden, typeof(TestResult));
Expand Down Expand Up @@ -96,6 +100,8 @@ internal static class AdapterTestProperties
#endif
private const string DoNotParallelizeLabel = "DoNotParallelize";
private const string ResourceLocksLabel = "ResourceLocks";

private const string DependenciesLabel = "Dependencies";
private const string ExecutionIdLabel = "ExecutionId";
private const string ParentExecIdLabel = "ParentExecId";
private const string WorkItemIdsLabel = "WorkItemIds";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,12 @@ internal static UnitTestElement ToUnitTestElementWithUpdatedSource(this TestCase
testElement.ResourceLocks = Array.ConvertAll(encodedResourceLocks, ResourceLockInfo.Decode);
}

string[]? encodedDependencies = testCase.GetPropertyValue<string[]>(AdapterTestProperties.DependenciesProperty, null);
if (encodedDependencies is { Length: > 0 })
{
testElement.Dependencies = Array.ConvertAll(encodedDependencies, TestDependencyInfo.Decode);
}

return testElement;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,12 @@ internal static TestCase ToTestCase(this UnitTestElement element)
testCase.SetPropertyValue(AdapterTestProperties.ResourceLocksProperty, Array.ConvertAll(resourceLocks, ResourceLockInfo.Encode));
}

// Set the declared dependencies if present, so they survive the discovery -> execution round-trip.
if (element.Dependencies is { Length: > 0 } dependencies)
{
testCase.SetPropertyValue(AdapterTestProperties.DependenciesProperty, Array.ConvertAll(dependencies, TestDependencyInfo.Encode));
Comment thread
Evangelink marked this conversation as resolved.
}

if (element.UnfoldingStrategy != TestDataSourceUnfoldingStrategy.Auto)
{
testCase.SetPropertyValue(AdapterTestProperties.UnfoldingStrategy, (int)element.UnfoldingStrategy);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ abstract Microsoft.Testing.Extensions.RunSettingsConfigurationProviderBase.ReadR
abstract Microsoft.Testing.Extensions.RunSettingsConfigurationProviderBase.Uid.get -> string!
abstract Microsoft.Testing.Extensions.RunSettingsConfigurationProviderBase.Version.get -> string!
const Microsoft.Testing.Extensions.RunSettingsCommandLineOptionsProviderBase.RunSettingsOptionName = "settings" -> string!
const Microsoft.Testing.Extensions.TestCaseFilterCommandLineOptionsProviderBase.TestCaseFilterOptionName = "filter" -> string!
const Microsoft.Testing.Extensions.TestRunParametersCommandLineOptionsProviderBase.TestRunParameterOptionName = "test-parameter" -> string!
Microsoft.Testing.Extensions.RunSettingsCommandLineOptionsProviderBase
Microsoft.Testing.Extensions.RunSettingsCommandLineOptionsProviderBase.RunSettingsCommandLineOptionsProviderBase(Microsoft.Testing.Platform.Extensions.IExtension! extension, Microsoft.Testing.Platform.Helpers.IFileSystem! fileSystem, string! optionDescription, string! fileDoesNotExistErrorFormat, string! fileCannotBeReadErrorFormat) -> void
Microsoft.Testing.Extensions.RunSettingsConfigurationProviderBase
Expand All @@ -25,13 +27,16 @@ Microsoft.Testing.Extensions.RunSettingsEnvironmentVariableProviderBase.UpdateAs
Microsoft.Testing.Extensions.RunSettingsEnvironmentVariableProviderBase.ValidateTestHostEnvironmentVariablesAsync(Microsoft.Testing.Platform.Extensions.TestHostControllers.IReadOnlyEnvironmentVariables! environmentVariables) -> System.Threading.Tasks.Task<Microsoft.Testing.Platform.Extensions.ValidationResult>!
Microsoft.Testing.Extensions.RunSettingsEnvironmentVariableProviderBase.Version.get -> string!
Microsoft.Testing.Extensions.RunSettingsProviderHelper
const Microsoft.Testing.Extensions.TestCaseFilterCommandLineOptionsProviderBase.TestCaseFilterOptionName = "filter" -> string!
Microsoft.Testing.Extensions.TestCaseFilterCommandLineOptionsProviderBase
Microsoft.Testing.Extensions.TestCaseFilterCommandLineOptionsProviderBase.TestCaseFilterCommandLineOptionsProviderBase(Microsoft.Testing.Platform.Extensions.IExtension! extension, string! optionDescription) -> void
const Microsoft.Testing.Extensions.TestRunParametersCommandLineOptionsProviderBase.TestRunParameterOptionName = "test-parameter" -> string!
Microsoft.Testing.Extensions.TestRunParametersCommandLineOptionsProviderBase
Microsoft.Testing.Extensions.TestRunParametersCommandLineOptionsProviderBase.TestRunParametersCommandLineOptionsProviderBase(Microsoft.Testing.Platform.Extensions.IExtension! extension, string! optionDescription, string! argumentIsNotParameterErrorFormat) -> void
override sealed Microsoft.Testing.Extensions.TestRunParametersCommandLineOptionsProviderBase.ValidateOptionArgumentsAsync(Microsoft.Testing.Platform.Extensions.CommandLine.CommandLineOption! commandOption, string![]! arguments) -> System.Threading.Tasks.Task<Microsoft.Testing.Platform.Extensions.ValidationResult>!
Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.MSTestEngine
Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.MSTestEngine.Cancel() -> void
Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.MSTestEngine.DiscoverAsync(System.Collections.Generic.IEnumerable<string!>! sources, string? settingsXml, Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface.IAdapterMessageLogger! logger, Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface.IUnitTestElementSink! elementSink, Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface.ITestElementFilterProvider? filterProvider, Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface.IConfiguration? configuration, Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface.ITestSourceHandler! testSourceHandler, bool isMTP) -> System.Threading.Tasks.Task!
Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.MSTestEngine.MSTestEngine(System.Threading.CancellationToken cancellationToken, System.Func<string!, System.Collections.Generic.IDictionary<string!, object!>!, System.Threading.Tasks.Task!>? telemetrySender = null, Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.TestExecutionManager? testExecutionManager = null) -> void
Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.MSTestEngine.RunFromSourcesAsync(System.Collections.Generic.IEnumerable<string!>! sources, string? settingsXml, string? testRunDirectory, Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface.IAdapterMessageLogger! logger, System.Func<Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.MSTestSettings!, Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface.ITestResultRecorder!>! recorderFactory, Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface.ITestElementFilterProvider? filterProvider, Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface.IConfiguration? configuration, Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface.ITestSourceHandler! testSourceHandler, bool isMTP) -> System.Threading.Tasks.Task!
Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.MSTestEngine.RunFromTestElementsAsync(System.Func<System.Collections.Generic.IEnumerable<Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.ObjectModel.UnitTestElement!>!>! testElementsFactory, System.Collections.Generic.IEnumerable<string!>! sourcesForInitialization, string? settingsXml, string? testRunDirectory, Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface.IAdapterMessageLogger! logger, System.Func<Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.MSTestSettings!, Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface.ITestResultRecorder!>! recorderFactory, Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface.ITestElementFilterProvider? filterProvider, Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface.IConfiguration? configuration, Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface.ITestSourceHandler! testSourceHandler) -> System.Threading.Tasks.Task!
Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.TestingPlatformAdapter.IUnitTestElementFilterExpression
Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.TestingPlatformAdapter.IUnitTestElementFilterExpression.MatchTestElement(System.Func<string!, object?>! propertyValueProvider) -> bool
Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.TestingPlatformAdapter.MtpTestElementFilterProvider
Expand All @@ -46,16 +51,12 @@ override Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.TestingPlatformA
override Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.TestingPlatformAdapter.MSTestRunSettingsConfigurationProvider.Version.get -> string!
override sealed Microsoft.Testing.Extensions.RunSettingsCommandLineOptionsProviderBase.ValidateCommandLineOptionsAsync(Microsoft.Testing.Platform.CommandLine.ICommandLineOptions! commandLineOptions) -> System.Threading.Tasks.Task<Microsoft.Testing.Platform.Extensions.ValidationResult>!
override sealed Microsoft.Testing.Extensions.RunSettingsCommandLineOptionsProviderBase.ValidateOptionArgumentsAsync(Microsoft.Testing.Platform.Extensions.CommandLine.CommandLineOption! commandOption, string![]! arguments) -> System.Threading.Tasks.Task<Microsoft.Testing.Platform.Extensions.ValidationResult>!
override sealed Microsoft.Testing.Extensions.TestRunParametersCommandLineOptionsProviderBase.ValidateOptionArgumentsAsync(Microsoft.Testing.Platform.Extensions.CommandLine.CommandLineOption! commandOption, string![]! arguments) -> System.Threading.Tasks.Task<Microsoft.Testing.Platform.Extensions.ValidationResult>!
static Microsoft.Testing.Extensions.RunSettingsProviderHelper.ApplyEnvironmentVariables(System.Xml.Linq.XDocument! runSettings, Microsoft.Testing.Platform.Extensions.TestHostControllers.IEnvironmentVariables! environmentVariables) -> void
static Microsoft.Testing.Extensions.RunSettingsProviderHelper.CanReadFile(Microsoft.Testing.Platform.Helpers.IFileSystem! fileSystem, string! filePath) -> bool
static Microsoft.Testing.Extensions.RunSettingsProviderHelper.FindInvalidTestParameter(string![]! arguments) -> string?
static Microsoft.Testing.Extensions.RunSettingsProviderHelper.HasEnvironmentVariables(System.Xml.Linq.XDocument! runSettings) -> bool
static Microsoft.Testing.Extensions.RunSettingsProviderHelper.TryLoadRunSettingsAsync(Microsoft.Testing.Platform.CommandLine.ICommandLineOptions! commandLineOptions, Microsoft.Testing.Platform.Helpers.IFileSystem! fileSystem, Microsoft.Testing.Platform.Helpers.IEnvironment! environment, string! runSettingsOptionName) -> System.Threading.Tasks.Task<System.Xml.Linq.XDocument?>!
static Microsoft.VisualStudio.TestTools.UnitTesting.MSTestTestNodeConverter.ToEmptyResultTestNode(Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.ObjectModel.UnitTestElement! element, bool isTrxEnabled) -> Microsoft.Testing.Platform.Extensions.Messages.TestNode!
Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.MSTestEngine
Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.MSTestEngine.Cancel() -> void
Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.MSTestEngine.DiscoverAsync(System.Collections.Generic.IEnumerable<string!>! sources, string? settingsXml, Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface.IAdapterMessageLogger! logger, Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface.IUnitTestElementSink! elementSink, Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface.ITestElementFilterProvider? filterProvider, Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface.IConfiguration? configuration, Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface.ITestSourceHandler! testSourceHandler, bool isMTP) -> System.Threading.Tasks.Task!
Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.MSTestEngine.MSTestEngine(System.Threading.CancellationToken cancellationToken, System.Func<string!, System.Collections.Generic.IDictionary<string!, object!>!, System.Threading.Tasks.Task!>? telemetrySender = null, Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.TestExecutionManager? testExecutionManager = null) -> void
Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.MSTestEngine.RunFromSourcesAsync(System.Collections.Generic.IEnumerable<string!>! sources, string? settingsXml, string? testRunDirectory, Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface.IAdapterMessageLogger! logger, System.Func<Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.MSTestSettings!, Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface.ITestResultRecorder!>! recorderFactory, Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface.ITestElementFilterProvider? filterProvider, Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface.IConfiguration? configuration, Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface.ITestSourceHandler! testSourceHandler, bool isMTP) -> System.Threading.Tasks.Task!
Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.MSTestEngine.RunFromTestElementsAsync(System.Func<System.Collections.Generic.IEnumerable<Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.ObjectModel.UnitTestElement!>!>! testElementsFactory, System.Collections.Generic.IEnumerable<string!>! sourcesForInitialization, string? settingsXml, string? testRunDirectory, Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface.IAdapterMessageLogger! logger, System.Func<Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.MSTestSettings!, Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface.ITestResultRecorder!>! recorderFactory, Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface.ITestElementFilterProvider? filterProvider, Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface.IConfiguration? configuration, Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface.ITestSourceHandler! testSourceHandler) -> System.Threading.Tasks.Task!
static readonly Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.AdapterTestProperties.DependenciesProperty -> Microsoft.VisualStudio.TestPlatform.ObjectModel.TestProperty!
static readonly Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.AdapterTestProperties.ResourceLocksProperty -> Microsoft.VisualStudio.TestPlatform.ObjectModel.TestProperty!
Loading