15 Commits

Author SHA1 Message Date
Kevin Pilch 39f89587fc Merge pull request #81 from heejaechang/fixDiscovery
made discovery to use same setting as run so that same tests are disc…
2017-11-01 09:24:29 -07:00
Heejae Chang 8c3c86d918 made wpf xunit runner to support showing/filtering running tests so that if we get deadlock or hang tests, we can see what the test it was running easily. 2017-10-31 17:23:22 -07:00
Heejae Chang 761f801e43 made discovery to use same setting as run so that same tests are discovered. 2017-10-31 14:56:33 -07:00
Kevin Pilch 643d9061c8 Merge pull request #79 from 333fred/fix-autoreload
Fix first open and default autoreload case
2017-06-05 16:17:11 -07:00
Fredric Silberberg 6d4a249a97 Fix first open and default autoreload case 2017-06-05 15:49:35 -07:00
Kevin Pilch 5ed3579b30 Merge pull request #78 from 333fred/screenshot
Added screenshot to readme.
2017-06-05 11:22:21 -07:00
Fredric Silberberg 1f55afd2e9 Added screenshot to readme. 2017-06-05 10:49:13 -07:00
Kevin Pilch c6c48067a7 Merge pull request #77 from 333fred/update-readme
Add nuget to readme
2017-06-05 10:32:28 -07:00
Fredric Silberberg ab5b3afea2 Add nuget to readme 2017-06-05 10:30:00 -07:00
Kevin Pilch feb8588961 Merge pull request #76 from sharwell/open-2017
Open solution in Visual Studio 2017
2017-06-03 14:42:28 -07:00
Kevin Pilch 08907d707c Merge pull request #75 from sharwell/include-binaries
Include binaries in the NuGet package
2017-06-03 14:42:07 -07:00
Sam Harwell de354d8095 Open solution in Visual Studio 2017
Since the project is using features from C# 7, update the solution to open
by default in a version of Visual Studio that supports them.
2017-06-03 16:40:14 -05:00
Sam Harwell dd668f753b Move .targets into a framework-specific folder
Fixes installation via project.json.
2017-06-03 16:38:56 -05:00
Sam Harwell a5712e104a Disable NuGet package analysis since this is a non-standard package layout 2017-06-03 16:30:06 -05:00
Sam Harwell f2e1c0fb5e Include binaries in NuGet package 2017-06-03 16:27:16 -05:00
16 changed files with 128 additions and 37 deletions
+4
View File
@@ -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).
![Screenshot](docs/screenshot.png)
[![Build status](https://ci.appveyor.com/api/projects/status/13dshnyj592mwe9e/branch/master?svg=true)](https://ci.appveyor.com/project/Pilchie/xunit-runner-wpf/branch/master)
Binary file not shown.

After

Width:  |  Height:  |  Size: 127 KiB

+1
View File
@@ -10,6 +10,7 @@ namespace Xunit.Runner.Data
{
All = 0,
NotRun,
Running,
Passed,
Skipped,
Failed,
+1 -1
View File
@@ -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);
+6 -1
View File
@@ -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;
+2 -2
View File
@@ -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:
+15
View File
@@ -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}"
+4
View File
@@ -125,6 +125,10 @@ namespace Xunit.Runner.Wpf.Persistence
settings.autoReloadAssemblies = autoReloadAssemblies;
}
else
{
settings.autoReloadAssemblies = true;
}
return settings;
}
+70 -29
View File
@@ -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;
+7
View File
@@ -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>
+4 -4
View File
@@ -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>