2015-11-27 40 views
2

我從集成測試和Arquilian開始。我對這個工具非常滿意。 我幾乎所有的設置,除了一件事:何時使用arquilian測試時構建數據庫結構?

我的數據庫結構當然是穩定在整個測試套件,所以,爲了減少測試運行所需的時間,我想建立數據庫儘可能少,並且每次測試都會填充數據庫,並對其進行處理並進行清理。

我想在測試套件的開頭建立數據庫,讓所有測試填充/擦除數據庫可能有點冒險:如果一個測試不能很好地清理,我可能會得到不可重現的測試。

但是,也許在每個測試類中構建它都是一種很好的方法,但如果測試出現問題,由於範圍較小,因此更容易發現。

我試圖使用@BeforeClass和@AfterClass來做到這一點,但是這些都在客戶端執行,也是靜態的,所以我沒有準備好用於連接數據庫的資源。

我的方法是在每次測試之前創建數據庫結構是否正確? arquilian生命週期的哪個階段可用於構建數據庫?

回答

3

您不必自己做,至少如果您在項目中使用JPA 2.1。考慮下面的測試類:

@RunWith(Arquillian.class) 
public class MyTest { 

    @Deployment 
    public static WebArchive createDeployment() throws Exception { 
     return ShrinkWrap.create(WebArchive.class) 
      .addAsResource("META-INF/init-schema.sql") // create table ... 
      .addAsResource("META-INF/testdata.sql") // insert into ... 
      .addAsResource("META-INF/drop-schema.sql") // drop table ... 
      .addAsResource("META-INF/persistence.xml"); 
      // and maybe more ... 
    } 

} 

createDeployment()方法被調用來創建WAR文件,這是可以部署到你的應用服務器。

persistence.xml應該引用這些SQL腳本:

[...] 
<persistence-unit [...]> 
    <properties> 
     <property name="javax.persistence.schema-generation.database.action" value="drop-and-create" /> 
     <property name="javax.persistence.schema-generation.create-source" value="script" /> 
     <property name="javax.persistence.schema-generation.create-script-source" value="META-INF/init-schema.sql" /> 
     <property name="javax.persistence.schema-generation.drop-source" value="script" /> 
     <property name="javax.persistence.schema-generation.drop-script-source" value="META-INF/drop-schema.sql" /> 
     <property name="javax.persistence.sql-load-script-source" value="META-INF/testdata.sql" /> 
    </properties> 
</persistence-unit> 

通過這種方式,數據庫會自動設置測試-WAR被部署時。確保SQL文件位於「META-INF」文件夾中(如果您使用Maven,它位於「src/test/resources/META-INF」中)。

如果要控制在其中正在執行的測試方法的順序,你可以使用@InSequence註釋,例如:

public class MyTest { 
    [...] 

    private @Inject EntityManager entityManager 

    @Test @InSequence(0) 
    public void shouldHaveFoo() { 
     Foo foo = entityManager.find(Foo.class, Long.valueOf(1)); 
     assertNotNull(foo); 
    } 

    @Test @InSequence(1) 
    public void shouldHaveBar() { 
     Bar bar = entityManager.find(Bar.class, Long.valueOf(99)); 
     assertNotNull(bar); 
    } 
} 
+0

這是個好消息!我會盡快嘗試(可能是星期一),讓你知道!謝謝! – JSBach

+0

我想在測試中使用的腳本是用於在數據庫中部署的腳本,它使用$$作爲分隔符。我收到錯誤消息:無法執行JPA架構生成創建命令[DELIMITER $$] – JSBach

+0

這可能是因爲換行符。看看我的[SqlAsset類](https://gist.github.com/jabu10245/80351433704e79d4fa2e)。它將多個文件合併到一個SQL文件中,並處理$$分隔符。使用addAsResource(sqlAsset,「testdata.sql」)將這個資產添加到WAR中 –

1

使用事務擴展Arqullian其作品不錯(http://arquillian.org/modules/transaction-extension/)。您在交易中創建的數據在測試完成後將被刪除。

唯一的問題是數據在數據庫可能會影響你的測試。解決方案是針對空數據庫進行測試。它可以嵌入,實際或上面描述的方法。但是擴展程序正確管理所有事務管理,您不必關心任何事情。