Simple Tool to Run Visual Studio Unit Tests without MsTest
Here is a simple tool to run Visual Studio Unit Tests outside of mstest.
First the program outputs some basic banner information
static void Main(string[] args)
{
Console.WriteLine("N8test - {0}",
Assembly.GetExecutingAssembly().GetName().Version);
Console.WriteLine("Implementation by Nate Bachmeier");
Console.WriteLine("//wasntnate.com");
Console.WriteLine("Running tests..");
Next it will load any assemblies that have been specified as arguments.
Note that this requires the full path; with using some additional calls to File, Directory, and Path this could easily work with relative paths.
var asmList = new List<Assembly>();
foreach (var arg in args)
{
try
{
var file = new FileInfo(arg);
if (file.Exists)
asmList.Add(Assembly.LoadFile(file.FullName));
}
catch
{
UseColor(ConsoleColor.Red, () =>
Console.WriteLine("Unable to open {0}", arg));
continue;
}
}
Find any public class that is tagged with [TestClass]
foreach (var testClass in from asm in asmList from t in asm.GetExportedTypes() let atts = t.GetCustomAttributes(true) where (from a in atts where string.Equals(a.GetType().Name, "TestClassAttribute") select a).FirstOrDefault() != null select t) {
Initialize our test class
Console.WriteLine("================");
Console.WriteLine(testClass.Name);
Console.WriteLine("================");
object instance;
try
{
instance = Activator.CreateInstance(testClass);
}
catch (TargetInvocationException tie)
{
Console.WriteLine("Failed to initalize {0} due to {1}",
testClass.Name, tie.InnerException.Message);
continue;
}
Find each public method that is tagged with [TestMethod]
foreach (var method in
from m in testClass.GetMethods()
let atts = m.GetCustomAttributes(true)
where (from a in atts
where string.Equals(a.GetType().Name, "TestMethodAttribute")
select a).FirstOrDefault() != null
select m)
{
Attempt to execute it and report the runtime on success
try
{
var stopwatch = new Stopwatch();
stopwatch.Start();
method.Invoke(instance, new object[] { });
stopwatch.Stop();
UseColor(ConsoleColor.Green, () =>
Console.WriteLine("[S] {0} in {1} milli seconds",
method.Name, stopwatch.ElapsedMilliseconds));
}
catch (TargetInvocationException tie)
{
UseColor(ConsoleColor.Red, () =>
Console.WriteLine("[F] {1} due to {1}",
method.Name, tie.InnerException));
}
}
}
Ask the user to press a key before leaving; useful for ‘F5-run’ scenarios
Console.WriteLine("Press any key to exit");
Console.ReadKey();
}
Finally a helper method to give us coloring while displaying messages
static void UseColor(ConsoleColor color, Action code)
{
var orgColor = Console.ForegroundColor;
Console.ForegroundColor = color;
try
{
code();
}
finally
{
Console.ForegroundColor = orgColor;
}
}
Which Products Does Microsoft Make? TSql – Auditing Row Deletions with Triggers