ffmpeg oder git aufruft, werden Unterschiede in der Umgebung der nutzenden Anwendung und Fehlschläge direkt zum Verhalten des Pakets. Rufen Sie shell_exec() oder exec() nicht direkt auf, sondern führen Sie Befehle über die Process-Facade aus und ersetzen Sie sie in Tests durch Process::fake().
Diese Seite richtet sich an Laravel 13 und prüft die Implementierung von Framework
v13.42.0. Sie setzt Prozesse und Pakete testen voraus. Der hier behandelte Abgleich von Array-Befehlen beruht darauf, wie Symfony Process, das Process intern verwendet, Argumente umwandelt.Warum Sie die direkte Ausführung vermeiden sollten
Direkte Funktionsaufrufe lassen sich in Tests nicht austauschen, und jeder Aufrufer behandelt Timeouts und Exit-Codes anders. Über die Process-Facade vereinheitlichen Sie das Protokollieren der Ausführung, Fakes, Timeouts und Exceptions bei Fehlschlägen.Befehle als Array übergeben
Ein Befehl als String wird vonsh interpretiert. Enthält er Benutzereingaben, entstehen Probleme mit Anführungszeichen und Raum für Injection. Übergeben Sie Argumente innerhalb eines Pakets als Array.
PendingProcess beträgt 60 Sekunden, der Idle-Timeout ist null. Setzen Sie bei langen Konvertierungen timeout() explizit und kombinieren Sie es bei Verarbeitungen, deren Ausgabe stocken kann, mit idleTimeout().
Exceptions und Meldungen bei Fehlschlägen
ProcessResult::throw() wirft eine ProcessFailedException, wenn der Exit-Code keinen Erfolg anzeigt. Die Meldung enthält den ausgeführten Befehl, den Exit-Code sowie die Standardausgabe und die Standardfehlerausgabe.
Timeouts werden durch ProcessTimedOutException dargestellt, Idle-Timeouts durch ProcessIdleTimedOutException. Dokumentieren Sie für die Nutzer Ihres Pakets, welche Exceptions Sie werfen und was sie beim Abfangen erwarten können.
In Tests faken
Ersetzen Sie externe Befehle in Tests durchProcess::fake(). Mit Process::result() legen Sie Standardausgabe, Standardfehlerausgabe und Exit-Code fest.
assertRan() eine Closure übergeben, können Sie command, timeout, environment und weitere Eigenschaften von PendingProcess prüfen. Array-Befehle werden mit $process->command auf exakte Gleichheit verglichen, sodass Tests Änderungen an Reihenfolge oder Werten der Argumente erkennen.
Fake-Schlüssel für Array-Befehle
Intern gleicht Process die Schlüssel vonfake() mit Str::is() gegen das Ergebnis von getCommandline() ab. Array-Befehle werden in einen für die Shell in Anführungszeichen gesetzten String umgewandelt, daher passt ein String-Muster wie 'ffmpeg*' nicht. Verwenden Sie in Tests für Array-Befehle eine der folgenden Möglichkeiten.
Unerwartete externe Befehle verhindern
Um externe Befehle zu erkennen, die in Tests nicht ausgeführt werden sollen, verwenden SiepreventStrayProcesses(). Befehle, die zu keinem Fake passen, führen zu einer RuntimeException und werden nicht tatsächlich gestartet.
Wenn Sie eine injizierte Factory verwenden
Wenn der Konstruktor Ihres PaketsIlluminate\Process\Factory entgegennimmt, prüfen Sie, ob der Zustand von Process::fake() bis zur injizierten Instanz reicht. Die Facade cacht die aufgelöste Instanz, und swap() ersetzt die Instanz im Container. Ob Factory im Container geteilt wird, können Sie dagegen nicht einer expliziten Registrierung durch das Framework überlassen. Prüfen Sie es daher tatsächlich in einem Test.
Reicht der Fake nicht bis zur injizierten Instanz, tauschen Sie die Factory im Test explizit aus oder gestalten Sie das Paket so, dass es über die Process-Facade läuft. Prüfen Sie in beiden Fällen mit assertRan(), dass der Aufruf protokolliert wurde. So erkennen Sie einen vergessenen Austausch.
Zusätzliche Prüfungen für die langfristige Wartung
Verwendete Primärquellen
- Offizielle Laravel-Dokumentation: Prozesse
- Offizielle Laravel-Dokumentation: Process::fake und assertRan
- Process Factory: fake und assertRan
- PendingProcess: Standard-Timeouts und Abgleich von Fakes
- ProcessResult: Verhalten von throw()
- ProcessFailedException: Aufbau der Meldung
- Facade: Caching und swap()