Dot-Net

單元測試在 Run All 但在 Run Selected Tests with all selected 時失敗

  • January 16, 2013

我有一些奇怪的行為。如果我在測試資源管理器中點擊“全部執行”,那麼我的 1 個單元測試將失敗,但如果我選擇所有測試並點擊“執行選定測試”,則單元測試通過。

失敗的測試引發了反射錯誤:System.Reflection.TargetException: Non-static method requires a target.在我正在測試的 dll 程式碼中定義的類型上。這個類似乎沒有什麼奇怪的——在 dll 中定義了許多其他類,反射很滿意。我在下麵包含了測試堆棧跟踪。

注意這是一個複雜的測試 - 它從 .xlsx 文件中讀取輸入和預期答案,使用 xlsx 中的數據填充 LocalDb,使用 LocalDB 中的數據執行計算,然後將計算出的值與預期值進行比較。但是,正如我所說的那樣,當我執行所有測試(使用全選>執行選定測試)時它正在工作並且工作。

Run All 有什麼不同?任何見解將不勝感激。

我嘗試過乾淨和重建,但沒有運氣。擷取和記錄反射錯誤表明 GetValue 呼叫正在為我嘗試訪問該類型的每個屬性拋出 - 但僅在由“全部執行”執行且僅在這一類型上執行時?(如果我發現錯誤,那麼所有 GetValues 在所有其他類型上都成功)。

堆棧跟踪

Test Name:  IT_CheckCashOnly1DepositOutputValues
Test FullName:  Lib.AE.Tests.Integration.CalculationTests.IT_CheckCashOnly1DepositOutputValues
Test Source:    c:\netreturn.co.za\Main\NetReturn\Lib.AE.Tests\IntegrationTests\CalculationTest.cs : line 23
Test Outcome:   Failed
Test Duration:  0:00:00.1661906

Result Message: 
Test method Lib.AE.Tests.Integration.CalculationTests.IT_CheckCashOnly1DepositOutputValues threw exception: 
System.Reflection.TargetException: Non-static method requires a target.
Result StackTrace:  
at System.Reflection.RuntimeMethodInfo.CheckConsistency(Object target)
at System.Reflection.RuntimeMethodInfo.InvokeArgumentsCheck(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.RuntimePropertyInfo.GetValue(Object obj, BindingFlags invokeAttr, Binder binder, Object[] index, CultureInfo culture)
at System.Reflection.RuntimePropertyInfo.GetValue(Object obj, Object[] index)
at Lib.AE.Xlsx.XlsxHelper.Compare[T](T expected, T calculated, ExcelWorksheet ws, Int32 r, Int32 colStart, Boolean& valid) in c:\netreturn.co.za\Main\NetReturn\Lib.AE\Xlsx\XlsxHelper.cs:line 101
at Lib.AE.Xlsx.XlsxWorkSheet_SharePNL.CompareXlsx(ExcelPackage pck, List`1 expectedXlsx, ValuationCalculation calc) in c:\netreturn.co.za\Main\NetReturn\Lib.AE\Xlsx\XlsxSharePNL.cs:line 143
at Lib.AE.Tests.Integration.CalculationTests.CheckCalculationResults(String xlsxDocToLoad, WorkSheets testingScenarios) in c:\netreturn.co.za\Main\NetReturn\Lib.AE.Tests\IntegrationTests\CalculationTest.cs:line 64
at Lib.AE.Tests.Integration.CalculationTests.IT_CheckCashOnly1DepositOutputValues() in c:\netreturn.co.za\Main\NetReturn\Lib.AE.Tests\IntegrationTests\CalculationTest.cs:line 23

解決方案

所以這原來是(a)我的問題 - 我的單元測試與另一個單元測試共享狀態和(b)訂單問題。請注意,TestExplorer 將以哪個順序執行您的測試並不明顯。我創建了一個新的 UnitTestProject,其中包含 2 個 UnitTest .cs 文件和三個 TestMethod,即:

單元測試1.cs

   [TestMethod]
   public void ONE_AAA() {}

   [TestMethod]
   public void ONE_BBB() {}

   [TestMethod]
   public void ONE_CCC() {}

單元測試2.cs

   [TestMethod]
   public void TWO_CCC() {}

   [TestMethod]
   public void TWO_BBB() {}

   [TestMethod]
   public void TWO_AAA() {}

然後通過兩種方法執行這些測試,即 (1) Run All (2) Select all 和 Run Selected Tests,並記錄 TestExplorer 啟動測試的順序。執行選定測試的結果相當不直覺:

-- Run All
2013-01-16 11:53:47.4062 INFO TestInitialize: ONE_AAA
2013-01-16 11:53:47.4122 INFO TestCleanup: ONE_AAA
2013-01-16 11:53:47.4122 INFO TestInitialize: ONE_BBB
2013-01-16 11:53:47.4122 INFO TestCleanup: ONE_BBB
2013-01-16 11:53:47.4122 INFO TestInitialize: ONE_CCC
2013-01-16 11:53:47.4282 INFO TestCleanup: ONE_CCC
2013-01-16 11:53:47.4282 INFO TestInitialize: TWO_CCC
2013-01-16 11:53:47.4282 INFO TestCleanup: TWO_CCC
2013-01-16 11:53:47.4282 INFO TestInitialize: TWO_BBB
2013-01-16 11:53:47.4282 INFO TestCleanup: TWO_BBB
2013-01-16 11:53:47.4282 INFO TestInitialize: TWO_AAA
2013-01-16 11:53:47.4282 INFO TestCleanup: TWO_AAA

-- Select All > Run Selected
2013-01-16 11:55:26.0139 INFO TestInitialize: TWO_BBB
2013-01-16 11:55:26.0139 INFO TestCleanup: TWO_BBB
2013-01-16 11:55:26.0249 INFO TestInitialize: ONE_BBB
2013-01-16 11:55:26.0249 INFO TestCleanup: ONE_BBB
2013-01-16 11:55:26.0249 INFO TestInitialize: TWO_AAA
2013-01-16 11:55:26.0249 INFO TestCleanup: TWO_AAA
2013-01-16 11:55:26.0249 INFO TestInitialize: TWO_CCC
2013-01-16 11:55:26.0249 INFO TestCleanup: TWO_CCC
2013-01-16 11:55:26.0249 INFO TestInitialize: ONE_CCC
2013-01-16 11:55:26.0249 INFO TestCleanup: ONE_CCC
2013-01-16 11:55:26.0249 INFO TestInitialize: ONE_AAA
2013-01-16 11:55:26.0249 INFO TestCleanup: ONE_AAA

我過去曾因執行多個單元測試而陷入困境,因為測試執行的順序可能不是它們在測試類中聲明的順序,實際上可能是測試方法名稱的順序。例如,如果我有

[Test]
public void PreviousTest()
{
}

[Test]
public void LaterTest()
{
}

然後在按字母順序排列時LaterTest首先執行,因為它的名稱出現在之前PreviousTest

如果您的所有測試都是完全獨立的,這無關緊要,但是如果它們正在修改共享資源,那麼如果您期望LaterTest’ 的更改不會PreviousTest因為它被聲明為第二個而產生任何影響,那麼您可能會遇到異常行為。

引用自:https://stackoverflow.com/questions/14349512