Last active
July 23, 2019 02:49
-
-
Save michael-wolfenden/3cfff65de7f4fced965c99d32e3e2e0b to your computer and use it in GitHub Desktop.
[Linqpad XUnit Runner] Run xunit within linqpad #xunit
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
<Query Kind="Program"> | |
<NuGetReference>xunit</NuGetReference> | |
<NuGetReference>xunit.runner.utility</NuGetReference> | |
<Namespace>Xunit</Namespace> | |
<Namespace>Xunit.Runners</Namespace> | |
<CopyLocal>true</CopyLocal> | |
</Query> | |
*/ | |
void Main() | |
{ | |
XUnitRunner.Run(Assembly.GetExecutingAssembly()); | |
} | |
[Theory] | |
[InlineData(3)] | |
[InlineData(5)] | |
[InlineData(6)] | |
public void MyFirstTheory(int value) | |
{ | |
Assert.True(IsOdd(value)); | |
} | |
bool IsOdd(int value) | |
{ | |
return value % 2 == 1; | |
} | |
// see: https://github.com/xunit/samples.xunit/blob/1173213302fd3a45bd6e4303371d2f78f1743552/TestRunner/Program.cs | |
public class XUnitRunner | |
{ | |
private Assembly _testAssembly; | |
private object _consoleLock = new object(); | |
private ManualResetEvent finished = new ManualResetEvent(false); | |
private int _result = 0; | |
private XUnitRunner(Assembly testAssembly) => | |
_testAssembly = testAssembly ?? throw new ArgumentNullException(nameof(testAssembly)); | |
public static int Run(Assembly testAssembly) => | |
new XUnitRunner(testAssembly).Run(); | |
private int Run() | |
{ | |
var newTestAssemblyLocation = CopyTestAssemblyToTheSameFolderAsTheXUnitAssemblies(); | |
using (var runner = AssemblyRunner.WithoutAppDomain(newTestAssemblyLocation)) | |
{ | |
runner.OnDiscoveryComplete = OnDiscoveryComplete; | |
runner.OnExecutionComplete = OnExecutionComplete; | |
runner.OnTestFailed = OnTestFailed; | |
runner.OnTestSkipped = OnTestSkipped; | |
Console.WriteLine("Discovering..."); | |
runner.Start(); | |
finished.WaitOne(); | |
finished.Dispose(); | |
return _result; | |
} | |
} | |
private string CopyTestAssemblyToTheSameFolderAsTheXUnitAssemblies() | |
{ | |
var testAssemblyFolder = new DirectoryInfo(Path.GetDirectoryName(_testAssembly.Location)); | |
var xunitFolder = new DirectoryInfo(Path.GetDirectoryName(typeof(Xunit.Assert).Assembly.Location)); | |
var isXunitInASubDirectory = xunitFolder.Parent.FullName == testAssemblyFolder.FullName; | |
if (!isXunitInASubDirectory) | |
throw new InvalidOperationException("Please enable 'Copy all non-framework references to a single local folder' (F4 -> Advanced)."); | |
var newTestAssemblyPath = Path.Combine(xunitFolder.FullName, Path.GetFileName(_testAssembly.Location)); | |
File.Copy(_testAssembly.Location, newTestAssemblyPath, overwrite: true); | |
return newTestAssemblyPath; | |
} | |
private void OnDiscoveryComplete(DiscoveryCompleteInfo info) | |
{ | |
lock (_consoleLock) | |
Console.WriteLine($"Running {info.TestCasesToRun} of {info.TestCasesDiscovered} tests..."); | |
} | |
private void OnExecutionComplete(ExecutionCompleteInfo info) | |
{ | |
lock (_consoleLock) | |
Console.WriteLine($"Finished: {info.TotalTests} tests in {Math.Round(info.ExecutionTime, 3)}s ({info.TestsFailed} failed, {info.TestsSkipped} skipped)"); | |
finished.Set(); | |
} | |
private void OnTestFailed(TestFailedInfo info) | |
{ | |
lock (_consoleLock) | |
{ | |
Console.WriteLine("[FAIL] {0}: {1}", info.TestDisplayName, info.ExceptionMessage); | |
if (info.ExceptionStackTrace != null) | |
Console.WriteLine(info.ExceptionStackTrace); | |
} | |
_result = 1; | |
} | |
private void OnTestSkipped(TestSkippedInfo info) | |
{ | |
lock (_consoleLock) | |
{ | |
Console.WriteLine("[SKIP] {0}: {1}", info.TestDisplayName, info.SkipReason); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment