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 dash, quindi se include input dell’utente nascono problemi di quoting e rischi di injection. All’interno di un pacchetto, passa gli argomenti come array.
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.
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 conProcess::fake(). Process::result() permette di specificare output standard, output di errore e codice di uscita.
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 difake() 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, usapreventStrayProcesses(). 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 riceveIlluminate\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
- Documentazione ufficiale di Laravel: processi
- Documentazione ufficiale di Laravel: Process::fake e assertRan
- Process Factory: fake e assertRan
- PendingProcess: timeout predefiniti e corrispondenza dei fake
- ProcessResult: comportamento di throw()
- ProcessFailedException: struttura del messaggio
- Facade: cache e swap()