1

EF&Code Firstを調査するとき、私は少し前に質問をしました(このスレッドを参照)。テストが互いに重複しないようにする方法を保護します。DBをシードしたいのですが、テストクラスごとに次のように実行していました(MSTestを使用)。

  public class CustomerSmokeTests {
    private const string CONNECTION_STRING = "server=localhost;database=CPT_CustomerDataSync_SmokeTests;uid=sa;pwd=Password1!;";

    private DatabaseFactory _dbfactory;
    private CustomerCacheContext _customerContext;

    [TestInitialize]
    public void Setup() {
      // set initializer to create new DB
      Database.SetInitializer(new SmokeTestCreateDbWithDataIfNotExists());
      Database.SetInitializer(new SmokeTestDropCreateDbWithDataAlways());

      // create new DB connection to local SQL Server
      _dbfactory = new DatabaseFactory(CONNECTION_STRING);

      // connect to DB to auto generate it
      _customerContext = _dbfactory.GetDataContext();
    }

    [TestCleanup]
    public void Cleanup() {
      _customerContext.Dispose();
      _dbfactory.Dispose();
    }

    // tests
}

ただし、ここでの問題は、各テストがDBを作成/破棄することです(互いにオーバーラップして失敗するため、理想的ではありません...テストを個別に実行すると、すべてが希望どおりに合格します...さらに、テストの速度が大幅に低下します)。

代わりにTransactionalScopesでラップするのが良い解決策でしたが、テスト実行の開始時に、シード情報を使用してDBが再生成されるようにします(テストが開発者によって開発されるとシードが変更されるため)。

これを行う総当たり攻撃の方法は、テストinitで、DBが最近作成されたかどうかを確認し、作成されていない場合はシード情報を使用して作成する、ある種のハンドラーを作成することです。そうでない場合は、そのステップを無視します。次に、テストクリーンアップでロールバックされるTransactionalScope()を作成します。

しかし、これを処理するためのより良い方法はありますか?このブルートフォースアプローチで過剰設計の感覚を得ました...アイデア?

4

2 に答える 2

2

マーベルの反応は私に正しい方向に考えさせました...それが機能し、ここで説明するのに少し時間がかかったので、私はここでそれをブログに書きました:http ://www.andrewconnell.com/blog/archive/2012/05/02/isolating -integration-tests-with-ef4-x-code-first-amp-mstest.aspx

于 2012-05-02T10:07:32.873 に答える
-1

一般に、これらのテストは継続的インテグレーションサーバーと高度に統合されており、各チェックが行われます。したがって、必要なすべてのマッピングを使用してdbを作成するため、テスト設定の最初のテストとしてdbCreationテストを注文できるとよいと思います。最初のテストで作成した後、他のテストでは、基本のTestFixtureクラスでTransactionscopeを使用して、現在の使用方法を確認できます。TestInitializeとTestCleanupを使用してデータベースを作成していないため、統合テストは効率的に機能します。

public class BaseTestFixture
{

TransactionScope transactionScope;

    [TestInitialize]
    public void InitializeTests()
    {            

        if (IsTransactionScopeNeeded)
        {
            transactionScope = new TransactionScope();
        } 
    }

    [TestCleanup]
    public void CleanUp()
    {
        if (transactionScope != null)
            transactionScope.Dispose();

    }

}

public class DbContextTests : BaseTestFixture
{

    protected override bool IsTransactionScopeNeeded
    {
        get
        {
            return false;
        }
    }

    //This test should run first 
    [TestMethod]
    public void CreateDatabase_DatabaseNotExistedOrObselete_DatabaseCreated()
    {
    }
}
于 2012-05-01T06:35:11.643 に答える