Ich möchte für jeden von mir geschriebenen Komponententest eine kleine PostgreSQL-Datenbank ausführen, die nur im Speicher ausgeführt wird. Zum Beispiel:
@Before
void setUp() {
String port = runPostgresOnRandomPort();
connectTo("postgres://localhost:"+port+"/in_memory_db");
// ...
}
Im Idealfall wird eine einzelne ausführbare Postgres-Datei in die Versionskontrolle eingecheckt, die vom Komponententest verwendet wird.
So etwas wie HSQL
, aber für Postgres. Wie kann ich das machen?
Kann ich eine solche Postgres-Version bekommen? Wie kann ich es anweisen, die Festplatte nicht zu verwenden?
testcontainers
dem Ihr Test im Wesentlichen eine wegwerfbare, dockerisierte Postgres-Instanz starten kann. Siehe github.com/testcontainers/testcontainers-java/blob/master/…(Verschieben meiner Antwort von der Verwendung von PostgreSQL im Speicher und Verallgemeinern):
Sie können Pg nicht im Prozess oder im Speicher ausführen
Nein, das ist nicht möglich. PostgreSQL ist in C implementiert und zu Plattformcode kompiliert. Im Gegensatz zu H2 oder Derby können Sie die nicht einfach laden
jar
und als wegwerfbare In-Memory-Datenbank starten.Im Gegensatz zu SQLite, das ebenfalls in C geschrieben und zu Plattformcode kompiliert ist, kann PostgreSQL auch nicht in Bearbeitung geladen werden. Es sind mehrere Prozesse erforderlich (einer pro Verbindung), da es sich um eine Multiprozessor- und keine Multithreading-Architektur handelt. Die Multiprozessor-Anforderung bedeutet, dass Sie den Postmaster als eigenständigen Prozess starten müssen .
Stattdessen: Konfigurieren Sie eine Verbindung vor
Ich schlage vor, einfach Ihre Tests zu schreiben, um zu erwarten, dass ein bestimmter Hostname / Benutzername / Passwort funktioniert, und den Test am Ende des Laufs
CREATE DATABASE
eine Wegwerfdatenbank zu verwendenDROP DATABASE
. Rufen Sie die Datenbankverbindungsdetails aus einer Eigenschaftendatei ab, erstellen Sie Zieleigenschaften, Umgebungsvariablen usw.Es ist sicher, eine vorhandene PostgreSQL-Instanz zu verwenden, in der Sie bereits Datenbanken haben, die Sie interessieren, solange der Benutzer, den Sie für Ihre Komponententests angeben, kein Superuser ist, sondern nur ein Benutzer mit
CREATEDB
Rechten. Im schlimmsten Fall verursachen Sie Leistungsprobleme in den anderen Datenbanken. Aus diesem Grund bevorzuge ich eine vollständig isolierte PostgreSQL-Installation zum Testen.Stattdessen: Starten Sie eine wegwerfbare PostgreSQL-Instanz zum Testen
Alternativ , wenn Sie wirklich keen könnten Sie Ihre Testumgebung haben suchen Sie die
initdb
undpostgres
Binärdateien, führen Sieinitdb
eine Datenbank zu erstellen, ändern ,pg_hba.conf
umtrust
, führenpostgres
sie an einem zufälligen Port zu starten, einen Benutzer erstellen, erstellen Sie eine DB, und die Tests ausführen . Sie können sogar die PostgreSQL-Binärdateien für mehrere Architekturen in einem JAR bündeln und die für die aktuelle Architektur in ein temporäres Verzeichnis entpacken, bevor Sie die Tests ausführen.Persönlich denke ich, dass dies ein großer Schmerz ist, der vermieden werden sollte; Es ist viel einfacher, nur eine Test-DB zu konfigurieren. Mit dem Aufkommen der
include_dir
Unterstützung in wird es jedoch ein wenig einfacherpostgresql.conf
. Jetzt können Sie nur noch eine Zeile anhängen und für den Rest eine generierte Konfigurationsdatei schreiben.Schnelleres Testen mit PostgreSQL
Weitere Informationen dazu, wie Sie die Leistung von PostgreSQL zu Testzwecken sicher verbessern können, finden Sie in einer ausführlichen Antwort, die ich zuvor zu diesem Thema geschrieben habe: Optimieren Sie PostgreSQL für schnelle Tests
Der PostgreSQL-Dialekt von H2 ist kein echter Ersatz
Einige Benutzer verwenden stattdessen die H2-Datenbank im PostgreSQL-Dialektmodus, um Tests auszuführen. Ich denke, das ist fast so schlimm wie die Rails-Leute, die SQLite zum Testen und PostgreSQL für die Produktionsbereitstellung verwenden.
H2 unterstützt einige PostgreSQL-Erweiterungen und emuliert den PostgreSQL-Dialekt. Es ist jedoch nur das - eine Emulation. Sie werden Bereiche , wo H2 eine Abfrage übernimmt aber PostgreSQL nicht der Fall, wo das Verhalten unterscheidet, etc . Es gibt auch viele Stellen, an denen PostgreSQL etwas unterstützt, was H2 zum Zeitpunkt des Schreibens einfach nicht kann - wie Fensterfunktionen.
Wenn Sie die Einschränkungen dieses Ansatzes verstehen und Ihr Datenbankzugriff einfach ist, ist H2 möglicherweise in Ordnung. Aber in diesem Fall sind Sie wahrscheinlich ein besserer Kandidat für ein ORM, das die Datenbank abstrahiert, weil Sie die interessanten Funktionen sowieso nicht nutzen - und in diesem Fall müssen Sie sich nicht mehr so sehr um die Datenbankkompatibilität kümmern.
Tablespaces sind nicht die Antwort!
Sie nicht einen Tabellen verwenden , um eine „in-memory“ Datenbank zu erstellen. Dies ist nicht nur unnötig, da es die Leistung ohnehin nicht wesentlich verbessert, sondern auch eine großartige Möglichkeit, den Zugriff auf andere zu stören, die Sie in derselben PostgreSQL-Installation interessieren könnten. Die 9.4-Dokumentation enthält jetzt die folgende Warnung :
weil ich bemerkte, dass zu viele Leute dies taten und in Schwierigkeiten gerieten.
(Wenn Sie dies getan haben, können Sie
mkdir
das fehlende Tablespace-Verzeichnis verwenden, um PostgreSQL erneut zu starten, dannDROP
die fehlenden Datenbanken, Tabellen usw. Es ist besser, es einfach nicht zu tun.)quelle
initdb
eine ganz neue Pg installieren. Aber wirklich, es gibt kaum einen Unterschied zwischen einer Pg, die für schnelle Tests auf normalem Speicher optimiert wurde (fsync = off und andere deaktivierte Funktionen für Datenbeständigkeit / Sicherheit), als auf einer Ramdisk, zumindest unter Linux.Oder Sie können einen TABLESPACE in einem ramfs / tempfs erstellen und dort alle Ihre Objekte erstellen.
Ich wurde kürzlich auf einen Artikel hingewiesen, in dem es darum geht, genau das unter Linux zu tun .
Warnung
Dies kann die Integrität Ihres gesamten Datenbankclusters gefährden .
Lesen Sie die hinzugefügte Warnung im Handbuch.
Dies ist also nur eine Option für Verbrauchsdaten.
Für Unit-Tests sollte es gut funktionieren. Wenn Sie andere Datenbanken auf demselben Computer ausführen, müssen Sie aus Sicherheitsgründen einen separaten Datenbankcluster (der über einen eigenen Port verfügt) verwenden.
quelle
initdb
eine neue Postgres-Instanz in einem Tempfs oder einer Ramdisk. Sie nicht eine Tabelle in einem tempfs usw. verwenden, es ist zerbrechlich und sinnlos. Verwenden Sie besser einen normalen Tabellenbereich und erstellen SieUNLOGGED
Tabellen - dies funktioniert ähnlich. Die WAL-Leistung und die fsync-Faktoren werden nur berücksichtigt, wenn Sie Maßnahmen ergreifen, die die Integrität der gesamten Datenbank gefährden (siehe stackoverflow.com/q/9407442/398670 ). Tu es nicht.Jetzt ist es möglich, eine In-Memory-Instanz von PostgreSQL in Ihren JUnit-Tests über die eingebettete PostgreSQL-Komponente von OpenTable auszuführen: https://github.com/opentable/otj-pg-embedded .
Durch Hinzufügen der Abhängigkeit zur in otj-pg eingebetteten Bibliothek ( https://mvnrepository.com/artifact/com.opentable.components/otj-pg-embedded ) können Sie Ihre eigene PostgreSQL-Instanz in Ihrem @Before und starten und stoppen @ Nach Haken:
Sie bieten sogar eine JUnit-Regel an, mit der JUnit Ihren PostgreSQL-Datenbankserver automatisch für Sie startet und stoppt:
quelle
@Rule
mit@ExtendWith
? Verwenden Sie einfach die.start()
in@BeforeAll
?DataSource embeddedPostgresDS = EmbeddedPostgres.builder().start().getPostgresDatabase();
Sie könnten verwenden TestContainers einen PosgreSQL Docker Behälter für Tests spin up: http://testcontainers.viewdocs.io/testcontainers-java/usage/database_containers/
TestContainer bieten eine JUnit @ Rule / @ ClassRule : Dieser Modus startet eine Datenbank in einem Container vor Ihren Tests und reißt sie anschließend ab.
Beispiel:
quelle
Es gibt jetzt eine In-Memory-Version von PostgreSQL von der russischen Suchfirma Yandex: https://github.com/yandex-qatools/postgresql-embedded
Es basiert auf dem Einbettungsprozess von Flapdoodle OSS.
Anwendungsbeispiel (von der Github-Seite):
Ich benutze es einige Zeit. Es funktioniert gut.
AKTUALISIERT : Dieses Projekt wird nicht mehr aktiv gepflegt
quelle
Sie können auch PostgreSQL-Konfigurationseinstellungen verwenden (wie die in der Frage und der akzeptierten Antwort hier beschriebenen ), um Leistung zu erzielen, ohne unbedingt auf eine speicherinterne Datenbank zurückgreifen zu müssen.
quelle
Wenn Sie NodeJS verwenden, können Sie pg-mem (Haftungsausschluss: Ich bin der Autor) verwenden, um die häufigsten Funktionen einer Postgres-Datenbank zu emulieren.
Sie verfügen über eine vollständige speicherinterne, isolierte, plattformunabhängige Datenbank, die das PG-Verhalten repliziert (sie wird sogar in Browsern ausgeführt ).
Ich schrieb einen Artikel zu zeigen , wie es zu benutzen für Ihr Gerät testet hier .
quelle