43

私はいくつかの奇妙な動作を取得しています。テスト エクスプローラーで [すべて実行] をクリックすると、単体テストの 1 つが失敗しますが、すべてのテストを選択して [選択したテストを実行] をクリックすると、単体テストは成功します。

失敗しているテストは、リフレクション エラーをスローしています:System.Reflection.TargetException: Non-static method requires a target.私がテストしている dll コードで定義されている型で。クラスに奇妙なことは何もないようです - リフレクションが満足しているdllで定義された他のクラスがたくさんあります。以下にテストスタックトレースを含めました。

注: これは複雑なテストです。.xlsx ファイルから入力と予想される回答を読み取り、xlsx からのデータを LocalDb に入力し、LocalDB のデータを使用して計算を実行し、計算結果を予想値と比較します。ただし、私が言うように、すべてのテストを実行すると機能し、機能します([すべて選択]> [選択したテストを実行]を使用)。

Run All との違いは何ですか? 任意の洞察をいただければ幸いです。

クリーンアップと再構築を試みましたが、うまくいきませんでした。リフレクションエラーをキャッチしてログに記録すると、そのタイプでアクセスしようとしたすべてのプロパティに対して GetValue 呼び出しがスローされていることが示されますが、「すべて実行」によって実行され、この 1 つのタイプでのみ実行されますか? (エラーをキャッチした場合、すべての 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 がどの順序でテストを実行するかは明らかではないことに注意してください。2 つの UnitTest .cs ファイルとそれぞれ 3 つの TestMethods を含む新しい UnitTestProject を作成しました。

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) すべてを選択して選択したテストを実行という 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

4 に答える 4

16

過去に複数の単体テストを実行していて、テストの実行順序がテスト クラスで宣言されている順序とは異なる可能性があり、実際にはテスト メソッド名の順序である可能性があることに気付きました。たとえば、私が持っている場合

[Test]
public void PreviousTest()
{
}

[Test]
public void LaterTest()
{
}

次に、アルファベット順に並べたときにLaterTestその名前が前に表示されるので、最初に実行されます。PreviousTest

すべてのテストが完全に独立している場合、これは問題になりませんが、共有リソースを変更している場合、2 番目に宣言されているためにLaterTest変更が影響しないと予想していた場合、異常な動作が発生する可能性があります。PreviousTest

于 2013-01-16T01:18:36.517 に答える
9

メンバーが setup スコープで初期化されていることを確認してください。そうしないと、再利用できます。

[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()
        {

        }
于 2014-08-24T10:51:40.770 に答える
0

メソッド[TestInitialize]は、すべてのテストの前に実行されます。単一テストに依存するコードをすべて削除し、個別のテストに配置します。

于 2013-01-16T00:33:13.623 に答える