2010-09-24 42 views
31

創建內存數據庫結構,我有很多地方「單位」測試使用其執行期間到Oracle數據庫真正連接的應用程序。從Oracle實例

你可以想像,這些測試需要太多的時間來執行,因爲他們需要初始化一些Spring上下文的,並傳達到Oracle實例。除此之外,我們還要管理複雜的機制,如交易,以避免在測試執行後,對數據庫的修改(即使我們使用有用的類從春天像AbstractAnnotationAwareTransactionalTests)。

所以我的想法是由內存數據庫,逐步替換該Oracle測試實例。我會用hsqldb或者更好的h2

我的問題是要知道什麼是做到這一點的最好的辦法。我主要關心的是內存數據庫結構的構建和參考數據的插入。

當然,我可以提取從Oracle數據庫結構,使用一些工具,如SQL DeveloperTOAD,然後修改這些腳本以使其適應hsqldbh2語言。但我不認爲這是更好的方法。


事實上,我已經做到了使用hsqldb另一個項目,但我已經寫了手動所有的腳本來創建表。幸運的是,我只有幾張桌子可以創作。此步驟中的主要問題是將用於創建表的Oracle腳本「翻譯」爲hsqldb語言。

例如,使用下面的SQL命令在Oracle中創建一個表:

CREATE TABLE FOOBAR (
    SOME_ID NUMBER, 
    SOME_DATE DATE, -- Add primary key constraint 
    SOME_STATUS NUMBER, 
    SOME_FLAG NUMBER(1) DEFAULT 0 NOT NULL); 

需要被 「翻譯」 爲hsqldb到:

CREATE TABLE FOOBAR (
    SOME_ID NUMERIC, 
    SOME_DATE TIMESTAMP PRIMARY KEY, 
    SOME_STATUS NUMERIC, 
    SOME_FLAG INTEGER DEFAULT 0 NOT NULL); 

在我目前的項目中,有太多很多表格要手動完成...


所以我的問題:

  • 你可以給我什麼建議,以實現這一目標?
  • 是否h2hsqldb提供一些工具來生成一個Oracle連接的腳本?

技術信息

的Java 1.6,Spring 2.5中,甲骨文10。克,Maven的2


編輯

關於我的單元測試的一些信息:

在我以前hsqldb的應用程序,我有以下測試: - 一些 「基本」 單元測試,這與DB無關。 - 對於DAO測試,我使用hsqldb來執行數據庫操作,如CRUD。 - 然後,在服務層上,我使用Mockito來模擬我的DAO對象,以便專注於服務測試而不是整個應用程序(即service + dao + DB)。

在我當前的應用程序中,我們遇到了最糟糕的情況:DAO層測試需要運行Oracle連接。服務層確實使用而不是使用任何模擬對象來模擬DAO。所以服務測試需要一個Oracle連接。

我知道mock和內存數據庫是兩個分離點,我會盡快解決它們。但是,我的第一步是嘗試通過內存數據庫刪除Oracle連接,然後我將使用我的Mockito知識來增強測試。

請注意,我也希望將單元測試與集成測試分開。後者需要訪問Oracle數據庫才能執行「真實」測試,但我主要關心的問題(這是這個問題的目的)是幾乎所有的單元測試都不是單獨運行。

回答

19

使用內存中/ Java數據庫進行測試。這將確保測試更接近現實世界,比如果您試圖在測試中「抽象出」數據庫。可能這樣的測試也更容易編寫和維護。另一方面,你可能想在測試中「抽象出」的是UI,因爲UI測試通常很難自動化。

您發佈的Oracle語法與H2數據庫(我剛剛測試過)的效果很好,所以看起來H2支持的Oracle語法比HSQLDB更好。免責聲明:我是H2的作者之一。如果出現問題,請將其發送到H2郵件列表中。

無論如何,您應該在版本控制系統中擁有數據庫的DDL語句。您也可以使用這些腳本進行測試。可能您還需要支持多個模式版本 - 在這種情況下,您可以編寫版本更新腳本(alter table ...)。有了Java數據庫,您也可以測試這些數據庫。

順便說一下,使用H2或HSQLDB時,不一定需要使用內存模式。即使您堅持數據,兩個數據庫都很快。它們很容易安裝(只是一個jar文件),所需內存比Oracle少得多。

+2

考慮到DAO代碼似乎與Oracle緊密結合,並且DAO無法被抽象出來,這似乎是最好的方法 - 儘管希望DAO代碼不依賴任何Oracle特性。最好儘快抽象出DAO ...... – 2010-09-24 17:12:53

2

你的單元測試是什麼? 如果他們測試了DDL和存儲過程的正確工作,那麼你應該把測試寫得更接近Oracle:或者沒有Java代碼,或者沒有Spring和其他所有關注數據庫的漂亮Web界面。

如果要測試在Java和Spring中實現的應用程序邏輯,那麼可以使用模擬對象/數據庫連接使測試獨立於數據庫。

如果您想測試整體工作(什麼是違反模塊化開發和測試原則),那麼您可以虛擬化您的數據庫並在該實例上測試,而不會有做一些令人討厭的不可修改的修改的風險。

+0

爲了更準確地說明我爲什麼要使用內存數據庫,我編輯了我的問題。 – romaintaz 2010-09-24 07:29:51

4

最新的HSQLDB 2.0.1通過語法兼容性標誌sql.syntax_ora = true支持DUAL,ROWNUM,NEXTVAL和CURRVAL的ORACLE語法。以相同的方式,用其他標誌來處理與NULL字符串連接的字符串和UNIQUE約束中NULL的限制。大多數Oracle的功能,例如TO_CHAR,TO_DATE,NVL等已經建成

目前,使用簡單的Oracle類型,如數字,你可以使用一個類型定義:

CREATE TYPE NUMBER爲數字

設置標誌時,下一個快照將允許NUMBER(N)和ORACLE類型兼容性的其他方面。

http://hsqldb.org/support/

下載[更新:] 10月4日發佈的快照轉換大多數Oracle特定類型ANSI SQL類型。與Oracle相同,HSQLDB 2.0也支持ANSI SQL INTERVAL類型和日期/時間戳算法。

1

只要您的測試自己清理完畢(因爲您已經知道如何設置),對真實數據庫實例運行測試沒有任何問題。事實上,這是我通常比較喜歡的方法,因爲您將盡可能接近生產地進行測試。

不兼容性看起來很小,但事實上最終不久後就會反彈回來。在一個好的情況下,你可能會擺脫一些討厭的sql翻譯/廣泛的嘲弄。在不好的情況下,系統的某些部分將無法測試,我認爲這對於業務關鍵型系統來說是不可接受的風險。

+4

「*對真正的DB *運行測試沒有任何問題」。我不同意這一點。使用真正的數據庫進行**單元**測試不是一個好主意,至少有兩個原因:1.您的測試依賴於您的數據庫,並且可能因爲您的數據庫關閉而失敗。 2.創建與真實數據庫的連接更加昂貴,當您談論數百個測試時,它們的執行將成爲問題。尤其以TDD方式。 – romaintaz 2011-12-12 16:37:05

+3

但是,當然,通過測試訪問真實的數據庫也是一個好主意,但我們不是在處理**單元**測試,而是在處理更多的**集成**測試。這不是我的觀點。 – romaintaz 2011-12-12 16:37:51