2013-07-24 2 views
12

Seit vier Monaten bauen wir eine komplexe Web-App mit Laravel 4 mit einer guten Unit-Test-Abdeckung. Jetzt haben wir 159 Tests und 592 Behauptungen, um Regression zu verhindern und uns zu erlauben, unsere App leicht zu refaktorisieren.Laravel & PHPUnit: erlauben Prozessisolierung Mysql zu verhindern Zu viele Verbindungen Fehler

Schönes Bild, aber seit einigen Tagen haben wir die folgenden Fehler in den letzten Tests:

PDOException: SQLSTATE[HY000] [1040] Too many connections 

Der Grund ist einfach: alle Tests laufen im gleichen Prozess und MySQL erlaubt nur eine bestimmte Anzahl von Zugang in der gleiche Zeit. Jetzt haben wir zu viele Tests. Wenn ich einige Tests in der Mitte meiner Testsuite lösche, werden die letzten bestanden.

Die Lösung könnte sein, PHPUnit in der Prozessisolation wie in der folgenden Konfiguration auszuführen, aber die Laravel-Tests scheinen nicht so gestartet zu sein. Ich erhalte einen anderen Fehler in jedem Test:

PHPUnit_Framework_Exception: Notice: Constant LARAVEL_START already defined in /.../.../autoload.php on line 3 
<?xml version="1.0" encoding="UTF-8"?> 
<phpunit backupGlobals="false" 
    backupStaticAttributes="false" 
    bootstrap="bootstrap/autoload.php" 
    colors="true" 
    convertErrorsToExceptions="true" 
    convertNoticesToExceptions="true" 
    convertWarningsToExceptions="true" 
    processIsolation="true" 
    stopOnFailure="false" 
    syntaxCheck="false" 
> 

</phpunit> 

Also meine Frage ist: wie könnte ich konfiguriere Laravel Tests mit processIsolation="true" arbeiten oder sehen Sie eine andere Lösung für mein Problem?

+0

Haben lösen Sie dieses Problem? –

+0

Sie können diese Diskussion überprüfen: https://plus.google.com/107528973720672293459/posts/bBC5CdKPFQ4 für weitere Informationen. Grundsätzlich kann ich Laravel und PHPUnit nicht zusammen mit processIsolation konfigurieren, also setze ich max_connections in MySQL config auf 1000. Nicht sehr hübsch, aber das funktioniert. –

Antwort

3

Für Laravel 4 können Sie \ DB :: disconnect ('connection') in Ihrer Funktion tearDown() verwenden. Siehe doc hier: http://laravel.com/docs/database#accessing-connections

„Wenn Sie von der Datenbank trennen müssen wegen Überschreitung der underyling PDO Instanz max_connections Grenze, verwenden Sie die Trennmethode“

2

Ich würde einen Blick auf Mocks nehmen und Ihre MySQL Abhängigkeit entfernen: https://github.com/padraic/mockery#mocking-public-static-methods

In Zukunft würde ich auf das Testen Ihrer SQL tatsächlich vorschlagen, mehr konzentrieren. Kürzlich hat meine Firma eine Menge DBA's eingestellt, die unsere alte Langsamkeit wirklich umkehrten.

+0

Danke für die Idee, aber ich möchte meine Datenbank aus verschiedenen Gründen wirklich testen. Ich möchte die Migrationen testen und habe viele Funktionstests, die einen DB-Zugriff benötigen, sie stehen kurz vor Integrationstests. Ein anderer Punkt ist, dass 90% der Arbeit einer klassischen Webanwendung Daten speichern, aufrufen und präsentieren. Wenn du die DB in den Tests nicht überprüfst, denke ich, dass dir etwas fehlt –

+1

* "Wenn du die DB in den Tests nicht kontrollierst, denke ich, dass du etwas vermisst ..." * Das stimmt zwar, stimmt Das bedeutet nicht, dass Sie Unit-Tests und Integrationstests gleichzeitig ausführen müssen. –

4

Sie können nun DB :: connection() -> setPdo (null) ausführen, um die Verbindung in den Tests Ihrer TearDown zu schließen, das sollte es lösen. Wenn das nicht funktioniert, können Sie unset($this->app['db']) in jedem Test durchführen, der Laravels TestCase erweitert.

+0

Es könnte großartig sein, aber die 'setPdo' Methode akzeptiert nur eine Instanz von PDO als Argument ... –

+0

Yeah Taylor hat meine PR editiert, es scheint, ich habe eine Alternative zu der Antwort hinzugefügt, die ich gerade benutze. –

+1

Es funktioniert! Ich setzte 'unset ($ this-> app ['db'])' in meine träneDown und das wars. –