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

Symfony控制器调用自定义命令时单元测试未执行问题求助

问题描述

通过Symfony控制器调用自定义命令时,命令立即返回[OK] success,但实际并未执行单元测试。该命令在CLI中运行正常,单元测试本身也能正常执行,且无任何报错信息。

控制器代码

<?php

namespace App\Controller\Api;

use OpenApi\Annotations as OA;
use Symfony\Component\Console\Output\ConsoleOutput;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\KernelInterface;
use Symfony\Component\Process\Process;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Bundle\FrameworkBundle\Console\Application;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Output\BufferedOutput;


class UnitTestController extends AbstractController
{
    private $kernel;

    public function __construct(KernelInterface $kernel)
    {
        $this->kernel = $kernel;
    }
    #[Route('/unit_tests', name: 'unit_test', methods: 'GET')]
    public function unitTest(): Response
    {
        $application = new Application($this->kernel);
        $application->setAutoExit(false);

        $input = new ArrayInput([
            'command' => 'mapi:unitTests',
        ]);
        $output = new BufferedOutput();
        $application->run($input, $output);

        $content = $output->fetch();
        dd($content);
    }
}

自定义命令代码

<?php

namespace App\Command;

use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Component\Process\Process;
use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\DecodingExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;

#[AsCommand(
    name: 'mapi:unitTests',
    description: 'lancement des tests unitaires',
)]
class unitTestCommand extends Command
{
    /**
     * @param InputInterface $input
     * @param OutputInterface $output
     * @return int
     * @throws ClientExceptionInterface
     * @throws DecodingExceptionInterface
     * @throws RedirectionExceptionInterface
     * @throws ServerExceptionInterface
     */
    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $io = new SymfonyStyle($input, $output);
        ini_set('max_execution_time', 300);
        $process = Process::fromShellCommandline('php vendor/bin/phpunit');
        $process->run();
        $io->success('success');

        return Command::SUCCESS;
    }
}
解决方案

1. 修正工作目录

Web服务器的工作目录通常不是项目根目录,导致找不到phpunit脚本。需要指定Process的工作目录为Symfony项目根目录:

// 在命令类中获取项目目录参数
$projectDir = $this->getContainer()->getParameter('kernel.project_dir');
$process = Process::fromShellCommandline('php vendor/bin/phpunit', $projectDir);

2. 添加执行状态检查

当前代码未验证phpunit是否成功执行,直接返回success。添加错误处理逻辑:

$process->run();

// 检查进程执行状态
if (!$process->isSuccessful()) {
    $io->error('单元测试执行失败:' . $process->getErrorOutput());
    return Command::FAILURE;
}

// 输出phpunit的执行结果到命令行输出
$io->write($process->getOutput());
$io->success('success');

3. 检查Web服务器权限

确保运行Web服务器的用户(如www-data)拥有项目目录的读写权限,特别是vendor目录和测试文件所在目录。可以通过以下命令调整权限(根据实际情况修改):

chown -R www-data:www-data /path/to/your/project
chmod -R 755 /path/to/your/project

4. 指定PHP绝对路径

Web环境中php命令的路径可能与CLI环境不同,使用绝对路径指定PHP二进制文件:

// 替换为服务器上实际的PHP路径,比如/usr/bin/php
$process = Process::fromShellCommandline('/usr/bin/php vendor/bin/phpunit', $projectDir);

内容的提问来源于stack exchange,提问作者lataix.sebastien

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 07:45:19