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:
Dustin Campbell
2015-12-06 11:06:54 -08:00
6 changed files with 93 additions and 63 deletions
+6 -2
View File
@@ -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);
+1
View File
@@ -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);
+10 -6
View File
@@ -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" />
+57 -43
View File
@@ -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();
}
+3 -3
View File
@@ -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;
}
}
}
}