Merge pull request #53 from DustinCampbell/test-state-filters
Invert test case filter buttons and mark skipped tests during discovery
This commit is contained in:
@@ -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<string, List<string>> TraitMap { get; set; }
|
||||
|
||||
public TestCaseData(string displayName, string assemblyPath, Dictionary<string, List<string>> traitMap)
|
||||
public TestCaseData(string displayName, string skipReason, string assemblyPath, Dictionary<string, List<string>> 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<string, List<string>>(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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -215,11 +215,12 @@
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<ToggleButton IsChecked="{Binding IncludePassedTests}"
|
||||
<ToggleButton IsChecked="{Binding FilterPassedTests}"
|
||||
BorderThickness="0"
|
||||
Background="Transparent"
|
||||
Margin="0,4,2,4"
|
||||
Grid.Column="0">
|
||||
Grid.Column="0"
|
||||
Command="{Binding TestFilterChanged}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Image Source="Artwork\Passed_large.png" />
|
||||
<TextBlock Margin="4,0"
|
||||
@@ -229,11 +230,12 @@
|
||||
</StackPanel>
|
||||
</ToggleButton>
|
||||
|
||||
<ToggleButton IsChecked="{Binding IncludeFailedTests}"
|
||||
<ToggleButton IsChecked="{Binding FilterFailedTests}"
|
||||
BorderThickness="0"
|
||||
Background="Transparent"
|
||||
Margin="2,4"
|
||||
Grid.Column="1">
|
||||
Grid.Column="1"
|
||||
Command="{Binding TestFilterChanged}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Image Source="Artwork\Failed_large.png" />
|
||||
<TextBlock Margin="4,0"
|
||||
@@ -243,11 +245,12 @@
|
||||
</StackPanel>
|
||||
</ToggleButton>
|
||||
|
||||
<ToggleButton IsChecked="{Binding IncludeSkippedTests}"
|
||||
<ToggleButton IsChecked="{Binding FilterSkippedTests}"
|
||||
BorderThickness="0"
|
||||
Background="Transparent"
|
||||
Margin="2,4,0,4"
|
||||
Grid.Column="2">
|
||||
Grid.Column="2"
|
||||
Command="{Binding TestFilterChanged}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Image Source="Artwork\Skipped_large.png" />
|
||||
<TextBlock Margin="4,0"
|
||||
@@ -273,6 +276,7 @@
|
||||
Margin="0,0,2,0"
|
||||
Source="{Binding Path=State, Mode=OneWay, Converter={StaticResource TestStateConverter}}"
|
||||
Grid.Column="0" />
|
||||
|
||||
<TextBlock Text="{Binding DisplayName}"
|
||||
VerticalAlignment="Center"
|
||||
Grid.Column="1" />
|
||||
|
||||
@@ -33,6 +33,8 @@ namespace Xunit.Runner.Wpf.ViewModel
|
||||
public FilteredCollectionView<TestCaseViewModel, SearchQuery> FilteredTestCases { get; }
|
||||
public ObservableCollection<TraitViewModel> Traits => this.traitCollectionView.Collection;
|
||||
|
||||
private ImmutableList<TestCaseViewModel> 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<Task> 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<Task>();
|
||||
|
||||
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<string>();
|
||||
|
||||
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> 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();
|
||||
}
|
||||
|
||||
@@ -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<TraitViewModel> TraitSet = new HashSet<TraitViewModel>(TraitViewModel.EqualityComparer);
|
||||
}
|
||||
|
||||
@@ -9,14 +9,12 @@ namespace Xunit.Runner.Wpf.ViewModel
|
||||
{
|
||||
private TestState _state = TestState.NotRun;
|
||||
|
||||
public TestCaseViewModel(string displayName, string assemblyFileName, IEnumerable<TraitViewModel> 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<TraitViewModel> 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<TraitViewModel> traits)
|
||||
{
|
||||
this.DisplayName = displayName;
|
||||
this.SkipReason = skipReason;
|
||||
this.AssemblyFileName = assemblyFileName;
|
||||
this.Traits = traits.ToImmutableArray();
|
||||
|
||||
public ImmutableArray<TraitViewModel> Traits { get; }
|
||||
if (!string.IsNullOrEmpty(skipReason))
|
||||
{
|
||||
_state = TestState.Skipped;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user