diff --git a/scripts/test.ps1 b/scripts/test.ps1
index 338e5e39eb..ed2bea934b 100644
--- a/scripts/test.ps1
+++ b/scripts/test.ps1
@@ -82,8 +82,11 @@ Get-ChildItem "Env:\dotnet_*"
& "$env:DOTNET_ROOT\dotnet.exe" --info
"`n`n---- x86 dotnet"
-& "${env:DOTNET_ROOT(x86)}\dotnet.exe" --info
-
+# avoid erroring out because we don't have the sdk for x86 that global.json requires
+try {
+ & "${env:DOTNET_ROOT(x86)}\dotnet.exe" --info 2> $null
+} catch {}
+
# Dotnet build doesn't support --packages yet. See https://github.com/dotnet/cli/issues/2712
$env:NUGET_PACKAGES = $env:TP_PACKAGES_DIR
diff --git a/src/Microsoft.TestPlatform.ObjectModel/RunSettings/RunConfiguration.cs b/src/Microsoft.TestPlatform.ObjectModel/RunSettings/RunConfiguration.cs
index 24f5ff8959..8b1476124a 100644
--- a/src/Microsoft.TestPlatform.ObjectModel/RunSettings/RunConfiguration.cs
+++ b/src/Microsoft.TestPlatform.ObjectModel/RunSettings/RunConfiguration.cs
@@ -488,6 +488,10 @@ public bool ResultsDirectorySet
public bool CollectSourceInformationSet { get; private set; } = false;
///
+ /// Default filter to use to filter tests
+ ///
+ public string TestCaseFilter { get; private set; }
+
/// Path to dotnet executable to be used to invoke testhost.dll. Specifying this will skip looking up testhost.exe and will force usage of the testhost.dll.
///
public string DotnetHostPath { get; private set; }
@@ -576,6 +580,13 @@ public override XmlElement ToXml()
root.AppendChild(targetDevice);
}
+ if (!string.IsNullOrEmpty(this.TestCaseFilter))
+ {
+ XmlElement testCaseFilter = doc.CreateElement(nameof(TestCaseFilter));
+ testCaseFilter.InnerXml = this.TestCaseFilter;
+ root.AppendChild(testCaseFilter);
+ }
+
if (!string.IsNullOrEmpty(this.DotnetHostPath))
{
XmlElement dotnetHostPath = doc.CreateElement(nameof(DotnetHostPath));
@@ -879,6 +890,11 @@ public static RunConfiguration FromXml(XmlReader reader)
runConfiguration.TargetDevice = reader.ReadElementContentAsString();
break;
+ case "TestCaseFilter":
+ XmlRunSettingsUtilities.ThrowOnHasAttributes(reader);
+ runConfiguration.TestCaseFilter = reader.ReadElementContentAsString();
+ break;
+
case "DotNetHostPath":
XmlRunSettingsUtilities.ThrowOnHasAttributes(reader);
runConfiguration.DotnetHostPath = reader.ReadElementContentAsString();
diff --git a/src/vstest.console/Processors/RunSettingsArgumentProcessor.cs b/src/vstest.console/Processors/RunSettingsArgumentProcessor.cs
index 92866c7ec8..4b7d903567 100644
--- a/src/vstest.console/Processors/RunSettingsArgumentProcessor.cs
+++ b/src/vstest.console/Processors/RunSettingsArgumentProcessor.cs
@@ -142,6 +142,12 @@ public void Initialize(string argument)
this.commandLineOptions.InIsolation = true;
this.runSettingsManager.UpdateRunSettingsNode(InIsolationArgumentExecutor.RunSettingsPath, "true");
}
+
+ var testCaseFilter = this.runSettingsManager.QueryRunSettingsNode("RunConfiguration.TestCaseFilter");
+ if (testCaseFilter != null)
+ {
+ this.commandLineOptions.TestCaseFilterValue = testCaseFilter;
+ }
}
catch (XmlException exception)
{
diff --git a/src/vstest.console/Processors/TestCaseFilterArgumentProcessor.cs b/src/vstest.console/Processors/TestCaseFilterArgumentProcessor.cs
index 3f10e0143d..8eb75e0f05 100644
--- a/src/vstest.console/Processors/TestCaseFilterArgumentProcessor.cs
+++ b/src/vstest.console/Processors/TestCaseFilterArgumentProcessor.cs
@@ -117,12 +117,23 @@ public TestCaseFilterArgumentExecutor(CommandLineOptions options)
/// Argument that was provided with the command.
public void Initialize(string argument)
{
- if (string.IsNullOrWhiteSpace(argument))
+ var defaultFilter = this.commandLineOptions.TestCaseFilterValue;
+ var hasDefaultFilter = !string.IsNullOrWhiteSpace(defaultFilter);
+
+ if (!hasDefaultFilter && string.IsNullOrWhiteSpace(argument))
{
throw new CommandLineException(string.Format(CultureInfo.CurrentUICulture, CommandLineResources.TestCaseFilterValueRequired));
}
- this.commandLineOptions.TestCaseFilterValue = argument;
+ if (!hasDefaultFilter)
+ {
+ this.commandLineOptions.TestCaseFilterValue = argument;
+ }
+ else
+ {
+ // Merge default filter an provided filter by AND operator to have both the default filter and custom filter applied.
+ this.commandLineOptions.TestCaseFilterValue = $"({defaultFilter})&({argument})";
+ }
}
///
diff --git a/src/vstest.console/TestPlatformHelpers/TestRequestManager.cs b/src/vstest.console/TestPlatformHelpers/TestRequestManager.cs
index 08699a5f82..778006ebf5 100644
--- a/src/vstest.console/TestPlatformHelpers/TestRequestManager.cs
+++ b/src/vstest.console/TestPlatformHelpers/TestRequestManager.cs
@@ -150,6 +150,7 @@ public void DiscoverTests(DiscoveryRequestPayload discoveryPayload, ITestDiscove
var runConfiguration = XmlRunSettingsUtilities.GetRunConfigurationNode(runsettings);
var batchSize = runConfiguration.BatchSize;
+ var testCaseFilterFromRunsettings = runConfiguration.TestCaseFilter;
if (requestData.IsTelemetryOptedIn)
{
@@ -160,10 +161,12 @@ public void DiscoverTests(DiscoveryRequestPayload discoveryPayload, ITestDiscove
this.LogCommandsTelemetryPoints(requestData);
}
+
+
// create discovery request
var criteria = new DiscoveryCriteria(discoveryPayload.Sources, batchSize, this.commandLineOptions.TestStatsEventTimeout, runsettings)
{
- TestCaseFilter = this.commandLineOptions.TestCaseFilterValue
+ TestCaseFilter = this.commandLineOptions.TestCaseFilterValue ?? testCaseFilterFromRunsettings
};
// Make sure to run the run request inside a lock as the below section is not thread-safe
diff --git a/test/vstest.console.UnitTests/Processors/RunSettingsArgumentProcessorTests.cs b/test/vstest.console.UnitTests/Processors/RunSettingsArgumentProcessorTests.cs
index bc3d6ef0fa..838f76fc6e 100644
--- a/test/vstest.console.UnitTests/Processors/RunSettingsArgumentProcessorTests.cs
+++ b/test/vstest.console.UnitTests/Processors/RunSettingsArgumentProcessorTests.cs
@@ -363,6 +363,30 @@ public void InitializeShouldNotSetInIsolataionToTrueIfEnvironmentVariablesNotSpe
Assert.IsNull(this.settingsProvider.QueryRunSettingsNode(InIsolationArgumentExecutor.RunSettingsPath));
}
+ [TestMethod]
+ public void InitializeShouldUpdateTestCaseFilterIfProvided()
+ {
+ // Arrange.
+ var fileName = "C:\\temp\\r.runsettings";
+ var filter = "TestCategory=Included";
+ var settingsXml = $"{filter}";
+
+ var executor = new TestableRunSettingsArgumentExecutor(
+ CommandLineOptions.Instance,
+ this.settingsProvider,
+ settingsXml);
+
+ // Setup mocks.
+ var mockFileHelper = new Mock();
+ mockFileHelper.Setup(fh => fh.Exists(It.IsAny())).Returns(true);
+ executor.FileHelper = mockFileHelper.Object;
+
+ // Act.
+ executor.Initialize(fileName);
+
+ // Assert.
+ Assert.AreEqual(filter, CommandLineOptions.Instance.TestCaseFilterValue);
+ }
#endregion
#region Testable Implementations
diff --git a/test/vstest.console.UnitTests/Processors/TestCaseFilterArgumentProcessorTests.cs b/test/vstest.console.UnitTests/Processors/TestCaseFilterArgumentProcessorTests.cs
index d684c7109c..7bd0c9292d 100644
--- a/test/vstest.console.UnitTests/Processors/TestCaseFilterArgumentProcessorTests.cs
+++ b/test/vstest.console.UnitTests/Processors/TestCaseFilterArgumentProcessorTests.cs
@@ -64,13 +64,29 @@ public void ExecutorInitializeWithNullOrEmptyTestCaseFilterShouldThrowCommandLin
}
[TestMethod]
- public void ExecutorInitializeWithValidTestCaseFilterShouldAddTestCaseFilterToCommandLineOptions()
+ public void ExecutorInitializeWithNullOrEmptyTestCaseFilterShouldNotThrowWhenTestFilterWasSpecifiedByPreviousStep()
+ {
+ var options = CommandLineOptions.Instance;
+ options.TestCaseFilterValue = "Test=FilterFromPreviousStep";
+ TestCaseFilterArgumentExecutor executor = new TestCaseFilterArgumentExecutor(options);
+
+ executor.Initialize(null);
+ }
+
+ [TestMethod]
+ public void ExecutorInitializeWithTestCaseFilterShouldMergeWithTheValueProvidedByPreviousStep()
{
var options = CommandLineOptions.Instance;
+ var defaultValue = "Test=FilterFromPreviousStep";
+ options.TestCaseFilterValue = defaultValue;
+ Assert.AreEqual(defaultValue, options.TestCaseFilterValue);
TestCaseFilterArgumentExecutor executor = new TestCaseFilterArgumentExecutor(options);
- executor.Initialize("Debug");
- Assert.AreEqual("Debug", options.TestCaseFilterValue);
+ var value = "Test=NewFilter";
+ executor.Initialize(value);
+
+ var expectedValue = $"({defaultValue})&({value})";
+ Assert.AreEqual(expectedValue, options.TestCaseFilterValue);
}
[TestMethod]