2013-01-14 11 views
26

Esiste un PostgreSql incorporato in modo che possiamo testare unitamente la nostra applicazione guidata PostgreSql?incorporato PostgreSql

Poiché PostgreSql ha alcuni dialetti, è meglio utilizzare PostgreSql incorporato rispetto ad altri database incorporati.

risposta

29

No, non esiste PostgreSQL incorporato, nel senso di un database caricabile in-process-as-a-library. PostgreSQL è orientato al processo; ogni backend ha un thread e genera più processi per lavorare. Non ha senso come una biblioteca.

The H2 database supporta a limited subset of the PostgreSQL SQL dialect e l'utilizzo del driver PgJDBC.

Cosa si può fare è initdb a new temporary database, inizia con pg_ctl su una porta randomizzato in modo che non sia in conflitto con altri casi, eseguire i test, quindi utilizzare pg_ctl per fermarlo e, infine, eliminare il database temporaneo.

ho raccomando vivamente che si eseguono i Postgres temporanei su una porta non predefinita modo non si rischia di collisione con qualsiasi PostgreSQL installato localmente sulla macchina che esegue i test.

(ci è "PostgreSQL incorporato nel senso di ecpg, essenzialmente un PostgreSQL cliente incorporato nel codice C fonte come estensioni del linguaggio C preprocessore base. Si richiede ancora un server che esegue ed è un po 'brutto a . uso, non proprio raccomandato Essa esiste per lo più per fare il porting da vari altri database più facili)

+0

Questo è quello che farei anch'io. Uno script batch/shell per installare Postgres senza alcun programma di installazione è composto da 5 righe di codice. Anche se fare un initdb su ogni unità di test-run probabilmente sarà troppo lento. –

+0

@a_horse_with_no_name Sì, puoi sempre decomprimere un database pre-initdb o copiare da un modello pulito che hai initdb se manca durante il processo di compilazione. Doloroso quando si aggiorna Pg però. Personalmente trovo initdb abbastanza veloce, ma non uso più i dischi rotanti. Per quanto riguarda il file batch, la sfida principale consiste nell'assicurarsi di utilizzare una porta non in conflitto (soprattutto se si eseguono test simultanei) e di essere davvero sicuri di aver terminato il server quando hai finito. Soprattutto su Windows, dove non è possibile eliminare il datadir fino a quando il server non viene arrestato. –

+4

Si dice "non ha senso che un pezzo orientato al processo sia impacchettato come una libreria". Perchè no? Oggi puoi automatizzare IE usando una libreria Java. Certo, i processi verranno generati dietro le quinte, ma puoi comunque parlare comodamente con una libreria Java per realizzarla. Lo stesso dovrebbe essere possibile con PostgreSQL. Puoi avvicinarti a questo obiettivo incorporando un programma di installazione di PostgreSQL, ma c'è un bel po 'di codice per configurarlo in questo modo. –

35

Il è un server "embedded" PostgreSQL che è stato progettato per i test delle unità da Java:.

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

PostgreSQL incorporato fornirà un modo piattaforma neutrale per l'esecuzione postgres binario in unit test. Gran parte del codice è stato messo da Flapdoodle OSS's embed process

Per inciso, esiste anche progetti simili per Mongo, Redis, Memcached e nodejs.

+0

perché non è contrassegnato come la risposta corretta? c'è un lato negativo di questa libreria? ha tutte le caratteristiche di Postgre? Può essere arricchito con moduli ecc? –

+0

Posso testimoniare che funziona bene. Postgres standard. Esempio di utilizzo: 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

cosa significa "incorporato" in realtà è piuttosto non chiaro, ma per me è in esecuzione in memoria proprio come H2. e yandex-qatools/postgresql-embedded non è conforme a questa definizione. in effetti scarica la versione postgres specificata, la decomprime nella directory temporanea e avvia il server, tutto ciò porta all'overhead del disco, che è difficilmente accettabile in ambiente non aziendale. sto valutando questo esempio di progetto https://github.com/scottmf/postgresql-integration-test, che è ancora un buon esempio. correggimi se ho torto – Valya

2

Se si desidera eseguire una versione in-process di postgres da una suite di test di integrazione (o simile), lo postgresql-embedded ha funzionato correttamente.

Ho scritto uno small maven plugin che può essere utilizzato come un wrapper maven attorno a una versione biforcuta di postgresql-embedded.

+0

Anche in questo caso, si tenga presente che questa soluzione presenta problemi se si esce dalla configurazione predefinita –

+0

in modo corretto. Ma, nel plugin Maven, ho aggiunto in particolare un'opzione di configurazione per impostare l'URL di download per i binari in una posizione diversa da quella predefinita. – aramcodez

+0

Si prega di checkout https://github.com/aramcodz/embedded-postgres-maven-plugin e cercare il parametro di configurazione del plugin "downloadUrl". – aramcodez

11

Ho provato il progetto suggerito da @btiernay (yandex-qatools). Ho passato un bel po 'di giorni con questo e senza alcuna offesa è finita la soluzione ingegnerizzata che non funziona nel mio caso perché volevo scaricare i binari dal repository interno piuttosto che andare su Internet pubblica. In teoria lo supporta ma in realtà non lo fa.

Ho finito per utilizzare otj-pg-embedded e funziona come un fascino. È stato menzionato nei commenti quindi ho pensato di menzionarlo anche qui.

L'ho usato come DB standalone e non tramite la regola per entrambi i test di unità e lo sviluppo locale.

Dipendenza:

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

Codice:

@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

E 'possibile creare uno schema dal file '.sql' in' otj-pg-embedded'. Non sto usando la primavera. Non ho trovato alcun esempio senza 'Rule'. – tuk

2

È possibile utilizzare un'istanza container di PostgreSQL.

Poiché la rotazione di un contenitore è una questione di secondi, questa dovrebbe essere sufficiente per l'unittests. Inoltre, nel caso in cui sia necessario mantenere i dati, ad es. per le indagini, non è necessario salvare l'intero contenitore, ma solo i file di dati, che possono essere mappati all'esterno del contenitore.

Uno degli esempi su come eseguire questa operazione è here.