Vai al contenuto principale
Quando un pacchetto chiama comandi esterni come ffmpeg o git, le differenze di ambiente dell’applicazione che lo usa e gli errori diventano direttamente il comportamento del pacchetto. Invece di chiamare direttamente shell_exec() o exec(), esegui i comandi tramite la facade Process e sostituiscili con Process::fake() nei test.
Questa pagina riguarda Laravel 13 e verifica l’implementazione di Framework v13.42.0. Presuppone la conoscenza dei processi e dei test dei pacchetti. La corrispondenza dei comandi in array trattata qui si basa su come Symfony Process, usato internamente da Process, converte gli argomenti.

Perché evitare l’esecuzione diretta

Le chiamate dirette a funzioni non si possono sostituire nei test, e ogni chiamante gestisce timeout e codici di uscita in modo diverso. Passando dalla facade Process unifichi la registrazione delle esecuzioni, i fake, i timeout e le eccezioni in caso di errore.

Passa i comandi come array

Un comando in forma di stringa viene interpretato da sh, quindi se include input dell’utente nascono problemi di quoting e rischi di injection. All’interno di un pacchetto, passa gli argomenti come array.
Il timeout predefinito di PendingProcess è di 60 secondi e il timeout di inattività è null. Per conversioni lunghe imposta esplicitamente timeout(), e per elaborazioni il cui output può bloccarsi aggiungi idleTimeout().

Eccezioni e messaggi in caso di errore

ProcessResult::throw() lancia ProcessFailedException quando il codice di uscita non indica successo. Il messaggio contiene il comando eseguito, il codice di uscita, l’output standard e l’output di errore.
Se inserisci segreti negli argomenti del comando, finiscono nel messaggio di ProcessFailedException e possono comparire nei log o a schermo. Non passare token come argomenti. Passali con env() oppure scrivili nel file di configurazione del comando.
I timeout sono rappresentati da ProcessTimedOutException e i timeout di inattività da ProcessIdleTimedOutException. Documenta per gli utenti del pacchetto quali eccezioni lanci e cosa possono aspettarsi quando le intercettano.

Usa i fake nei test

Nei test, sostituisci i comandi esterni con Process::fake(). Process::result() permette di specificare output standard, output di errore e codice di uscita.
Passando una closure a assertRan() puoi verificare command, timeout, environment e altre proprietà di PendingProcess. I comandi in array vengono confrontati con $process->command per corrispondenza esatta, quindi i test rilevano modifiche all’ordine o ai valori degli argomenti.

Chiavi di fake per comandi in array

Internamente Process confronta le chiavi di fake() con il risultato di getCommandline() tramite Str::is(). I comandi in array vengono convertiti in una stringa con virgolette per la shell, quindi un pattern stringa come 'ffmpeg*' non corrisponde. Nei test di comandi in array usa uno dei seguenti approcci.

Impedire comandi esterni imprevisti

Per rilevare comandi esterni che non dovrebbero essere eseguiti nei test, usa preventStrayProcesses(). I comandi che non corrispondono a nessun fake generano una RuntimeException e non vengono realmente avviati.

Se usi una Factory iniettata

Se il costruttore del pacchetto riceve Illuminate\Process\Factory, verifica che lo stato di Process::fake() raggiunga l’istanza iniettata. La facade mette in cache l’istanza risolta e swap() sostituisce l’istanza nel container. Non puoi invece contare su una registrazione esplicita del framework perché Factory sia condivisa nel container, quindi verificalo in un test. Se il fake non raggiunge l’istanza iniettata, sostituisci esplicitamente la Factory nel test oppure progetta il pacchetto in modo che passi dalla facade Process. In entrambi i casi, verificare con assertRan() che la chiamata sia stata registrata permette di individuare una sostituzione dimenticata.

Verifiche da aggiungere per la manutenzione a lungo termine

Fonti primarie consultate

Ultima modifica il 13 novembre 2026