You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在前端运行Laravel Dusk测试用例并展示结果?

解决Laravel Dusk通过Web触发执行的问题

核心问题拆解

你需要通过页面按钮触发指定Laravel Dusk测试用例,在浏览器展示结果,但遇到两个关键问题:

  • 用exec()/shell_exec()执行Dusk命令时,出现WebDriver Curl连接错误
  • 调用Artisan::call('dusk')提示命令不存在,而本地命令行执行完全正常

解决方案

1. 修复Artisan::call找不到dusk命令的问题

Dusk的Artisan命令默认仅在local或testing环境加载,若Web环境未正确加载Dusk服务提供者,就会出现命令不存在的错误。

  • 步骤1:注册Dusk服务提供者
    打开config/app.php,在providers数组中添加:

    Laravel\Dusk\DuskServiceProvider::class,
    

    或在App\Providers\AppServiceProvider的register方法中条件加载(推荐,避免生产环境加载):

    public function register()
    {
        if ($this->app->environment('local')) {
            $this->app->register(\Laravel\Dusk\DuskServiceProvider::class);
        }
    }
    
  • 步骤2:清理配置缓存
    执行命令刷新配置:

    php artisan config:cache
    

2. 解决exec/shell_exec的WebDriver Curl错误

这个错误本质是Web服务器进程(如www-data)的权限或环境变量与命令行用户不一致导致的。

  • 指定完整路径与捕获错误输出
    执行命令时必须指定PHP和Artisan的完整路径,并捕获错误输出方便排查:

    $testFilter = 'YourTestClassName'; // 替换为你的测试类名
    $command = sprintf(
        '/usr/bin/php %s artisan dusk:test --filter=%s 2>&1',
        base_path(),
        $testFilter
    );
    $result = shell_exec($command);
    

    这里2>&1会把错误信息合并到标准输出,便于查看具体问题。

  • 配置ChromeDriver参数适配Web进程
    在tests/DuskTestCase.php的driver方法中添加关键参数,解决Web进程的权限限制:

    protected function driver()
    {
        $options = (new \Laravel\Dusk\ChromeOptions)->addArguments([
            '--headless',
            '--no-sandbox', // 必须添加,Web用户无沙箱权限
            '--disable-dev-shm-usage',
            '--disable-gpu',
        ]);
    
        return \Facebook\WebDriver\Remote\RemoteWebDriver::create(
            'http://localhost:9515',
            \Facebook\WebDriver\Remote\DesiredCapabilities::chrome()->setCapability(
                \Laravel\Dusk\ChromeOptions::CAPABILITY,
                $options
            )
        );
    }
    
  • 确保Web进程能访问ChromeDriver
    若ChromeDriver不在系统PATH中,执行命令时指定其路径:

    $command = sprintf(
        'DUSK_DRIVER_PATH=/path/to/your/chromedriver /usr/bin/php %s artisan dusk:test --filter=%s 2>&1',
        base_path(),
        $testFilter
    );
    

3. 异步执行与结果展示(避免页面超时)

直接同步执行Dusk测试会导致页面长时间等待甚至超时,建议用队列异步处理:

  • 创建执行测试的Job
    生成RunDuskTestJob:

    php artisan make:job RunDuskTestJob
    

    编写Job逻辑:

    namespace App\Jobs;
    
    use Illuminate\Bus\Queueable;
    use Illuminate\Contracts\Queue\ShouldQueue;
    use Illuminate\Foundation\Bus\Dispatchable;
    use Illuminate\Queue\InteractsWithQueue;
    use Illuminate\Queue\SerializesModels;
    use Illuminate\Support\Facades\Storage;
    
    class RunDuskTestJob implements ShouldQueue
    {
        use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
    
        protected $testClass;
    
        public function __construct(string $testClass)
        {
            $this->testClass = $testClass;
        }
    
        public function handle()
        {
            // 构建执行命令
            $command = sprintf(
                'DUSK_DRIVER_PATH=/usr/local/bin/chromedriver /usr/bin/php %s artisan dusk:test --filter=%s 2>&1',
                base_path(),
                $this->testClass
            );
            $output = shell_exec($command);
    
            // 将测试结果存储到storage目录
            $fileName = sprintf('dusk-results/%s-%s.txt', $this->testClass, time());
            Storage::put($fileName, $output);
        }
    }
    
  • 前端触发与轮询结果
    页面按钮点击时,通过AJAX调用接口推送Job:

    // routes/web.php
    Route::post('/run-dusk-test', function (\Illuminate\Http\Request $request) {
        \App\Jobs\RunDuskTestJob::dispatch($request->input('test_class'));
        return response()->json(['status' => 'pending', 'message' => '测试已启动']);
    });
    

    前端轮询接口获取结果文件内容,展示在页面上:

    // 示例JS代码
    function checkTestResult(testClass) {
        fetch(`/get-dusk-result?test_class=${testClass}`)
            .then(res => res.text())
            .then(data => {
                document.getElementById('test-result').innerText = data;
                setTimeout(() => checkTestResult(testClass), 3000); // 每3秒轮询一次
            });
    }
    

4. 关键权限检查

  • 确保Web服务器用户(www-data)拥有项目目录的读写权限,尤其是storage和bootstrap/cache目录
  • 若使用Homestead/Valet,注意Web进程与命令行用户的环境变量差异,比如PHP版本、ChromeDriver路径

内容的提问来源于stack exchange,提问作者Ketan Modi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 23:59:58