web-dev-qa-db-ja.com

MsTest ClassInitializeと継承

私のテスト用の基本クラスは次のように構成されています:

[TestClass]
public abstract class MyBaseTest
{
   protected static string myField = "";

   [ClassInitialize]
   public static void ClassInitialize(TestContext context)
   {
       // static field initialization
       myField = "new value";
   }
}

今、私はベースから継承する新しいテストを、次のシグネチャで作成しようとしています:

[TestClass]
public class MyTest : MyBaseTest
{
   [TestMethod]
   public void BaseMethod_ShouldHave_FieldInitialized()
   {
       Assert.IsTrue(myField == "new value");
   }
}

ClassInitializeは子テストによって呼び出されることはありません... MsTestでの継承を使用したテスト初期化の使用方法実際の正しいとは何ですか?

59
Raffaeu

残念ながら ClassInitializeAttribute Class は継承できないため、この方法では実現できません。

継承された属性は、それを使用するクラスのサブクラスで使用できます。 ClassInitializeAttributeは継承できないため、MyTestクラスが初期化されると、ClassInitializeクラスのMyBaseTestメソッドを呼び出すことはできません。

別の方法で解決してみてください。あまり効率的ではない方法は、ClassInitializeMyTestメソッドを再度定義し、コードを複製する代わりに基本メソッドを呼び出すことです。

36
chaliasos

潜在的な回避策は、代わりにAssemblyInitializeAttributeを使用して新しいクラスを定義することです。それは明らかに異なるスコープを持っていますが、私にとってはそれが私のニーズを満たします(横断的な懸念、ちょうどすべてのテストクラスとテストメソッドにまったく同じ設定を必要とすることです)。

using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace MyTests
{
  [TestClass]
  public sealed class TestAssemblyInitialize
  {
    [AssemblyInitialize]
    public static void Initialize(TestContext context)
    {
      ...
    }
  }
}
6
Dave Sexton

クラスのすべての[TestMethod]が実行されると、クラスの新しいインスタンスが構築されることがわかります。これが発生するたびに、基本クラスのパラメーターなしのコンストラクターが呼び出されます。基本クラスで静的変数を作成し、コンストラクターの実行時にテストすることはできませんでしたか?

これにより、サブクラスに初期化コードを忘れずに配置できます。

このアプローチに欠点があるかどうかはわかりません...

そのようです:

public class TestBase
{
    private static bool _isInitialized = false;
    public TestBase()
    {
        if (!_isInitialized)
        {
            TestClassInitialize();
            _isInitialized = true;
        }
    }

    public void TestClassInitialize()
    {
        // Do one-time init stuff
    }
}
public class SalesOrderTotals_Test : TestBase
{
    [TestMethod]
    public void TotalsCalulateWhenThereIsNoSalesTax()
    {
    }
    [TestMethod]
    public void TotalsCalulateWhenThereIsSalesTax()
    {
    }
}
0
C.List

基本クラスで静的コンストラクターを使用しますか?設計により一度だけ実行され、ClassInitializeAttributeのような継承に関する奇妙な制限はありません。

0
Mladen B.