2013-01-14 309 views
26

是否有嵌入PostgreSql,以便我們可以單元測試我們的PostgreSql驅動的應用程序?嵌入式PostgreSql

由於PostgreSql有一些方言,所以最好使用嵌入式PostgreSql本身比其他嵌入式數據庫更好。

回答

29

不,沒有嵌入式PostgreSQL,就是說可以在進程中加載​​數據庫作爲庫。 PostgreSQL是面向過程的;每個後端都有一個線程,並且它產生了多個進程來完成工作。它作爲一個圖書館沒有意義。

The H2 database支持a limited subset of the PostgreSQL SQL dialect和使用PgJDBC驅動程序。

什麼你可以做的是initdb a new temporary database,與pg_ctl啓動它的隨機端口,因此不會與其他實例相沖突,運行測試,然後使用pg_ctl阻止它,最後刪除臨時數據庫。

強烈建議您在非默認端口上運行的Postgres臨時這樣你就不會冒險與任何本地安裝PostgreSQL的運行測試機器上的碰撞。

(有「在ecpg意識,本質上是PostgreSQL的客戶嵌入C 源代碼基於預處理C語言擴展嵌入式PostgreSQL的,它仍然需要一個正在運行的服務器,這是一個有點壞壞地。使用,並不推薦它主要存在使各種其他數據庫更容易移植)

+0

這就是我要做的。無需任何安裝程序即可設置Postgres的批處理文件/ shell腳本大約有5行代碼。雖然在每個單元測試運行中執行initdb可能會太慢。 –

+0

@a_horse_with_no_name是的,你可以隨時解壓initdb的數據庫,或者從一個乾淨的模板複製initdb,如果它在構建過程中丟失的話。當你升級Pg時痛苦不堪。就我個人而言,我發現initdb足夠快,但我不再使用旋轉磁盤。至於批處理文件 - 主要的挑戰是確保使用非衝突端口(尤其是在運行併發測試時),並確保在完成後終止服務器。特別是在Windows上,在服務器停止之前無法刪除數據塊。 –

+4

你說「把面向過程的作品打包成一個庫是沒有意義的」。爲什麼不?您現在可以使用Java庫自動化IE。當然,流程將在幕後衍生,但您仍然可以舒適地談論Java庫以實現它。 PostgreSQL也應該是這樣。您可以通過嵌入PostgreSQL安裝程序來接近該目標,但是有很多樣板只是爲了設置它。 –

35

的是,已被設計爲單元測試從Java的「嵌入」 PostgreSQL的服務器:

https://github.com/yandex-qatools/postgresql-embedded

嵌入式PostgreSQL將提供在單元測試運行Postgres的二進制的平臺中立的方式。大部分的代碼已經從Flapdoodle OSS's embed process

製作順便說一句,也存在於MongoRedisMemcachednodejs類似的項目。

+0

爲什麼這不被標記爲正確答案?這個庫有一個缺點嗎?它具有Postgre的所有功能嗎?它可以嵌入模塊等? –

+0

我可以證明它運作良好。標準Postgres。用法示例:https://github.com/icgc-dcc/dcc-submission/blob/develop/dcc-submission-loader/src/test/java/org/icgc/dcc/submission/loader/util/EmbeddedPostgres.java https://開頭github上。com/icgc -dcc/dcc-submission/blob/c5f6e38783fe164b35a63ac15dfb22fe9559d5f5/dcc-submission-loader/src/test/java/org/icgc/dcc/submission/loader/util/AbstractPostgressTest.java – btiernay

+0

'embedded'不清楚,但對我來說,它就像H2一樣在記憶中運行。而yandex-qatools/postgresql-embedded不符合這個定義。實際上它會下載指定的postgres版本,將其解壓到臨時目錄並啓動服務器,所有這些都會導致磁盤開銷,這在非企業環境中很難接受。我正在判斷這個示例項目https://github.com/scottmf/postgresql-integration-test,這仍然是一個很好的例子。糾正我,如果我錯了 – Valya

2

如果您希望從集成(或類似的)測試套件運行postgres的進程中版本,postgresql-embedded對我來說工作得很好。

我寫了一個small maven plugin,可以用作postgresql嵌入分支版本的maven包裝。

+0

同樣,如果您超出默認配置 –

+0

的公平值,請注意此解決方案存在問題。但是,在maven插件中,我專門添加了一個配置選項,用於將二進制文件的下載URL設置爲非默認位置。 – aramcodez

+0

請檢出https://github.com/aramcodz/embedded-postgres-maven-plugin並查找「downloadUrl」插件配置參數。 – aramcodez

11

我試過@btiernay(yandex-qatools)建議的項目。我花了好幾天的時間,沒有任何冒犯它的工程解決方案,這在我的情況下不起作用,因爲我想從內部存儲庫下載二進制文件,而不是去公共互聯網。理論上它支持它,但實際上它不支持。

我結束了使用otj-pg-embedded它的作品就像一個魅力。它在評論中提到,所以我想我也會在這裏提及它。

我用它作爲獨立的數據庫,而不是通過規則進行單元測試和本地開發。

相關性:

<dependency> 
    <groupId>com.opentable.components</groupId> 
    <artifactId>otj-pg-embedded</artifactId> 
    <version>0.7.1</version> 
</dependency> 

代碼:

@Bean 
public DataSource dataSource(PgBinaryResolver pgBinaryResolver) throws IOException { 
    EmbeddedPostgres pg = EmbeddedPostgres.builder() 
     .setPgBinaryResolver(pgBinaryResolver) 
     .start(); 


    // It doesn't not matter which databse it will be after all. We just use the default. 
    return pg.getPostgresDatabase(); 
} 

@Bean 
public PgBinaryResolver nexusPgBinaryResolver() { 
    return (system, machineHardware) -> { 
     String url = getArtifactUrl(postgrePackage, system + SEPARATOR + machineHardware); 
     log.info("Will download embedded Postgre package from: {}", url); 

     return new URL(url).openConnection().getInputStream(); 
    }; 
} 

private static String getArtifactUrl(PostgrePackage postgrePackage, String classifier) { 
    // Your internal repo URL logic 
} 
+0

是否可以通過'otj-pg-embedded'中的'.sql'文件創建模式。我不使用彈簧。沒有'Rule'我找不到任何示例。 – tuk

2

你可以使用PostgreSQL的container實例。

由於旋轉一個容器只需幾秒鐘,這應該足夠單元測試。此外,如果您需要保留數據,例如爲了調查,您不需要保存整個容器,只需要保存可以映射到容器外部的數據文件。

如何做到這一點的例子之一可以找到here