Skip to content

Commit

Permalink
Allow specifying Test Selection Language filters in VSTest runsettings
Browse files Browse the repository at this point in the history
This allows using `dotnet test` as a drop in replacement for a
nunit-console run with the `--where` option.

i.e.:

`nunit-console SomeTests.dll --where "cat == SomeCategory"`
becomes
`dotnet test SomeTest.csproj -- NUnit.TestsWhere="cat == SomeCategory"`
  • Loading branch information
mletterle committed Oct 30, 2019
1 parent bddee2c commit 3358c8c
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 8 deletions.
3 changes: 3 additions & 0 deletions src/NUnitTestAdapter/AdapterSettings.cs
Expand Up @@ -41,6 +41,7 @@ public interface IAdapterSettings
IDictionary<string, string> TestProperties { get; }
string InternalTraceLevel { get; }
string WorkDirectory { get; }
string TestsWhere { get; }
int DefaultTimeout { get; }
int NumberOfTestWorkers { get; }
bool ShadowCopyFiles { get; }
Expand Down Expand Up @@ -157,6 +158,7 @@ public AdapterSettings(TestLogger logger)
public string InternalTraceLevel { get; private set; }

public string WorkDirectory { get; private set; }
public string TestsWhere { get; private set; }
public string TestOutputXml { get; private set; }
public bool UseTestOutputXml => !string.IsNullOrEmpty(TestOutputXml);
public int DefaultTimeout { get; private set; }
Expand Down Expand Up @@ -254,6 +256,7 @@ public void Load(string settingsXml)
InternalTraceLevel = GetInnerTextWithLog(nunitNode, nameof(InternalTraceLevel), "Off", "Error", "Warning",
"Info", "Verbose", "Debug");
WorkDirectory = GetInnerTextWithLog(nunitNode, nameof(WorkDirectory));
TestsWhere = GetInnerTextWithLog(nunitNode, nameof(TestsWhere));
DefaultTimeout = GetInnerTextAsInt(nunitNode, nameof(DefaultTimeout), 0);
NumberOfTestWorkers = GetInnerTextAsInt(nunitNode, nameof(NumberOfTestWorkers), -1);
ShadowCopyFiles = GetInnerTextAsBool(nunitNode, nameof(ShadowCopyFiles), false);
Expand Down
5 changes: 3 additions & 2 deletions src/NUnitTestAdapter/NUnit3TestExecutor.cs
Expand Up @@ -99,8 +99,9 @@ public void RunTests(IEnumerable<string> sources, IRunContext runContext, IFrame
try
{
var assemblyPath = Path.IsPathRooted(assemblyName) ? assemblyName : Path.Combine(Directory.GetCurrentDirectory(), assemblyName);
var filter = CreateTestFilterBuilder().MakeTestFilter(null, Settings.TestsWhere);

RunAssembly(assemblyPath, null, TestFilter.Empty);
RunAssembly(assemblyPath, null, filter);
}
catch (Exception ex)
{
Expand Down Expand Up @@ -143,7 +144,7 @@ public void RunTests(IEnumerable<TestCase> tests, IRunContext runContext, IFrame
var assemblyPath = Path.IsPathRooted(assemblyName) ? assemblyName : Path.Combine(Directory.GetCurrentDirectory(), assemblyName);

var filterBuilder = CreateTestFilterBuilder();
var filter = filterBuilder.MakeTestFilter(assemblyGroup);
var filter = filterBuilder.MakeTestFilter(assemblyGroup, Settings.TestsWhere);

RunAssembly(assemblyPath, assemblyGroup, filter);
}
Expand Down
19 changes: 13 additions & 6 deletions src/NUnitTestAdapter/NUnitTestFilterBuilder.cs
Expand Up @@ -29,15 +29,22 @@ public TestFilter ConvertTfsFilterToNUnitFilter(TfsTestFilter tfsFilter, List<Te
return MakeTestFilter(testCases);
}

public TestFilter MakeTestFilter(IEnumerable<TestCase> testCases)
public TestFilter MakeTestFilter(IEnumerable<TestCase> testCases = null, string where = null)
{
if (testCases.Count() == 0)
return NoTestsFound;

ITestFilterBuilder filterBuilder = _filterService.GetTestFilterBuilder();

foreach (TestCase testCase in testCases)
filterBuilder.AddTest(testCase.FullyQualifiedName);
if(!string.IsNullOrEmpty(where))
{
filterBuilder.SelectWhere(where);
}

if(testCases is null == false)
{
foreach (TestCase testCase in testCases)
{
filterBuilder.AddTest(testCase.FullyQualifiedName);
}
}

return filterBuilder.GetFilter();
}
Expand Down
7 changes: 7 additions & 0 deletions src/NUnitTestAdapterTests/AdapterSettingsTests.cs
Expand Up @@ -367,5 +367,12 @@ public void LiveUnitTestingDataCollector()
Assert.That(_settings.NumberOfTestWorkers, Is.Zero);
Assert.True(_settings.InProcDataCollectorsAvailable);
}

[Test]
public void TestsWhereCanBeSet()
{
_settings.Load("<RunSettings><NUnit><TestsWhere>cat == SomeCategory and namespace == SomeNamespace or cat != SomeOtherCategory</TestsWhere></NUnit></RunSettings>");
Assert.That(_settings.TestsWhere, Is.EqualTo("cat == SomeCategory and namespace == SomeNamespace or cat != SomeOtherCategory"));
}
}
}
11 changes: 11 additions & 0 deletions src/NUnitTestAdapterTests/Fakes/FakeRunSettings.cs
Expand Up @@ -54,4 +54,15 @@ public FakeRunSettingsForTestOutputAndWorkDir(string testOutput,string workDir)
public override string SettingsXml => $"<RunSettings><NUnit><WorkDirectory>{_workDir}</WorkDirectory><TestOutputXml>{_testOutput}</TestOutputXml></NUnit></RunSettings>";
}

