2012-08-01 130 views
10

我存儲關於給定的測試中的一個屬性的各種信息(用於多個錯誤跟蹤系統ID)的,像這樣:如何在運行時從NUnit測試運行中獲取單元測試方法屬性?

[TestCaseVersion("001","B-8345","X543")] 
public void TestSomethingOrOther() 

爲了取一個測試的過程中該信息,我寫的以下代碼:

 public string GetTestID() 
    { 
     StackTrace st = new StackTrace(1); 
     StackFrame sf; 
     for (int i = 1; i <= st.FrameCount; i++) 
     { 
      sf = st.GetFrame(i); 
      if (null == sf) continue; 
      MethodBase method = sf.GetMethod(); 
      if (method.GetCustomAttributes(typeof(TestAttribute), true).Length == 1) 
      { 
       if (method.GetCustomAttributes(typeof(TestCaseVersion), true).Length == 1) 
       { 
        TestCaseVersion tcv = 
         sf.GetMethod().GetCustomAttributes(typeof(TestCaseVersion), true).OfType<TestCaseVersion>() 
          .First(); 
        return tcv.TestID; 
       } 
      } 
     } 

的問題是,通過NUnit的在Release模式運行測試時,其應具有測試名稱和這些屬性,所述方法由下列替代:

System.RuntimeMethodHandle._InvokeMethodFast(IRuntimeMethodInfo method, Object target, Object[] arguments, SignatureStruct& sig, MethodAttributes methodAttributes, RuntimeType typeOwner) 
    at System.RuntimeMethodHandle.InvokeMethodFast(IRuntimeMethodInfo method, Object target, Object[] arguments, Signature sig, MethodAttributes methodAttributes, RuntimeType typeOwner) 
    at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks) 
    at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) 
    at NUnit.Core.Reflect.InvokeMethod(MethodInfo method, Object fixture, Object[] args) 

UPDATE 對於任何人誰是有興趣,我結束了實現以下面的方式代碼(以便任何屬性值可以訪問,而無需改變任何使用TestCaseVersion屬性的現有代碼:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.Method, AllowMultiple = false)] 
public class TestCaseVersion : PropertyAttribute 
{ 
    public TestCaseVersion(string testCaseCode, string story, string task, string description) 
    { 
     base.Properties.Add("TestId", testCaseCode); 
     base.Properties.Add("Description", description); 
     base.Properties.Add("StoryId", story); 
     base.Properties.Add("TaskId", task); 
    } 
} 

public string GetTestID() 
{ 
    return TestContext.CurrentContext.Test.Properties["TestId"]; 
} 
+0

不錯的更新!如果可以,我會給你第二個upvote :-) – 2012-08-02 20:54:42

回答

8

如果你是一個具有一個單值的測試用例版本字符串(IE的"001, B-8345, X543"代替"001","B-8345","X543"),你應該能夠利用現有的TestContext功能在NUnit的2.5.7和更高OK 。

具體來說,你可以定義和使用測試方面Property屬性TestCaseVersion這樣的:

[Test, Property("TestCaseVersion", "001, B-8345, X543")] 
public void TestContextPropertyTest() 
{ 
    Console.WriteLine(TestContext.CurrentContext.Test.Properties["TestCaseVersion"]); 
} 

UPDATE順便說一句,如果你要使用的測試的多值表示您可以定義多個屬性,如下所示:

[Test, Property("MajorVersion", "001"), 
Property("MinorVersion", "B-8345"), Property("Build", "X543")] 
public void TestContextPropertyTest() 
{ 
    Console.WriteLine(TestContext.CurrentContext.Test.Properties["MajorVersion"]); 
    Console.WriteLine(TestContext.CurrentContext.Test.Properties["MinorVersion"]); 
    Console.WriteLine(TestContext.CurrentContext.Test.Properties["Build"]); 
} 
+0

謝謝,這是我能找到的唯一解決方案。我希望有一種方法可以獲得實際測試方法的任何其他屬性,但這是必須的 – breed052 2012-08-02 16:02:18

0

可能我不明白你的想法,但爲什麼不使用更簡單的解決方案?

[TestCase(TestName = "001, B-8345, X543")] 
public void TestSomethingOrOther() 
+0

我很滿意NUnit TestContext中的TestName,但我想通過將它們添加到屬性來提供多個附加值。如果我在TestCase屬性中使用它們,我將不得不將它們作爲參數添加到測試方法中,並且如果不向每個測試添加其他代碼,它們仍然無法訪問。 – breed052 2012-08-01 16:24:35

+0

但你打算如何使用'GetTestID()',添加額外的信息來斷言消息? – Akim 2012-08-01 16:46:12

+0

我在所有測試調用的方法上使用GetTestID來記錄測試結果。 – breed052 2012-08-01 19:27:40