单击测试在“全部运行”上失败,但未在“运行所选测试”中全部选中

时间:2013-01-16 00:28:07

标签: .net unit-testing exception-handling visual-studio-2012

我得到了一些奇怪的行为。如果我在测试资源管理器中单击“全部运行”,则单元测试中的一个会失败,但如果我选择所有测试并单击“运行选定的测试”,则单元测试将通过。

失败的测试是在我正在测试的dll代码中定义的类型上抛出反射错误:System.Reflection.TargetException: Non-static method requires a target.。这个类似乎没有什么奇怪的东西 - 在dll中定义了很多其他类,反映很满意。我在下面列出了测试堆栈跟踪。

NB这是一个复杂的测试 - 它读取输入&来自.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文件和3个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

4 个答案:

答案 0 :(得分:10)

我在过去遇到了多个单元测试,因为测试运行的顺序可能与测试类中声明的顺序不同,实际上可能是测试顺序方法名称。例如如果我有

[Test]
public void PreviousTest()
{
}

[Test]
public void LaterTest()
{
}

然后LaterTest首先运行,因为按字母顺序排序时,PreviousTest的名称会显示在LaterTest之前。

如果您的所有测试都是完全独立的,那么无关紧要,但如果他们正在修改共享资源,那么如果您期望PreviousTest的更改不会对其产生任何影响,那么您可能会遇到异常行为{{1}}由于被宣布为第二名。

答案 1 :(得分:5)

确保您的成员在设置范围内进行初始化,否则可以重复使用。

[TestFixture]
public class RegistrationInteractorTests
{
    private  IRegistrationService _registrationService;
    private  IRegistrationValidationService _registrationValidationService;
  ......

    [SetUp]
    public void Init()
    {
        _registrationService = A.Fake<IRegistrationService>();
        _registrationValidationService = A.Fake<IRegistrationValidationService>();
    }

...

}

//错误的方式是这样的:

 [TestFixture]
    public class RegistrationInteractorTests
    {
        protected readonly IRegistrationService _registrationService = A.Fake<IRegistrationService>();

        protected readonly IRegistrationValidationService _registrationValidationService =
            A.Fake<IRegistrationValidationService>();



        [SetUp]
        public void Init()
        {

        }

答案 2 :(得分:0)

您的[TestInitialize]方法在每次测试之前运行。从中删除所有与测试相关的代码,并将其放入单独的测试中。

答案 3 :(得分:0)

我们尝试调查此问题已有一个星期了。确保所有测试项目都使用相同版本的DLL,尤其是Nuget包。

问题是,当您执行“全部运行”时,所有TEST项目中所有使用的库都放在一个文件夹中(类似MyApp\TestResults\Deploy_user1 2018-11-20 15_52_15\Out)。并且由于这些Dll库发生冲突。