(Flytta mitt svar från att använda PostgreSQL i minnet och generalisera det):
Du kan inte köra Pg under process, in-memory
Jag kan inte ta reda på hur man kör in-memory Postgres databas för testning. Är det möjligt?
Nej, det är inte möjligt. PostgreSQL implementeras i C och kompileras till plattformskod. Till skillnad från H2 eller Derby kan du inte bara ladda jar
och avfyra den som en engångs-DB i minnet.
Till skillnad från SQLite, som också är skriven i C och kompilerad till plattformskod, kan PostgreSQL inte heller laddas under processen. Det kräver flera processer (en per anslutning) eftersom det är en multiprocessing, inte en multithreading, arkitektur. Kravet på multibearbetning betyder att du måste starta postmastern som en fristående process.
Istället:förkonfigurera en anslutning
Jag föreslår att du helt enkelt skriver dina tester för att förvänta dig att ett visst värdnamn/användarnamn/lösenord ska fungera och att du har testkabeln CREATE DATABASE
en engångsdatabas, sedan DROP DATABASE
i slutet av löpningen. Få information om databasanslutningen från en egenskapsfil, bygg målegenskaper, miljövariabel, etc.
Det är säkert att använda en befintlig PostgreSQL-instans där du redan har databaser som du bryr dig om, så länge som användaren du tillhandahåller till dina enhetstester är inte en superanvändare, bara en användare med CREATEDB
rättigheter. I värsta fall kommer du att skapa prestandaproblem i de andra databaserna. Jag föredrar att köra en helt isolerad PostgreSQL-installation för testning av den anledningen.
Istället:Starta en engångspostgreSQL-instans för testning
Alternativt, om du är på riktigt angelägen om att du kan låta din testsele hitta initdb
och postgres
binärer, kör initdb
för att skapa en databas, ändra pg_hba.conf
att trust
, kör postgres
för att starta den på en slumpmässig port, skapa en användare, skapa en DB och köra testen. Du kan till och med bunta PostgreSQL-binärfilerna för flera arkitekturer i en burk och packa upp de för den aktuella arkitekturen till en tillfällig katalog innan du kör testerna.
Personligen tycker jag att det är en stor smärta som bör undvikas; det är mycket lättare att bara ha en test-DB konfigurerad. Det har dock blivit lite lättare med tillkomsten av include_dir
stöd i postgresql.conf
; nu kan du bara lägga till en rad och sedan skriva en genererad konfigurationsfil för resten.
Snabbare testning med PostgreSQL
För mer information om hur du säkert förbättra prestanda för PostgreSQL för teständamål, se ett detaljerat svar jag skrev om detta ämne tidigare:Optimera PostgreSQL för snabbtestning
H2:s PostgreSQL-dialekt är inte en riktig ersättning
Vissa människor använder istället H2-databasen i PostgreSQL-dialektläge för att köra tester. Jag tror att det är nästan lika illa som Rails-folket som använder SQLite för testning och PostgreSQL för produktionsinstallation.
H2 stöder vissa PostgreSQL-tillägg och emulerar PostgreSQL-dialekten. Men det är bara det - en emulering. Du hittar områden där H2 accepterar en fråga men PostgreSQL inte gör det, där beteendet skiljer sig etc. Du hittar också många platser där PostgreSQL stöder att göra något som H2 bara inte kan - som fönsterfunktioner, vid tidpunkten för skriver.
Om du förstår begränsningarna med detta tillvägagångssätt och din databasåtkomst är enkel, kan H2 vara OK. Men i så fall är du förmodligen en bättre kandidat för en ORM som abstraherar databasen eftersom du ändå inte använder dess intressanta funktioner – och i så fall behöver du inte bry dig lika mycket om databaskompatibilitet längre.
Tabellytor är inte svaret!
Gör inte använd ett tabellutrymme för att skapa en "in-memory" databas. Det är inte bara onödigt eftersom det inte kommer att hjälpa prestanda nämnvärt i alla fall, utan det är också ett utmärkt sätt att störa åtkomsten till alla andra du kanske bryr dig om i samma PostgreSQL-installation. 9.4-dokumentationen innehåller nu följande varning:
VARNING
Även om de ligger utanför PostgreSQL-datakatalogen är tabellutrymmen en integrerad del av databasklustret och kan inte behandlas som en autonom samling av datafiler. De är beroende av metadata som finns i huvuddatakatalogen och kan därför inte kopplas till ett annat databaskluster eller säkerhetskopieras individuellt. På liknande sätt, om du förlorar ett tabellutrymme (filradering, diskfel, etc.), kan databasklustret bli oläsligt eller oläsligt. Att placera ett tabellutrymme på ett temporärt filsystem som en ramdisk riskerar tillförlitligheten för hela klustret.
eftersom jag märkte att för många människor gjorde detta och råkade ut för problem.
(Om du har gjort detta kan du mkdir
den saknade tabellutrymmeskatalogen för att få PostgreSQL att starta igen, sedan DROP
de saknade databaserna, tabellerna etc. Det är bättre att bara inte göra det.)