MSTest测试上下文exception处理

有没有办法可以使用TestContext或基础测试类上的其他方法来处理由MSTest框架处理的exception?

如果在我的一个测试中发生未处理的exception,我想旋转exception.Data字典中的所有项目并将它们显示给测试结果,以帮助我找出测试失败的原因(我们通常会将数据添加到帮助我们在生产环境中调试的exception,所以我想做同样的测试)。

注意:我没有测试exception是支持HAPPEN(我有其他测试),我正在测试一个有效的情况,我只需要查看exception数据。

这是我正在谈论的代码示例。

[TestMethod] public void IsFinanceDeadlineDateValid() { var target = new BusinessObject(); SetupBusinessObject(target); //How can I capture this in the text context so I can display all the data //in the exception in the test result... var expected = 100; try { Assert.AreEqual(expected, target.PerformSomeCalculationThatMayDivideByZero()); } catch (Exception ex) { ex.Data.Add("SomethingImportant", "I want to see this in the test result, as its important"); ex.Data.Add("Expected", expected); throw ex; } } 

我知道为什么我可能不应该有这样的封装方法存在问题,但我们也有子测试来测试PerformSomeCalculation的所有function……

但是,如果测试失败,99%的时间,我重新运行它通过,所以没有这些信息我无法调试任何东西。 我还想在GLOBAL级别上执行此操作,因此如果任何测试失败,我会在测试结果中获取信息,而不是为每个单独的测试执行此操作。

这是将exception信息放在测试结果中的代码。

  public void AddDataFromExceptionToResults(Exception ex) { StringBuilder whereAmI = new StringBuilder(); var holdException = ex; while (holdException != null) { Console.WriteLine(whereAmI.ToString() + "--" + holdException.Message); foreach (var item in holdException.Data.Keys) { Console.WriteLine(whereAmI.ToString() + "--Data--" + item + ":" + holdException.Data[item]); } holdException = holdException.InnerException; } } 

我一直在遇到同样的问题,似乎没有对此表示支持。 您甚至无法使用ApplicationDomain的未处理exception挂钩,因为如果MSTEST在它们冒泡到那么远之前没有捕获exception,它本身就会崩溃。

可能的解决方法:

  private delegate void TestImplDelegate(); private void RunTestWithExceptionLogging(TestImplDelegate testImpl) { try { testImpl(); } catch (Exception e) { string message = e.Message; // don't warn about unused variables // do logging here } } [TestMethod] public void test1() { RunTestWithExceptionLogging(test1Impl); } private void test1Impl() { // test code goes here throw new Exception("This should get logged by the test wrapper."); } [TestMethod] public void test2() { RunTestWithExceptionLogging(test2Impl); } private void test2Impl() { // test code goes here throw new Exception("This should get logged by the test wrapper."); } 

它当然不是最优的,但至少这种方式你没有exception处理程序代码的多个副本。

我建议在http://connect.microsoft.com/上提交function请求(或者查看其他人是否已经请求过,并添加您的投票。)

这是一个“干净”的工作,将exception放入TestBase.TestContext属性(或在TestBase实例中的任何位置)。

该示例使用postharp (这是一个AOP库)在编译时为您的代码注入try-catch。 它将注入具有[TestMethod]属性的所有方法。 – postsharp免费版将完成工作,无需通过许可证。

您要做的第一件事是创建AOP属性。 这些属性定义了在exception和+ define注入条件下将要完成的操作,这是你如何做到的:

 ///  /// Catch exceptions of tests and save them in  under TestContext.Properties. This is done since MSTEST does not supply any mechanism to catch tests exceptions. ///  [SerializableAttribute] public class CodedTestsExceptionsHandlingAop : OnExceptionAspect { ///  /// The name of the property that will be added to the test context properties object. ///  public const string FailureExceptionProerty = "FailureException"; ///  /// Save the exception in a  and rethrow. ///  ///  public override void OnException(MethodExecutionArgs args) { var testBase = (Framework.TestBase) args.Instance;//The instance running the test inherits from TestBase. testBase.TestContext.Properties.Add("FailureException", args.Exception); args.FlowBehavior = FlowBehavior.RethrowException; } ///  /// Make sure only test methods will get this AOP. ///  ///  ///  public override bool CompileTimeValidate(MethodBase method) { if (method.IsDefined(typeof(TestMethodAttribute))) return true; return false; } } 

第二件事,你必须将以下程序集级属性添加到你的测试项目中(如果它与testBase不在同一个项目中,还需要安装postharp),这将在测试程序集中应用AOP注入:

 [assembly: CodedTestsExceptionsHandlingAop(AttributeTargetTypes = "*", AttributeTargetElements = MulticastTargets.Method)] 

如果您只是想测试预期的exception,可以使用ExpectedExceptionAttribute

我认为能够获得unit testing的exception会在出现意外exception时更有用,并且您希望记录或收集有关exception的额外信息,而不是依靠TestExplorer来查找检查失败的测试。