2010-01-14 5 views
6

기본 테스트 클래스에서 TestContext 또는 다른 메서드를 사용하여 MSTest 프레임 워크에서 처리 한 예외를 얻을 수있는 방법이 있습니까?MSTest 테스트 컨텍스트 예외 처리

테스트 중 하나에서 처리되지 않은 예외가 발생하면 exception.Data 사전의 모든 항목을 검색하여 테스트 결과에 표시하여 테스트가 실패한 이유를 알아낼 수있게 도와줍니다. 프로덕션 환경에서 디버깅 할 수 있도록 데이터를 예외에 추가하십시오. 따라서 테스트를 위해 동일한 작업을 수행하고 싶습니다.)

참고 : 예외가 있음 (다른 테스트가 있음)을 테스트하지 않고 유효한 사례를 테스트하고 있으며 예외 데이터를 확인해야합니다.

다음은 내가 말하는 것에 대한 코드 예입니다.

[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의 모든 기능을 테스트하는 하위 검사를 실패, 99 %의 시간, 나는 그것을 다시 통과하므로이 정보 없이는 아무것도 디버깅 할 수 없습니다. 나는 또한 GLOBAL 수준에서 이것을하고 싶습니다. 그래서 어떤 테스트가 실패하면, 각각의 개별 테스트를 위해 그것을하는 것과 반대로 테스트 결과에 정보를 얻습니다.

다음은 테스트 결과에 예외 정보를 넣을 코드입니다.

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; 
     } 
    } 
+0

도 참조하십시오. http://stackoverflow.com/questions/37660311/method-for-handling-exceptions-in-mstest/39208343#39208343 – Almund

답변

3

저는 같은 문제에 직면 해 있으며,이를 지원하지 않습니다. ApplicationDomain의 처리되지 않은 예외 훅도 사용할 수 없습니다. MSTEST가 예외를 잡기 전에 예외를 잡아 내지 못하면 그 자체가 충돌하기 때문입니다.

가능한 해결 방법 :

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."); 
    } 

확실히 최적은 아니지만, 적어도 이런 식으로 당신은 예외 핸들러 코드의 여러 사본이 없습니다.

내가 http://connect.microsoft.com/에서 이것에 대한 기능 요청을 제출하는 것이 좋습니다 (또는 다른 사람이 이미 요청한 있는지 확인하고 투표를 추가합니다.) 것

다음
1

가에 예외를 넣어 것이다 주위에 "깨끗한"작품입니다 TestBase.TestContext 속성 (또는 TestBase 인스턴스에서 원하는 모든 위치).

이 예제에서는 컴파일 타임에 코드에 try-catch를 삽입하기 위해 postsharp (AOP lib)을 사용합니다. 그것은 [TestMethod] 속성을 가진 모든 메소드에 주입 할 것입니다. - 포스트 샤프 무료 버전은 라이센스를 필요로하지 않고 작업을 수행합니다.

먼저해야 할 일은 AOP 속성을 만드는 것입니다.속성은 예외의 경우에서 수행하고 + 주입을위한 조건을 정의합니다을 정의, 이것은 당신이 그것을 할 방법 :

/// <summary> 
/// Catch exceptions of tests and save them in <see cref="TestBase"/> under TestContext.Properties. This is done since MSTEST does not supply any mechanism to catch tests exceptions. 
/// </summary> 
[SerializableAttribute] 
public class CodedTestsExceptionsHandlingAop : OnExceptionAspect 
{ 
    /// <summary> 
    /// The name of the property that will be added to the test context properties object. 
    /// </summary> 
    public const string FailureExceptionProerty = "FailureException"; 

    /// <summary> 
    /// Save the exception in a <see cref="TestBase"/> and rethrow. 
    /// </summary> 
    /// <param name="args"></param> 
    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; 
    } 

    /// <summary> 
    /// Make sure only test methods will get this AOP. 
    /// </summary> 
    /// <param name="method"></param> 
    /// <returns></returns> 
    public override bool CompileTimeValidate(MethodBase method) 
    { 
     if (method.IsDefined(typeof(TestMethodAttribute))) 
      return true; 

     return false; 
    } 
} 

2 일, 당신은 테스트 프로젝트에 다음 어셈블리 수준의 속성을 추가해야합니다 당신은 단지 예상 예외를 테스트하고자하는 경우

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

:이 테스트 어셈블리를 통해 AOP 주입을 적용합니다 (또한 당신의 TestBase와 같은 프로젝트에없는 경우 postsharp를 설치해야 함) 사용할 수 있음 ExpectedExceptionAttribute

유닛 테스트에 대한 예외를 얻을 수있는 것이 예기치 않은 예외이며 더 이상 테스트를 찾지 못한 TestExplorer에 의존하기보다는 예외에 대한 추가 정보를 기록하거나 수집하려는 경우에 더 유용 할 것이라고 생각합니다.