using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
public static async Task Main()
var testAssemblies = new Assembly[]
var testRunner = new XunitTestRunner();
await testRunner.RunAsync(testAssemblies);
public sealed class XunitTestRunner
public async Task RunAsync(IEnumerable<Assembly> assemblies)
Console.WriteLine("Test runner starting...");
var testEntries = assemblies
.SelectMany(asm => asm.GetTypes()
var factAttr = method.GetCustomAttribute(typeof(FactAttribute));
.Where(method => method != null)
Console.WriteLine($"Test runner found {testEntries.Length} tests.");
foreach (var testEntry in testEntries)
var testName = $"{testEntry.Type.Name}.{testEntry.TestMethod.Name}";
Console.WriteLine($"Running '{testName}'...");
var instance = Activator.CreateInstance(testEntry.Type);
.GetCustomAttributes(typeof(AsyncStateMachineAttribute), false)
var asyncTestMethod = (Func<Task>)testEntry.TestMethod.CreateDelegate(typeof(Func<Task>), instance);
testEntry.TestMethod.Invoke(instance, null);
$"Exception caught running '{testName}':\r\n" +
$"{ex.GetType()}: {ex.Message}\r\n" +
$"Stack Trace:{ex.StackTrace}");
Console.WriteLine("Test runner complete.");
public sealed class Tests
Console.WriteLine("Test...");
private async Task yy_yy_yy()
await Task.Run(() => Console.WriteLine("async test..."));