ffmpeg o git, las diferencias de entorno de la aplicación que lo usa y los fallos se convierten directamente en el comportamiento del paquete. En lugar de llamar directamente a shell_exec() o exec(), ejecuta los comandos con la facade Process y sustitúyelos con Process::fake() en las pruebas.
Esta página se centra en Laravel 13 y revisa la implementación de Framework
v13.42.0. Da por conocidos los procesos y las pruebas de paquetes. La coincidencia de comandos en array que se trata aquí se basa en cómo Symfony Process, que Process usa internamente, convierte los argumentos.Por qué evitar la ejecución directa
Las llamadas directas a funciones no se pueden sustituir en las pruebas, y cada llamador gestiona los timeouts y los códigos de salida de forma distinta. Si pasas por la facade Process, unificas el registro de ejecuciones, los fakes, los timeouts y las excepciones en caso de fallo.Pasa los comandos como array
Un comando en forma de string pasa por la interpretación desh, así que si incluye datos del usuario aparecen problemas con las comillas y riesgo de inyección. Dentro del paquete, pasa los argumentos como array.
PendingProcess es de 60 segundos y el timeout de inactividad es null. Para conversiones largas indica timeout() de forma explícita y, en procesos cuya salida puede detenerse, combínalo con idleTimeout().
Excepciones y mensajes en caso de fallo
ProcessResult::throw() lanza ProcessFailedException cuando el código de salida no indica éxito. El mensaje incluye el comando ejecutado, el código de salida y las salidas estándar y de error.
Los timeouts se representan con ProcessTimedOutException y los timeouts de inactividad con ProcessIdleTimedOutException. Documenta para los usuarios del paquete qué excepciones lanzas y qué pueden esperar al capturarlas.
Usa fakes en las pruebas
En las pruebas, sustituye los comandos externos conProcess::fake(). Process::result() permite indicar la salida estándar, la salida de error y el código de salida.
assertRan(), puedes comprobar command, timeout, environment y otras propiedades de PendingProcess. Los comandos en array se comparan con $process->command por coincidencia exacta, así que las pruebas detectan cambios en el orden o en los valores de los argumentos.
Claves de fake para comandos en array
Internamente, Process compara las claves defake() con el resultado de getCommandline() usando Str::is(). Los comandos en array se convierten en un string con comillas para la shell, así que un patrón de string como 'ffmpeg*' no coincide. En las pruebas de comandos en array, usa una de estas opciones.
Evita comandos externos inesperados
Para detectar comandos externos que no deberían ejecutarse en las pruebas, usapreventStrayProcesses(). Los comandos que no coinciden con ningún fake lanzan RuntimeException y no llegan a iniciarse.
Si usas una Factory inyectada
Si el constructor del paquete recibeIlluminate\Process\Factory, comprueba que el estado de Process::fake() llega hasta la instancia inyectada. La facade guarda en caché la instancia resuelta y swap() reemplaza la instancia en el contenedor. En cambio, no puedes confiar en que el framework registre explícitamente Factory como compartida en el contenedor, así que compruébalo en una prueba.
Si el fake no llega a la instancia inyectada, sustituye la Factory de forma explícita en la prueba o diseña el paquete para que pase por la facade Process. En ambos casos, comprobar con assertRan() que la llamada quedó registrada te permite detectar una sustitución olvidada.
Comprobaciones para el mantenimiento a largo plazo
Fuentes primarias consultadas
- Documentación oficial de Laravel: procesos
- Documentación oficial de Laravel: Process::fake y assertRan
- Process Factory: fake y assertRan
- PendingProcess: timeouts por defecto y coincidencia de fakes
- ProcessResult: comportamiento de throw()
- ProcessFailedException: estructura del mensaje
- Facade: caché y swap()