这是一个可以出于任何原因独立于MS Ordered Tests框架设置和运行有序测试的类,例如不必在生成机上调整mstest.exe参数,或在类中混合有序与无序。
原始测试框架仅将已排序测试的列表视为单个测试,因此,任何初始化/清除(如[TestInitalize()] Init())都只能在整个集合之前和之后调用。
用法:
[TestMethod]
public void OrderedStepsTest()
{
OrderedTest.Run(TestContext, new List<OrderedTest>
{
new OrderedTest ( T10_Reset_Database, false ),
new OrderedTest ( T20_LoginUser1, false ),
new OrderedTest ( T30_DoLoginUser1Task1, true ),
new OrderedTest ( T40_DoLoginUser1Task2, true ),
});
}
实现方式:
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
namespace UnitTests.Utility
{
public class OrderedTest
{
public Action TestMethod { get; private set; }
public bool ContinueOnFailure { get; private set; }
public Exception ExceptionResult;
public OrderedTest(Action testMethod, bool continueOnFailure = false)
{
TestMethod = testMethod;
ContinueOnFailure = continueOnFailure;
}
public void Run()
{
try
{
TestMethod();
}
catch (Exception ex)
{
ExceptionResult = ex;
throw;
}
}
static public void Run(TestContext testContext, List<OrderedTest> tests)
{
Stopwatch overallStopWatch = new Stopwatch();
overallStopWatch.Start();
List<Exception> exceptions = new List<Exception>();
int testsAttempted = 0;
for (int i = 0; i < tests.Count; i++)
{
OrderedTest test = tests[i];
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
testContext.WriteLine("Starting ordered test step ({0} of {1}) '{2}' at {3}...\n",
i + 1,
tests.Count,
test.TestMethod.Method,
DateTime.Now.ToString("G"));
try
{
testsAttempted++;
test.Run();
}
catch
{
if (!test.ContinueOnFailure)
break;
}
finally
{
Exception testEx = test.ExceptionResult;
if (testEx != null)
exceptions.Add(testEx);
testContext.WriteLine("\n{0} ordered test step {1} of {2} '{3}' in {4} at {5}{6}\n",
testEx != null ? "Error: Failed" : "Successfully completed",
i + 1,
tests.Count,
test.TestMethod.Method,
stopWatch.ElapsedMilliseconds > 1000
? (stopWatch.ElapsedMilliseconds * .001) + "s"
: stopWatch.ElapsedMilliseconds + "ms",
DateTime.Now.ToString("G"),
testEx != null
? "\nException: " + testEx.Message +
"\nStackTrace: " + testEx.StackTrace +
"\nContinueOnFailure: " + test.ContinueOnFailure
: "");
}
}
testContext.WriteLine("Completed running {0} of {1} ordered tests with a total of {2} error(s) at {3} in {4}",
testsAttempted,
tests.Count,
exceptions.Count,
DateTime.Now.ToString("G"),
overallStopWatch.ElapsedMilliseconds > 1000
? (overallStopWatch.ElapsedMilliseconds * .001) + "s"
: overallStopWatch.ElapsedMilliseconds + "ms");
if (exceptions.Any())
{
throw new Exception(String.Join("; ", exceptions.Select(e => e.Message), new AggregateException(exceptions)));
}
}
}
}