class FakeRunSettingsForTestWhere : FakeRunSettings
{
private readonly string _where;

public FakeRunSettingsForTestWhere(string where)
{
_where = where;
}
public override string SettingsXml => $"<RunSettings><NUnit><TestsWhere>{_where}</TestsWhere></NUnit></RunSettings>";
}

}
39 changes: 39 additions & 0 deletions src/NUnitTestAdapterTests/TestExecutionTests.cs
Expand Up @@ -62,6 +62,45 @@ private int GetCount(TestOutcome outcome)
}


[Category("TestExecution")]
public class TestFilteringTests
{
private string MockAssemblyPath;
[OneTimeSetUp]
public void LoadMockassembly()
{
MockAssemblyPath = Path.Combine(TestContext.CurrentContext.TestDirectory, "mock-assembly.dll");

// Sanity check to be sure we have the correct version of mock-assembly.dll
Assert.That(MockAssembly.TestsAtRuntime, Is.EqualTo(MockAssembly.Tests),
"The reference to mock-assembly.dll appears to be the wrong version");
}

[TestCase("", 35)]
[TestCase(null, 35)]
[TestCase("cat == Special", 1)]
[TestCase("cat == MockCategory", 2)]
[TestCase("method =~ MockTest?", 5)]
[TestCase("method =~ MockTest? and cat != MockCategory", 3)]
[TestCase("namespace == ThisNamespaceDoesNotExist", 0)]
[TestCase("test==NUnit.Tests.Assemblies.MockTestFixture", MockTestFixture.Tests, TestName = "{m}_MockTestFixture")]
[TestCase("test==NUnit.Tests.IgnoredFixture and method == Test2", 1, TestName = "{m}_IgnoredFixture")]
[TestCase("class==NUnit.Tests.Assemblies.MockTestFixture", MockTestFixture.Tests)]
[TestCase("name==MockTestFixture", MockTestFixture.Tests + NUnit.Tests.TestAssembly.MockTestFixture.Tests)]
[TestCase("cat==FixtureCategory", MockTestFixture.Tests)]
public void TestsWhereShouldFilter(string filter, int expectedCount)
{
// Create a fake environment.
var context = new FakeRunContext(new FakeRunSettingsForTestWhere(filter));
var fakeFramework = new FakeFrameworkHandle();

var executor = TestAdapterUtils.CreateExecutor();
executor.RunTests(new[] { MockAssemblyPath }, context, fakeFramework);

Assert.AreEqual(expectedCount, fakeFramework.Events.Where(e => e.EventType == FakeFrameworkHandle.EventType.RecordEnd).Count());
}

}

[Category("TestExecution")]
public class TestExecutionTests
Expand Down

0 comments on commit 3358c8c

Please sign in to comment.