我遇到了一些奇怪的问题。如果我在“测试资源管理器”中点击“运行全部”,那么我的某个单元测试会失败,但是如果我选择所有测试并点击“运行所选测试”,则该单元测试将通过。
这个失败的测试引发了一个反射错误:
注意:这是一个复杂的测试——它从一个 .xlsx 文件中读取输入和期望的答案,使用来自 xlsx 的数据填充 LocalDb,在 LocalDB 中执行计算,然后将计算结果与期望值进行比较。但是,就像我说的,它可以工作,并且在运行所有测试(使用“全选”>“运行所选测试”)时也可以工作。
运行全部有什么不同?任何见解都会受到赞赏。
我尝试过干净和重建,但没有成功。捕获和记录反射错误表明每次我尝试访问类型上的任何属性时,GetValue 调用都会失败。但只有在“运行全部”时才会失败,并且只针对这一个类型?(如果我捕获错误,则所有其他类型上的所有 GetValues 都会成功。)
堆栈跟踪
这个失败的测试引发了一个反射错误:
System.Reflection.TargetException: Non-static method requires a target.
,该类型被定义在我要测试的 dll 代码中。这个类似乎没有任何异常——dll 中定义的许多其他类都可以正常运行反射。下面是测试堆栈跟踪。注意:这是一个复杂的测试——它从一个 .xlsx 文件中读取输入和期望的答案,使用来自 xlsx 的数据填充 LocalDb,在 LocalDB 中执行计算,然后将计算结果与期望值进行比较。但是,就像我说的,它可以工作,并且在运行所有测试(使用“全选”>“运行所选测试”)时也可以工作。
运行全部有什么不同?任何见解都会受到赞赏。
我尝试过干净和重建,但没有成功。捕获和记录反射错误表明每次我尝试访问类型上的任何属性时,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
解决方案
这个问题最终被证明是我的问题 - 我的单元测试与另一个单元测试共享了状态,而且是一个顺序问题。请注意,TestExplorer将以哪种顺序运行您的测试并不明显。我创建了一个新的UnitTestProject,其中包含2个UnitTest .cs文件和每个文件中的三个TestMethods,即:
UnitTest1.cs
[TestMethod]
public void ONE_AAA() {}
[TestMethod]
public void ONE_BBB() {}
[TestMethod]
public void ONE_CCC() {}
UnitTest2.cs
[TestMethod]
public void TWO_CCC() {}
[TestMethod]
public void TWO_BBB() {}
[TestMethod]
public void TWO_AAA() {}
然后通过两种方法运行这些测试,即(1)运行全部(2)选择全部并运行所选测试,并记录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