diff --git a/xunit.runner.data/TestCaseData.cs b/xunit.runner.data/TestCaseData.cs index 5efad84..058ec0b 100644 --- a/xunit.runner.data/TestCaseData.cs +++ b/xunit.runner.data/TestCaseData.cs @@ -6,12 +6,14 @@ namespace Xunit.Runner.Data public sealed class TestCaseData { public string DisplayName { get; set; } + public string SkipReason { get; set; } public string AssemblyPath { get; set; } public Dictionary> TraitMap { get; set; } - public TestCaseData(string displayName, string assemblyPath, Dictionary> traitMap) + public TestCaseData(string displayName, string skipReason, string assemblyPath, Dictionary> traitMap) { DisplayName = displayName; + SkipReason = skipReason; AssemblyPath = assemblyPath; TraitMap = traitMap; } @@ -19,6 +21,7 @@ namespace Xunit.Runner.Data public static TestCaseData ReadFrom(BinaryReader reader) { var displayName = reader.ReadString(); + var skipReason = reader.ReadString(); var assemblyPath = reader.ReadString(); var count = reader.ReadInt32(); var traitMap = new Dictionary>(count); @@ -37,12 +40,13 @@ namespace Xunit.Runner.Data traitMap.Add(key, values); } - return new TestCaseData(displayName, assemblyPath, traitMap); + return new TestCaseData(displayName, skipReason, assemblyPath, traitMap); } public void WriteTo(BinaryWriter writer) { writer.Write(DisplayName); + writer.Write(SkipReason ?? string.Empty); writer.Write(AssemblyPath); writer.Write(TraitMap.Count); diff --git a/xunit.runner.worker/DiscoverUtil.cs b/xunit.runner.worker/DiscoverUtil.cs index 6b90270..cda4357 100644 --- a/xunit.runner.worker/DiscoverUtil.cs +++ b/xunit.runner.worker/DiscoverUtil.cs @@ -23,6 +23,7 @@ namespace Xunit.Runner.Worker var testCase = testCaseDiscovered.TestCase; var testCaseData = new TestCaseData( testCase.DisplayName, + testCase.SkipReason, testCaseDiscovered.TestAssembly.Assembly.AssemblyPath, testCase.Traits); diff --git a/xunit.runner.wpf/MainWindow.xaml b/xunit.runner.wpf/MainWindow.xaml index c2461af..36f88a5 100644 --- a/xunit.runner.wpf/MainWindow.xaml +++ b/xunit.runner.wpf/MainWindow.xaml @@ -215,11 +215,12 @@ - + Grid.Column="0" + Command="{Binding TestFilterChanged}"> - + Grid.Column="1" + Command="{Binding TestFilterChanged}"> - + Grid.Column="2" + Command="{Binding TestFilterChanged}"> + diff --git a/xunit.runner.wpf/ViewModel/MainViewModel.cs b/xunit.runner.wpf/ViewModel/MainViewModel.cs index dcb29ed..00b4584 100644 --- a/xunit.runner.wpf/ViewModel/MainViewModel.cs +++ b/xunit.runner.wpf/ViewModel/MainViewModel.cs @@ -33,6 +33,8 @@ namespace Xunit.Runner.Wpf.ViewModel public FilteredCollectionView FilteredTestCases { get; } public ObservableCollection Traits => this.traitCollectionView.Collection; + private ImmutableList runningTests; + public MainViewModel() { if (IsInDesignMode) @@ -84,19 +86,21 @@ namespace Xunit.Runner.Wpf.ViewModel } } + var noFilter = !(searchQuery.FilterFailedTests | searchQuery.FilterPassedTests | searchQuery.FilterSkippedTests); + switch (testCase.State) { case TestState.Passed: - return searchQuery.IncludePassedTests; + return noFilter || searchQuery.FilterPassedTests; case TestState.Skipped: - return searchQuery.IncludeSkippedTests; + return noFilter || searchQuery.FilterSkippedTests; case TestState.Failed: - return searchQuery.IncludeFailedTests; + return noFilter || searchQuery.FilterFailedTests; case TestState.NotRun: - return true; + return noFilter; default: Debug.Assert(false, "What state is this test case in?"); @@ -423,13 +427,18 @@ namespace Xunit.Runner.Wpf.ViewModel private async void OnExecuteRun() { + Debug.Assert(this.runningTests == null); + await ExecuteTestSessionOperation(RunTests); + + this.runningTests = null; } private List RunTests() { Debug.Assert(this.isBusy); Debug.Assert(this.cancellationTokenSource != null); + Debug.Assert(this.runningTests == null); TestsCompleted = 0; TestsPassed = 0; @@ -438,15 +447,17 @@ namespace Xunit.Runner.Wpf.ViewModel CurrentRunState = TestState.NotRun; Output = string.Empty; - foreach (var tc in FilteredTestCases) + this.runningTests = FilteredTestCases.ToImmutableList(); + + foreach (var tc in this.runningTests) { tc.State = TestState.NotRun; } - var runAll = FilteredTestCases.Count == this.allTestCases.Count; + var runAll = this.runningTests.Count == this.allTestCases.Count; var testSessionList = new List(); - foreach (var assemblyFileName in FilteredTestCases.Select(x => x.AssemblyFileName).Distinct()) + foreach (var assemblyFileName in this.runningTests.Select(x => x.AssemblyFileName).Distinct()) { Task task; if (runAll) @@ -457,7 +468,7 @@ namespace Xunit.Runner.Wpf.ViewModel { var builder = ImmutableArray.CreateBuilder(); - foreach (var testCase in FilteredTestCases) + foreach (var testCase in this.runningTests) { if (testCase.AssemblyFileName == assemblyFileName) { @@ -527,44 +538,47 @@ namespace Xunit.Runner.Wpf.ViewModel var testCaseViewModel = new TestCaseViewModel( testCase.DisplayName, + testCase.SkipReason, testCase.AssemblyPath, traitWorkerList); + if (testCaseViewModel.State == TestState.Skipped) + { + TestsSkipped++; + } + this.allTestCases.Add(testCaseViewModel); } } private void OnTestsFinished(IEnumerable testResultData) { - foreach (var data in testResultData) - { - OnTestFinished(data); - } - } + Debug.Assert(this.runningTests != null); - private void OnTestFinished(TestResultData testResultData) - { - var testCase = FilteredTestCases.Single(x => x.DisplayName == testResultData.TestCaseDisplayName); - testCase.State = testResultData.TestState; - - TestsCompleted++; - switch (testResultData.TestState) + foreach (var result in testResultData) { - case TestState.Passed: - TestsPassed++; - break; - case TestState.Failed: - TestsFailed++; - Output = Output + testResultData.Output; - break; - case TestState.Skipped: - TestsSkipped++; - break; - } + var testCase = this.runningTests.Single(x => x.DisplayName == result.TestCaseDisplayName); + testCase.State = result.TestState; - if (testResultData.TestState > CurrentRunState) - { - CurrentRunState = testResultData.TestState; + TestsCompleted++; + switch (result.TestState) + { + case TestState.Passed: + TestsPassed++; + break; + case TestState.Failed: + TestsFailed++; + Output = Output + result.Output; + break; + case TestState.Skipped: + TestsSkipped++; + break; + } + + if (result.TestState > CurrentRunState) + { + CurrentRunState = result.TestState; + } } } @@ -623,36 +637,36 @@ namespace Xunit.Runner.Wpf.ViewModel RemoveAssemblies(Assemblies.ToArray()); } - public bool IncludePassedTests + public bool FilterPassedTests { - get { return searchQuery.IncludePassedTests; } + get { return searchQuery.FilterPassedTests; } set { - if (Set(ref searchQuery.IncludePassedTests, value)) + if (Set(ref searchQuery.FilterPassedTests, value)) { FilterAfterDelay(); } } } - public bool IncludeFailedTests + public bool FilterFailedTests { - get { return searchQuery.IncludeFailedTests; } + get { return searchQuery.FilterFailedTests; } set { - if (Set(ref searchQuery.IncludeFailedTests, value)) + if (Set(ref searchQuery.FilterFailedTests, value)) { FilterAfterDelay(); } } } - public bool IncludeSkippedTests + public bool FilterSkippedTests { - get { return searchQuery.IncludeSkippedTests; } + get { return searchQuery.FilterSkippedTests; } set { - if (Set(ref searchQuery.IncludeSkippedTests, value)) + if (Set(ref searchQuery.FilterSkippedTests, value)) { FilterAfterDelay(); } diff --git a/xunit.runner.wpf/ViewModel/SearchQuery.cs b/xunit.runner.wpf/ViewModel/SearchQuery.cs index 65ea5b2..2105fce 100644 --- a/xunit.runner.wpf/ViewModel/SearchQuery.cs +++ b/xunit.runner.wpf/ViewModel/SearchQuery.cs @@ -4,9 +4,9 @@ namespace Xunit.Runner.Wpf.ViewModel { public class SearchQuery { - public bool IncludeFailedTests = true; - public bool IncludePassedTests = true; - public bool IncludeSkippedTests = true; + public bool FilterFailedTests = false; + public bool FilterPassedTests = false; + public bool FilterSkippedTests = false; public string SearchString = string.Empty; public ISet TraitSet = new HashSet(TraitViewModel.EqualityComparer); } diff --git a/xunit.runner.wpf/ViewModel/TestCaseViewModel.cs b/xunit.runner.wpf/ViewModel/TestCaseViewModel.cs index 14cfb76..67a07a0 100644 --- a/xunit.runner.wpf/ViewModel/TestCaseViewModel.cs +++ b/xunit.runner.wpf/ViewModel/TestCaseViewModel.cs @@ -9,14 +9,12 @@ namespace Xunit.Runner.Wpf.ViewModel { private TestState _state = TestState.NotRun; - public TestCaseViewModel(string displayName, string assemblyFileName, IEnumerable traits) - { - this.DisplayName = displayName; - this.AssemblyFileName = assemblyFileName; - this.Traits = traits.ToImmutableArray(); - } - public string DisplayName { get; } + public string SkipReason { get; } + public string AssemblyFileName { get; } + public ImmutableArray Traits { get; } + + public bool HasSkipReason => !string.IsNullOrEmpty(this.SkipReason); public TestState State { @@ -24,8 +22,17 @@ namespace Xunit.Runner.Wpf.ViewModel set { Set(ref _state, value); } } - public string AssemblyFileName { get; } + public TestCaseViewModel(string displayName, string skipReason, string assemblyFileName, IEnumerable traits) + { + this.DisplayName = displayName; + this.SkipReason = skipReason; + this.AssemblyFileName = assemblyFileName; + this.Traits = traits.ToImmutableArray(); - public ImmutableArray Traits { get; } + if (!string.IsNullOrEmpty(skipReason)) + { + _state = TestState.Skipped; + } + } } }