Compare commits
15 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 39f89587fc | |||
| 8c3c86d918 | |||
| 761f801e43 | |||
| 643d9061c8 | |||
| 6d4a249a97 | |||
| 5ed3579b30 | |||
| 1f55afd2e9 | |||
| c6c48067a7 | |||
| ab5b3afea2 | |||
| feb8588961 | |||
| 08907d707c | |||
| de354d8095 | |||
| dd668f753b | |||
| a5712e104a | |||
| f2e1c0fb5e |
@@ -3,4 +3,8 @@ XUnit Gui written in WPF
|
||||
|
||||
A simple replacement for the old winforms xunit.gui with support for xunit 2.0.
|
||||
|
||||
Find it on NuGet at [xunit.runner.wpf](https://www.nuget.org/packages/xunit.runner.wpf).
|
||||
|
||||

|
||||
|
||||
[](https://ci.appveyor.com/project/Pilchie/xunit-runner-wpf/branch/master)
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 127 KiB |
@@ -10,6 +10,7 @@ namespace Xunit.Runner.Data
|
||||
{
|
||||
All = 0,
|
||||
NotRun,
|
||||
Running,
|
||||
Passed,
|
||||
Skipped,
|
||||
Failed,
|
||||
|
||||
@@ -35,7 +35,7 @@ namespace Xunit.Runner.Worker
|
||||
|
||||
internal static void Go(string assemblyFileName, Stream stream)
|
||||
{
|
||||
Go(assemblyFileName, stream, AppDomainSupport.Denied,
|
||||
Go(assemblyFileName, stream, AppDomainSupport.IfAvailable,
|
||||
(xunit, configuration, writer) =>
|
||||
{
|
||||
using (var sink = new TestDiscoverySink(writer))
|
||||
|
||||
@@ -19,6 +19,12 @@ namespace Xunit.Runner.Worker.MessageSinks
|
||||
|
||||
protected override bool OnMessage(IMessageSinkMessage message)
|
||||
{
|
||||
var testStarted = message as ITestStarting;
|
||||
if (testStarted != null)
|
||||
{
|
||||
OnTestStarted(testStarted);
|
||||
}
|
||||
|
||||
var testFailed = message as ITestFailed;
|
||||
if (testFailed != null)
|
||||
{
|
||||
@@ -47,6 +53,7 @@ namespace Xunit.Runner.Worker.MessageSinks
|
||||
|
||||
protected virtual bool ShouldContinue => true;
|
||||
|
||||
protected abstract void OnTestStarted(ITestStarting testStarted);
|
||||
protected abstract void OnTestFailed(ITestFailed testFailed);
|
||||
protected abstract void OnTestPassed(ITestPassed testPassed);
|
||||
protected abstract void OnTestSkipped(ITestSkipped testSkipped);
|
||||
|
||||
@@ -23,13 +23,18 @@ namespace Xunit.Runner.Worker
|
||||
|
||||
private void Process(string displayName, string uniqueID, TestState state, string output = "")
|
||||
{
|
||||
Console.WriteLine($"{state} - {displayName}");
|
||||
System.Diagnostics.Trace.WriteLine($"{state} - {displayName}");
|
||||
var result = new TestResultData(displayName, uniqueID, state, output);
|
||||
|
||||
_writer.Write(TestDataKind.Value);
|
||||
_writer.Write(result);
|
||||
}
|
||||
|
||||
protected override void OnTestStarted(ITestStarting testStarted)
|
||||
{
|
||||
Process(testStarted.TestCase.DisplayName, testStarted.TestCase.UniqueID, TestState.Running);
|
||||
}
|
||||
|
||||
protected override void OnTestFailed(ITestFailed testFailed)
|
||||
{
|
||||
var displayName = testFailed.TestCase.DisplayName;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 14
|
||||
VisualStudioVersion = 14.0.23107.0
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.26430.4
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "xunit.runner.wpf", "xunit.runner.wpf\xunit.runner.wpf.csproj", "{34FB519C-FB49-4B31-ACA2-7F7879311BCF}"
|
||||
EndProject
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 659 B |
Binary file not shown.
|
After Width: | Height: | Size: 402 B |
@@ -9,6 +9,7 @@ namespace Xunit.Runner.Wpf.Converters
|
||||
{
|
||||
public class TestStateConverter : IValueConverter
|
||||
{
|
||||
private static ImageSource runningSource;
|
||||
private static ImageSource failedSource;
|
||||
private static ImageSource passedSource;
|
||||
private static ImageSource skippedSource;
|
||||
@@ -17,6 +18,7 @@ namespace Xunit.Runner.Wpf.Converters
|
||||
|
||||
static TestStateConverter()
|
||||
{
|
||||
runningSource = LoadResourceImage("Running_small.png");
|
||||
failedSource = LoadResourceImage("Failed_small.png");
|
||||
passedSource = LoadResourceImage("Passed_small.png");
|
||||
skippedSource = LoadResourceImage("Skipped_small.png");
|
||||
@@ -38,6 +40,8 @@ namespace Xunit.Runner.Wpf.Converters
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case TestState.Running:
|
||||
return Brushes.Blue;
|
||||
case TestState.Failed:
|
||||
return Brushes.Red;
|
||||
case TestState.Passed:
|
||||
@@ -52,6 +56,8 @@ namespace Xunit.Runner.Wpf.Converters
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case TestState.Running:
|
||||
return runningSource;
|
||||
case TestState.Failed:
|
||||
return failedSource;
|
||||
case TestState.Passed:
|
||||
|
||||
@@ -277,6 +277,21 @@
|
||||
VerticalAlignment="Center" />
|
||||
</StackPanel>
|
||||
</ToggleButton>
|
||||
|
||||
<ToggleButton IsChecked="{Binding FilterRunningTests}"
|
||||
BorderThickness="0"
|
||||
Background="Transparent"
|
||||
Margin="2,4,0,4"
|
||||
Grid.Column="2"
|
||||
Command="{Binding TestFilterChanged}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Image Source="Artwork\Running_large.png" />
|
||||
<TextBlock Margin="4,0"
|
||||
FontSize="16"
|
||||
Text="{Binding TestsRunning, StringFormat={}{0:#\,0}}"
|
||||
VerticalAlignment="Center" />
|
||||
</StackPanel>
|
||||
</ToggleButton>
|
||||
</StackPanel>
|
||||
|
||||
<ListBox x:Name="TestCases" ItemsSource="{Binding FilteredTestCases}"
|
||||
|
||||
@@ -125,6 +125,10 @@ namespace Xunit.Runner.Wpf.Persistence
|
||||
|
||||
settings.autoReloadAssemblies = autoReloadAssemblies;
|
||||
}
|
||||
else
|
||||
{
|
||||
settings.autoReloadAssemblies = true;
|
||||
}
|
||||
|
||||
return settings;
|
||||
}
|
||||
|
||||
@@ -29,6 +29,8 @@ namespace Xunit.Runner.Wpf.ViewModel
|
||||
private readonly HashSet<string> allTestCaseUniqueIDs = new HashSet<string>();
|
||||
private readonly ObservableCollection<TestCaseViewModel> allTestCases = new ObservableCollection<TestCaseViewModel>();
|
||||
private readonly TraitCollectionView traitCollectionView = new TraitCollectionView();
|
||||
private readonly HashSet<string> runningTestSet = new HashSet<string>();
|
||||
|
||||
private CancellationTokenSource filterCancellationTokenSource = new CancellationTokenSource();
|
||||
|
||||
private CancellationTokenSource cancellationTokenSource;
|
||||
@@ -52,7 +54,7 @@ namespace Xunit.Runner.Wpf.ViewModel
|
||||
|
||||
public ObservableCollection<RecentAssemblyViewModel> RecentAssemblies { get; } = new ObservableCollection<RecentAssemblyViewModel>();
|
||||
|
||||
private ImmutableList<TestCaseViewModel> runningTests;
|
||||
private ImmutableList<TestCaseViewModel> testsToRun;
|
||||
|
||||
public ICommand ExitCommand { get; }
|
||||
public ICommand WindowLoadedCommand { get; }
|
||||
@@ -107,6 +109,7 @@ namespace Xunit.Runner.Wpf.ViewModel
|
||||
|
||||
RebuildRecentAssembliesMenu();
|
||||
AutoReloadAssemblies = this.settings.GetAutoReloadAssemblies();
|
||||
UpdateAutoReloadStatus();
|
||||
}
|
||||
|
||||
private void RebuildRecentAssembliesMenu()
|
||||
@@ -152,10 +155,13 @@ namespace Xunit.Runner.Wpf.ViewModel
|
||||
}
|
||||
}
|
||||
|
||||
var noFilter = !(searchQuery.FilterFailedTests | searchQuery.FilterPassedTests | searchQuery.FilterSkippedTests);
|
||||
var noFilter = !(searchQuery.FilterRunningTests | searchQuery.FilterFailedTests | searchQuery.FilterPassedTests | searchQuery.FilterSkippedTests);
|
||||
|
||||
switch (testCase.State)
|
||||
{
|
||||
case TestState.Running:
|
||||
return noFilter || searchQuery.FilterRunningTests;
|
||||
|
||||
case TestState.Passed:
|
||||
return noFilter || searchQuery.FilterPassedTests;
|
||||
|
||||
@@ -262,6 +268,13 @@ namespace Xunit.Runner.Wpf.ViewModel
|
||||
}
|
||||
}
|
||||
|
||||
private int testsRunning = 0;
|
||||
public int TestsRunning
|
||||
{
|
||||
get { return testsRunning; }
|
||||
set { Set(ref testsRunning, value); }
|
||||
}
|
||||
|
||||
private int testsPassed = 0;
|
||||
public int TestsPassed
|
||||
{
|
||||
@@ -559,12 +572,12 @@ namespace Xunit.Runner.Wpf.ViewModel
|
||||
|
||||
private async void OnExecuteRunAll()
|
||||
{
|
||||
Debug.Assert(this.runningTests == null);
|
||||
Debug.Assert(this.testsToRun == null);
|
||||
UpdateTestCaseInfo(useSelected: false);
|
||||
|
||||
await ExecuteTestSessionOperation(RunFilteredTests);
|
||||
|
||||
this.runningTests = null;
|
||||
this.testsToRun = null;
|
||||
}
|
||||
|
||||
private List<Task> RunFilteredTests()
|
||||
@@ -574,13 +587,13 @@ namespace Xunit.Runner.Wpf.ViewModel
|
||||
|
||||
private async void OnExecuteRunSelected()
|
||||
{
|
||||
Debug.Assert(this.runningTests == null);
|
||||
Debug.Assert(this.testsToRun == null);
|
||||
Debug.Assert(this.SelectedTestCase != null);
|
||||
UpdateTestCaseInfo(useSelected: true);
|
||||
|
||||
await ExecuteTestSessionOperation(RunSelectedTests);
|
||||
|
||||
this.runningTests = null;
|
||||
this.testsToRun = null;
|
||||
}
|
||||
|
||||
private List<Task> RunSelectedTests()
|
||||
@@ -592,37 +605,38 @@ namespace Xunit.Runner.Wpf.ViewModel
|
||||
{
|
||||
Debug.Assert(this.isBusy);
|
||||
Debug.Assert(this.cancellationTokenSource != null);
|
||||
Debug.Assert(this.runningTests == null);
|
||||
Debug.Assert(this.testsToRun == null);
|
||||
|
||||
TestsCompleted = 0;
|
||||
TestsRunning = 0;
|
||||
TestsPassed = 0;
|
||||
TestsFailed = 0;
|
||||
TestsSkipped = 0;
|
||||
CurrentRunState = TestState.NotRun;
|
||||
Output = string.Empty;
|
||||
|
||||
this.runningTests = tests;
|
||||
this.testsToRun = tests;
|
||||
|
||||
foreach (var tc in this.runningTests)
|
||||
foreach (var tc in this.testsToRun)
|
||||
{
|
||||
tc.State = TestState.NotRun;
|
||||
}
|
||||
|
||||
var runAll = this.runningTests.Count == this.allTestCases.Count;
|
||||
var runAll = this.testsToRun.Count == this.allTestCases.Count;
|
||||
var testSessionList = new List<Task>();
|
||||
|
||||
foreach (var assemblyFileName in this.runningTests.Select(x => x.AssemblyFileName).Distinct())
|
||||
foreach (var assemblyFileName in this.testsToRun.Select(x => x.AssemblyFileName).Distinct())
|
||||
{
|
||||
Task task;
|
||||
if (runAll)
|
||||
{
|
||||
task = this.testUtil.RunAll(assemblyFileName, OnTestsFinished, this.cancellationTokenSource.Token);
|
||||
task = this.testUtil.RunAll(assemblyFileName, OnTestStateChange, this.cancellationTokenSource.Token);
|
||||
}
|
||||
else
|
||||
{
|
||||
var builder = ImmutableArray.CreateBuilder<string>();
|
||||
|
||||
foreach (var testCase in this.runningTests)
|
||||
foreach (var testCase in this.testsToRun)
|
||||
{
|
||||
if (testCase.AssemblyFileName == assemblyFileName)
|
||||
{
|
||||
@@ -630,7 +644,7 @@ namespace Xunit.Runner.Wpf.ViewModel
|
||||
}
|
||||
}
|
||||
|
||||
task = this.testUtil.RunSpecific(assemblyFileName, builder.ToImmutable(), OnTestsFinished, this.cancellationTokenSource.Token);
|
||||
task = this.testUtil.RunSpecific(assemblyFileName, builder.ToImmutable(), OnTestStateChange, this.cancellationTokenSource.Token);
|
||||
}
|
||||
|
||||
testSessionList.Add(task);
|
||||
@@ -710,28 +724,43 @@ namespace Xunit.Runner.Wpf.ViewModel
|
||||
}
|
||||
}
|
||||
|
||||
private void OnTestsFinished(IEnumerable<TestResultData> testResultData)
|
||||
private void OnTestStateChange(IEnumerable<TestResultData> testResultData)
|
||||
{
|
||||
Debug.Assert(this.runningTests != null);
|
||||
Debug.Assert(this.testsToRun != null);
|
||||
|
||||
foreach (var result in testResultData)
|
||||
{
|
||||
var testCase = this.runningTests.Single(x => x.UniqueID == result.TestCaseUniqueID);
|
||||
var testCase = this.testsToRun.Single(x => x.UniqueID == result.TestCaseUniqueID);
|
||||
testCase.State = result.TestState;
|
||||
|
||||
TestsCompleted++;
|
||||
switch (result.TestState)
|
||||
if (result.TestState == TestState.Running)
|
||||
{
|
||||
case TestState.Passed:
|
||||
TestsPassed++;
|
||||
break;
|
||||
case TestState.Failed:
|
||||
TestsFailed++;
|
||||
Output = Output + result.Output;
|
||||
break;
|
||||
case TestState.Skipped:
|
||||
TestsSkipped++;
|
||||
break;
|
||||
if (runningTestSet.Add(result.TestCaseUniqueID))
|
||||
{
|
||||
TestsRunning++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (runningTestSet.Remove(result.TestCaseUniqueID))
|
||||
{
|
||||
TestsRunning--;
|
||||
}
|
||||
|
||||
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)
|
||||
@@ -819,6 +848,18 @@ namespace Xunit.Runner.Wpf.ViewModel
|
||||
}
|
||||
}
|
||||
|
||||
public bool FilterRunningTests
|
||||
{
|
||||
get { return searchQuery.FilterRunningTests; }
|
||||
set
|
||||
{
|
||||
if (Set(ref searchQuery.FilterRunningTests, value))
|
||||
{
|
||||
FilterAfterDelay();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool FilterPassedTests
|
||||
{
|
||||
get { return searchQuery.FilterPassedTests; }
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace Xunit.Runner.Wpf.ViewModel
|
||||
{
|
||||
public class SearchQuery
|
||||
{
|
||||
public bool FilterRunningTests = false;
|
||||
public bool FilterFailedTests = false;
|
||||
public bool FilterPassedTests = false;
|
||||
public bool FilterSkippedTests = false;
|
||||
|
||||
@@ -161,6 +161,7 @@
|
||||
<ItemGroup>
|
||||
<NuGetManifest Include="xunit.runner.wpf.nuspec">
|
||||
<Version>$(NuPkgVersion)</Version>
|
||||
<PackageAnalysis>False</PackageAnalysis>
|
||||
</NuGetManifest>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
@@ -202,6 +203,12 @@
|
||||
<ItemGroup>
|
||||
<Resource Include="Artwork\Application.ico" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Resource Include="Artwork\Running_large.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Resource Include="Artwork\Running_small.png" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
|
||||
@@ -12,9 +12,9 @@
|
||||
<tags>XUnit Gui test runner</tags>
|
||||
</metadata>
|
||||
<files>
|
||||
<file src="*.dll" target="tools\"/>
|
||||
<file src="xunit.runner.wpf.targets" target="build"/>
|
||||
<file src="*.exe" target="tools\" exclude="*vshost*"/>
|
||||
<file src="*.config" target="tools\" exclude="*vshost*"/>
|
||||
<file src="bin\$Configuration$\*.dll" target="tools\"/>
|
||||
<file src="xunit.runner.wpf.targets" target="build\net45"/>
|
||||
<file src="bin\$Configuration$\*.exe" target="tools\" exclude="**\*vshost*"/>
|
||||
<file src="bin\$Configuration$\*.config" target="tools\" exclude="**\*vshost*"/>
|
||||
</files>
|
||||
</package>
|
||||
|
||||
Reference in New Issue
Block a user