Die kurze Antwort ist, es gibt keine gute Möglichkeit, gleichzeitige Lese-/Schreibvorgänge auf einer tatsächlichen Datenbank mit PHPUnit zu testen. Es ist einfach nicht das richtige Werkzeug für diesen Job.
Aber es gibt ein paar Facetten für eine gute Lösung, um dies zu testen. Zuerst kann der Code geschrieben werden, um jedes mögliche Szenario zu behandeln. Ein Datenbanksystem wie Postgres schlägt bei Sperren und Transaktionsproblemen sofort fehl. So behandeln Sie es elegant verwende ich Code, der etwa so aussieht (Pseudo-Code, verwendet auch another question antworten):
begin transaction
while not successful and count < 5
try
execute sql
commit
except
if error code is '40P01' or '55P03'
# Deadlock or lock not available
sleep a random time (200 ms to 1 sec) * number of retries
else if error code is '40001' or '25P02'
# "In failed sql transaction" or serialized transaction failure
rollback
sleep a random time (200 ms to 1 sec) * number of retries
begin transaction
else if error message is 'There is no active transaction'
sleep a random time (200 ms to 1 sec) * number of retries
begin transaction
increment count
Dann werden zwei Sätze von Tests erstellen: ein Satz sollte den Code bestätigen, die Situationen, Umgang mit richtig (dh Unit-Tests). Der andere Satz von Tests betrifft die Umgebung (d. H. Integrations-/Funktionstests).
Unit Tests
ich diese finde eine harte Situation zu sein, in einem PHPUnit Test zu reproduzieren, die mit einer Datenbank verbunden ist, und eine echte Datenbank ist für einen echten Unit-Test nicht geeignet. Erstellen Sie stattdessen PDO-Stubs und Unit-Tests, die jede Art von Datenbankausnahme auslösen. Dies bestätigt der Code funktioniert wie erwartet, aber testet nicht Parallelität auf einer wirklichen Datenbank, z.B .:
$iterationCount = 0;
$db->runInTransaction(function() use (&$iterationCount) {
$iterationCount++;
if ($iterationCount === 1) {
$exception = new PDOExceptionStub('Deadlock');
$exception->setCode('40P01');
throw $exception;
}
});
// First time fails, second time succeeds
$this->assertEquals(2, $iterationCount, 'Expected 2 iterations of runInTransaction');
eine komplette Suite von Tests schreiben, die an die DB nicht anschließen, aber Logik bestätigen.
Integrationstests
Wie Sie gefunden haben, PHPUnit ist einfach nicht das richtige Werkzeug ein Lasttest durchzuführen.Es eignet sich nicht für komplexere Tests als sequenzielle Einheiten- und Integrationstests. Sie können mehrere Instanzen von PHPUnit gleichzeitig ausführen, um die Datenbank stärker zu belasten. Ich finde jedoch, dass dies über das hinausgeht, wofür es gedacht war, und es hilft Ihnen auch nicht, die Datenbank auf Probleme zu überwachen. Daher sehe ich keinen Weg um die höheren Tests, die Sie vermeiden möchten.
Aber Ihre Bibliothek kann getestet werden, ohne Ihre vollständige Anwendung auszuführen. Ich würde die einfachste mögliche Anwendung erstellen, nur um sie zu testen. Es kann ein oder mehrere CLI-Skripts enthalten, die eine Verbindung zu einer Datenbank herstellen. Diese Skripts können mehrfach erstellt werden, um die Datenbank zu belasten. Wenn es hilft, können Sie damit auch eine App mit zusätzlichem Code zum Überwachen der Datenbank verwenden.
Mit der gleichen Frage – XuDing
Sie können nicht regelmäßig Nebenläufigkeit testen. Die einzigen Dinge, die Sie tun können, ist a) Stresstest und b) die Durchsetzung von Bedingungen, bei denen Sie denken, dass eine Anomalie passieren sollte (falls dies möglich ist). Grundsätzlich sollten Sie die Datenbank überhaupt nicht testen, Sie sollten sicherstellen, dass in White Papers angegeben wird, dass Ihre Algorithmen sicher sind und, wenn Sie extrem sicher sein möchten, spezifische Stresstests auf der höchsten Teststufe hinzufügen (außerhalb der Anwendung). Um die spezifische Frage zu beantworten, können Sie immer multiple Prozesse verwenden, um gleichzeitige Operationen auszuführen, so dass manuelle Verzweigungen oder Bibliotheken wie kirswswallsmith/spork helfen sollten. – Etki