Last active
September 3, 2015 19:13
-
-
Save pocheptsov/e53f689f450b59c8c112 to your computer and use it in GitHub Desktop.
xUnit Console Runner
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
using System; | |
using System.Linq; | |
using System.Reflection; | |
using System.Text.RegularExpressions; | |
using System.Threading.Tasks; | |
using Xunit; | |
namespace TestsRunner | |
{ | |
public class Program | |
{ | |
public void Main() | |
{ | |
var filter = "*.*"; | |
//filter one method | |
//filter = nameof(GoogleServiceTests) + "." + nameof(GoogleServiceTests.GetGoalsTest); | |
//filter test case method | |
//filter = nameof(GoogleServiceTests) + ".*"; | |
int testNum = 0, successTestNum = 0; | |
var filterParts = filter.Split('.'); | |
var typeFilter = new Regex(filterParts[0].Replace("*", ".*")); | |
var methodFilter = new Regex(filterParts[1].Replace("*", ".*")); | |
var exportedTypes = | |
Assembly.GetExecutingAssembly() | |
.GetExportedTypes() | |
.Where(_ => typeFilter.IsMatch(_.Name) && !_.IsAbstract && !_.IsInterface) | |
.ToList(); | |
foreach (var type in exportedTypes) | |
{ | |
var testMethods = type.GetMethods(BindingFlags.Instance | BindingFlags.Public) | |
.Where(_ => | |
{ | |
var factAttribute = _.GetCustomAttribute<FactAttribute>(); | |
return methodFilter.IsMatch(_.Name) && factAttribute != null && | |
string.IsNullOrEmpty(factAttribute.Skip); | |
}).ToList(); | |
if (!testMethods.Any()) | |
continue; | |
RunSafely(() => | |
{ | |
Console.WriteLine($@"{type.Name}:"); | |
var instance = Activator.CreateInstance(type); | |
foreach (var testMethod in testMethods) | |
{ | |
Console.WriteLine($" {testMethod.Name}"); | |
var isSuccess = RunSafely(() => | |
{ | |
var result = testMethod.Invoke(instance, null); | |
// for task wait completion | |
var task = result as Task; | |
if (task != null) | |
{ | |
Task.WaitAll(task); | |
} | |
}); | |
if (isSuccess) | |
{ | |
successTestNum++; | |
} | |
Console.WriteLine(); | |
} | |
var disposable = instance as IDisposable; | |
disposable?.Dispose(); | |
}); | |
testNum += testMethods.Count; | |
Console.WriteLine(Environment.NewLine); | |
} | |
Console.WriteLine(new string('-', 70)); | |
Console.Write(@"Tests Failed: "); | |
var failedTestNum = testNum - successTestNum; | |
if (failedTestNum > 0) | |
{ | |
Console.ForegroundColor = ConsoleColor.Red; | |
} | |
Console.Write(failedTestNum); | |
Console.ResetColor(); | |
Console.Write($@". Succeeded tests: {successTestNum}. Num of tests: {testNum}."); | |
Console.ReadLine(); | |
} | |
public bool RunSafely(Action action) | |
{ | |
try | |
{ | |
action(); | |
} | |
catch (AggregateException aex) | |
{ | |
LogException(aex.InnerException); | |
return false; | |
} | |
catch (Exception ex) | |
{ | |
LogException(ex); | |
return false; | |
} | |
return true; | |
} | |
private static void LogException(Exception ex) | |
{ | |
Console.ForegroundColor = ConsoleColor.Red; | |
Action<Exception> logException = e => Console.WriteLine(e.Message + Environment.NewLine + e.StackTrace); | |
logException(ex); | |
var innerEx = ex.GetBaseException(); | |
if (innerEx != ex) | |
{ | |
logException(innerEx); | |
} | |
Console.ResetColor(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment