2011-08-09 17 views
3

すべて(JPA + Hibernateを介して)データベースにアクセスするユニットテストを記述するためには、それらを並列に実行できるようにするために何を知っておく必要がありますか?我々は、単一のスレッドで実行されているときに発生しないmavens並列ユニットテスト機能と経験テストの失敗を使用し始めました。並列で実行できるJPAに対してjunitテストを書くには?

ここで私たちがテストをどのように書いているかの簡単な例を挙げます。 EntityManagerとその他のクラスを@Beforeに設定し、トランザクションを開始し、最終的にクラス内のすべてのテストに必要なテストデータを挿入します(テスト固有のデータがテストで作成されます)。 @Afterテストが実行されると、すべてのメンバ変数のTransaction.rollback();nullを呼び出すことですべてをロールバックします。 すべての単体テストをメモリ内のhsqldbに対して実行します。

public class TestLogEntryDAO { 
    private EntityManager em; 
    private LogEntryDAO dao; 

    @Before 
    public void before() { 
     em = Persistence.createEntityManagerFactory("junit") 
      .createEntityManager(); 
     dao = new DAOFactory<LogEntryDAO>(LogEntryDAO.class).newInstance(em, 
      Mockito.mock(ILogger.class)); 

     em.getTransaction().begin(); 

     RecordDAO recordDAO = new DAOFactory<RecordDAO>(RecordDAO.class) 
      .newInstance(em, Mockito.mock(ILogger.class)); 
     recordDAO.setLogEntryDAO(dao); 
     createTestData(); // Is this ok? 
    } 

    @After 
    public void after() { 
     em.getTransaction().rollback(); 
     em = null; 
     dao = null; 
    } 

    @Test 
    public void testSomething() { 
     // ... 
    } 
} 

ありがとうございます!

+1

それぞれの 'EntityManager'を' ThreadLocal'に格納して、エンティティマネージャのインスタンスをオーバーライドしたくないときにオーバーライドしないようにしてください。 – Jeremy

答えて

1

警告:私はこれを試みていません。これは私の現在のテストスイートで実装されていない拡張機能の1つです。並行使用して同じデータセットを実行している

  • テスト:JPAを含む


    パラレルテストは、以下の一つ以上に該当する場合、失敗にバインドされています。

  • データを読み取るテストは、データを作成、更新、または削除するテストと同時に実行できます。

パラレルテストを実行する必要がある場合は、データを読み取るすべてのテストを別のスイートにグループ化できますが、依然としてデータベースの状態を変更するテストのシリアル化が必要です。テストで許可されている場合は、並列実行されるテストごとに個別のデータセットを使用できます。これは、すべてのアプリケーションとすべてのテストでは当てはまりません。

テスト固有のデータセットは、ファイルセット(DbUnitを使用)やインメモリデータセット(カスタムテスト値ファクトリを使用して作成)から読み込むことができ、各パラレルテストは異なるアイテムに依存しますセットで。明らかに、共通のデータは、テスト全体でに変更してはいけません。そうしないと、トランザクションがロールバックされてしまいます(オプティミスティックロックが存在する場合)。

また、テスト全体で突然変異を起こす可能性のあるデータは、複数のテストで共有することはできません。これは、各テストで異なる値のピンを使用すると簡単に達成できます。あなたは、あなたのテストがそれらの値、またはテストに特有の不変の不変のプロパティに対してアサートすることを保証する必要があります。データピンニングはスレッドIDを使用して実行できます。

上記の例を示すには、エンティティA(属性A1およびA2)をデータベースに保持するテストを実行している場合、テストT1は値A1 = x1およびA2 = y1、および並列テストT2は、Aの別のエンティティをA1 = x2およびA2 = y2の値で維持する必要があります。これは、並列に実行される他のテストでは、A1とA2の両方の値が変更されることを前提としています。あなたのテストがA1を突然変異させないという特性を持っているならば、そのようなA1の値は全てテストを通して一定であることができます。

関連する問題