gpt4 book ai didi

PhpStorm v2017.3.4 与 Codeception v2.4.0 不兼容

转载 作者:行者123 更新时间:2023-12-02 19:30:28 24 4
gpt4 key购买 nike

我正在努力使代码接收与 PhpStorm 一起工作。

我已经设置了 CLI 解释器:

enter image description here

enter image description here

我还设置了 Codeception:

enter image description here

这是 Codeception 的配置:

enter image description here

当我从 PhpStorm 运行测试时,我收到以下信息:

左边:

enter image description here

以及右侧的文字:

Testing started at 00:06 ...
/Applications/MAMP/bin/php/php7.2.1/bin/php /private/var/folders/3g/xng_tnzj6797frqqk20r69mw0000gn/T/ide-codeception.php run --report -o "reporters: report: PhpStorm_Codeception_ReportPrinter" --no-ansi --no-interaction unit

Process finished with exit code 255

但是当我在终端上的项目文件夹中运行 concept run 时,它工作正常并且我收到以下消息:

enter image description here

我做错了什么?我真的阅读了PhpStorm的手册here和 youtube 上的视频,但我无法使其工作:/

谢谢!

更新:

经过进一步调查,我发现了以下内容:

$ /usr/bin/env php --version                                                                                                                                                                                     
PHP 7.2.1 (cli) (built: Jan 15 2018 12:20:50) ( NTS )
Copyright (c) 1997-2017 The PHP Group
Zend Engine v3.2.0, Copyright (c) 1998-2017 Zend Technologies

$ php --version
PHP 7.2.1 (cli) (built: Jan 15 2018 12:20:50) ( NTS )
Copyright (c) 1997-2017 The PHP Group
Zend Engine v3.2.0, Copyright (c) 1998-2017 Zend Technologies
with Zend OPcache v7.2.1, Copyright (c) 1999-2017, by Zend Technologies
with Xdebug v2.6.0beta1, Copyright (c) 2002-2017, by Derick Rethans

$ /usr/bin/env php -c "/Library/Application Support/appsolute/MAMP PRO/conf/php7.2.1.ini" --version
PHP 7.2.1 (cli) (built: Jan 15 2018 12:20:50) ( NTS )
Copyright (c) 1997-2017 The PHP Group
Zend Engine v3.2.0, Copyright (c) 1998-2017 Zend Technologies
with Zend OPcache v7.2.1, Copyright (c) 1999-2017, by Zend Technologies
with Xdebug v2.6.0beta1, Copyright (c) 2002-2017, by Derick Rethans

$ cat .zprofile | grep "alias php="
alias php='/Applications/MAMP/bin/php/php7.2.1/bin/php -c "/Library/Application Support/appsolute/MAMP PRO/conf/php7.2.1.ini"'

更新2:

虽然这解决了我在终端上使用代码覆盖标志 --coverage 运行时遇到的代码接收问题:

$ which php
php: aliased to /Applications/MAMP/bin/php/php7.2.1/bin/php -c '/Library/Application Support/appsolute/MAMP PRO/conf/php7.2.1.ini'

$ /usr/bin/env php -i | grep "Loaded Configuration File"
Loaded Configuration File => /Applications/MAMP/bin/php/php7.2.1/conf/php.ini

$ mv /Applications/MAMP/bin/php/php7.2.1/conf/php.ini /Applications/MAMP/bin/php/php7.2.1/conf/php.bk.ini

$ ln -s "/Library/Application Support/appsolute/MAMP PRO/conf/php7.2.1.ini" /Applications/MAMP/bin/php/php7.2.1/conf/php.ini

$ /usr/bin/env php --version
PHP 7.2.1 (cli) (built: Jan 15 2018 12:20:50) ( NTS )
Copyright (c) 1997-2017 The PHP Group
Zend Engine v3.2.0, Copyright (c) 1998-2017 Zend Technologies
with Zend OPcache v7.2.1, Copyright (c) 1999-2017, by Zend Technologies
with Xdebug v2.6.0beta1, Copyright (c) 2002-2017, by Derick Rethans

现在我在 PhpStorm 上收到以下消息:

Testing started at 15:55 ...
/Applications/MAMP/bin/php/php7.2.1/bin/php /private/var/folders/3g/xng_tnzj6797frqqk20r69mw0000gn/T/ide-codeception.php run --report -o "reporters: report: PhpStorm_Codeception_ReportPrinter" --no-ansi --no-interaction

Fatal error: Class 'PHPUnit_TextUI_ResultPrinter' not found in /private/var/folders/3g/xng_tnzj6797frqqk20r69mw0000gn/T/ide-codeception.php on line 22

Call Stack:
0.0222 528280 1. {main}() /private/var/folders/3g/xng_tnzj6797frqqk20r69mw0000gn/T/ide-codeception.php:0


Process finished with exit code 255

这是我的 composer.json 文件中的 "require-dev" 的一部分

  "require-dev": {
"codeception/codeception": "^2.4"
},

基于 fatal error :未找到“PHPUnit_TextUI_ResultPrinter”类,并查看类名PHPUnit_TextUI_ResultPrinter而不是PHPUnit\TextUI\ResultPrinter一点,我怀疑codeception 2.4使用的phpunit版本比PhpStorm所需的版本新?也许需要 phpunit v6?

谢谢!

更新3:

我现在可以确认 PhpStorm v2017.3.4 与 Codeception 2.4 不兼容,因为后者在 v2.4.0 迁移到 PHPUnit v7.x 后,PhpStorm v2017.3.4 似乎还不兼容。运行后:

$ composer remove codeception/codeception
$ composer require codeception/codeception:2.3.9 --dev

我在 PhpStorm 上得到以下信息:

enter image description here

最佳答案

经过更多研究,我解决了我的问题。

简单步骤:

$ cd /Applications/PhpStorm.app/Contents/plugins/codeception/lib

$ ls
codeception.jar resources_en.jar

$ mv codeception.jar codeception.zip

$ unzip codeception.zip -d codeception

$ rm codeception.zip

$ cd codeception

$ vim scripts/codeception.php

$ zip -r ../codeception.zip *

$ cd ..

$ mv codeception.zip codeception.jar

$ rm -r codeception/

您可以使用您喜欢的任何其他文本编辑器代替 vimscripts/codeception.php,并将内容替换为以下内容:

<?php

if (!isset($_SERVER['IDE_CODECEPTION_EXE'])) {
fwrite(STDERR, "The value of Codeception executable is not specified" . PHP_EOL);
exit(1);
}

$exe = realpath($_SERVER['IDE_CODECEPTION_EXE']);
if (!file_exists($exe)) {
$originalPath = $_SERVER['IDE_CODECEPTION_EXE'];
fwrite(STDERR, "The value of Codeception executable is specified, but file doesn't exist '$originalPath'" . PHP_EOL);
exit(1);
}

if (Phar::isValidPharFilename(basename($exe), true)) {
require_once 'phar://' . $exe . '/autoload.php';
}
else {
require_once dirname($exe) .'/autoload.php';
}


class PhpStorm_Codeception_ReportPrinter extends \PHPUnit\TextUI\ResultPrinter
{
protected $testStatus = \PHPUnit\Runner\BaseTestRunner::STATUS_PASSED;

protected $failures = [];

/**
* @var bool
*/
private $isSummaryTestCountPrinted = false;

/**
* @var string
*/
private $startedTestName;

/**
* @var string
*/
private $flowId;

/**
* @param string $progress
*/
protected function writeProgress($progress): void
{
}

/**
* @param \PHPUnit\Framework\TestResult $result
*/
public function printResult(\PHPUnit\Framework\TestResult $result) : void
{
$this->printHeader();
$this->printFooter($result);
}

/**
* An error occurred.
*
* @param \PHPUnit\Framework\Test $test
* @param \Throwable $e
* @param float $time
*/
public function addError(\PHPUnit\Framework\Test $test, \Throwable $e, float $time): void
{
$this->addFail(\PHPUnit\Runner\BaseTestRunner::STATUS_ERROR, $test, $e);
}

/**
* A warning occurred.
*
* @param \PHPUnit\Framework\Test $test
* @param \PHPUnit\Framework\Warning $e
* @param float $time
*
* @since Method available since Release 5.1.0
*/
public function addWarning(\PHPUnit\Framework\Test $test, \PHPUnit\Framework\Warning $e, float $time): void
{
$this->addFail(\PHPUnit\Runner\BaseTestRunner::STATUS_ERROR, $test, $e);
}

/**
* A failure occurred.
*
* @param \PHPUnit\Framework\Test $test
* @param \PHPUnit\Framework\AssertionFailedError $e
* @param float $time
*/
public function addFailure(\PHPUnit\Framework\Test $test, \PHPUnit\Framework\AssertionFailedError $e, float $time): void
{
$parameters = [];
if ($e instanceof \PHPUnit\Framework\ExpectationFailedException) {
$comparisonFailure = $e->getComparisonFailure();

if ($comparisonFailure instanceof \SebastianBergmann\Comparator\ComparisonFailure) {
$expectedString = $comparisonFailure->getExpectedAsString();

if (is_null($expectedString) || empty($expectedString)) {
$expectedString = self::getPrimitiveValueAsString($comparisonFailure->getExpected());
}

$actualString = $comparisonFailure->getActualAsString();

if (is_null($actualString) || empty($actualString)) {
$actualString = self::getPrimitiveValueAsString($comparisonFailure->getActual());
}

if (!is_null($actualString) && !is_null($expectedString)) {
$parameters['type'] = 'comparisonFailure';
$parameters['actual'] = $actualString;
$parameters['expected'] = $expectedString;
}
}
}

$this->addFail(\PHPUnit\Runner\BaseTestRunner::STATUS_ERROR, $test, $e, $parameters);
}

/**
* Incomplete test.
*
* @param \PHPUnit\Framework\Test $test
* @param \Throwable $e
* @param float $time
*/
public function addIncompleteTest(\PHPUnit\Framework\Test $test, \Throwable $e, float $time): void
{
$this->addIgnoredTest($test, $e);
}

/**
* Risky test.
*
* @param \PHPUnit\Framework\Test $test
* @param \Throwable $e
* @param float $time
*/
public function addRiskyTest(\PHPUnit\Framework\Test $test, \Throwable $e, float $time): void
{
$this->addError($test, $e, $time);
}

/**
* Skipped test.
*
* @param \PHPUnit\Framework\Test $test
* @param \Throwable $e
* @param float $time
*/
public function addSkippedTest(\PHPUnit\Framework\Test $test, \Throwable $e, float $time): void
{
$testName = self::getTestAsString($test);
if ($this->startedTestName != $testName) {
$this->startTest($test);
$this->printEvent(
'testIgnored',
[
'name' => $testName,
'message' => self::getMessage($e),
'details' => self::getDetails($e),
]
);
$this->endTest($test, $time);
} else {
$this->addIgnoredTest($test, $e);
}
}

public function addIgnoredTest(\PHPUnit\Framework\Test $test, Exception $e) {
$this->addFail(\PHPUnit\Runner\BaseTestRunner::STATUS_SKIPPED, $test, $e);
}

private function addFail($status, \PHPUnit\Framework\Test $test, $e, $parameters = []) {
$key = self::getTestSignature($test);
$this->testStatus = $status;
$parameters['message'] = self::getMessage($e);
$parameters['details'] = self::getDetails($e);

$this->failures[$key][] = $parameters;
}

/**
* A testsuite started.
*
* @param \PHPUnit\Framework\TestSuite $suite
*/
public function startTestSuite(\PHPUnit\Framework\TestSuite $suite): void
{
if (stripos(ini_get('disable_functions'), 'getmypid') === false) {
$this->flowId = getmypid();
} else {
$this->flowId = false;
}

if (!$this->isSummaryTestCountPrinted) {
$this->isSummaryTestCountPrinted = true;

$this->printEvent(
'testCount',
['count' => count($suite)]
);
}

$suiteName = $suite->getName();

if (empty($suiteName)) {
return;
}

//TODO: configure 'locationHint' to navigate to 'unit', 'acceptance', 'functional' test suite
//TODO: configure 'locationHint' to navigate to DataProvider tests for Codeception earlier 2.2.6
$parameters = ['name' => $suiteName];
$this->printEvent('testSuiteStarted', $parameters);
}

/**
* A testsuite ended.
*
* @param \PHPUnit\Framework\TestSuite $suite
*/
public function endTestSuite(\PHPUnit\Framework\TestSuite $suite): void
{
$suiteName = $suite->getName();

if (empty($suiteName)) {
return;
}

$parameters = ['name' => $suiteName];
$this->printEvent('testSuiteFinished', $parameters);
}

public static function getTestSignature(\PHPUnit\Framework\SelfDescribing $testCase)
{
if ($testCase instanceof Codeception\Test\Interfaces\Descriptive) {
return $testCase->getSignature();
}
if ($testCase instanceof \PHPUnit\Framework\TestCase) {
return get_class($testCase) . ':' . $testCase->getName(false);
}
return $testCase->toString();
}

public static function getTestAsString(\PHPUnit\Framework\SelfDescribing $testCase)
{
if ($testCase instanceof Codeception\Test\Interfaces\Descriptive) {
return $testCase->toString();
}
if ($testCase instanceof \PHPUnit\Framework\TestCase) {
$text = $testCase->getName();
$text = preg_replace('/([A-Z]+)([A-Z][a-z])/', '\\1 \\2', $text);
$text = preg_replace('/([a-z\d])([A-Z])/', '\\1 \\2', $text);
$text = preg_replace('/^test /', '', $text);
$text = ucfirst(strtolower($text));
$text = str_replace(['::', 'with data set'], [':', '|'], $text);
return Codeception\Util\ReflectionHelper::getClassShortName($testCase) . ': ' . $text;
}
return $testCase->toString();
}

public static function getTestFileName(\PHPUnit\Framework\SelfDescribing $testCase)
{
if ($testCase instanceof Codeception\Test\Interfaces\Descriptive) {
return $testCase->getFileName();
}
return (new \ReflectionClass($testCase))->getFileName();
}

public static function getTestFullName(\PHPUnit\Framework\SelfDescribing $testCase)
{
if ($testCase instanceof Codeception\Test\Interfaces\Plain) {
return self::getTestFileName($testCase);
}
if ($testCase instanceof Codeception\Test\Interfaces\Descriptive) {
$signature = $testCase->getSignature(); // cut everything before ":" from signature
return self::getTestFileName($testCase) . '::' . preg_replace('~^(.*?):~', '', $signature);
}
if ($testCase instanceof \PHPUnit\Framework\TestCase) {
return self::getTestFileName($testCase) . '::' . $testCase->getName(false);
}
return self::getTestFileName($testCase) . '::' . $testCase->toString();
}

/**
* A test started.
*
* @param \PHPUnit\Framework\Test $test
*/
public function startTest(\PHPUnit\Framework\Test $test): void
{
$testName = self::getTestAsString($test);
$this->startedTestName = $testName;
$location = "php_qn://" . self::getTestFullName($test);
$gherkin = self::getGherkinTestLocation($test);
if ($gherkin != null) {
$location = $gherkin;
}
$params = ['name' => $testName, 'locationHint' => $location];

if ($test instanceof \Codeception\Test\Interfaces\ScenarioDriven) {
$this->printEvent('testSuiteStarted', $params);
}
else {
$this->printEvent('testStarted', $params);
}
}

/**
* A test ended.
*
* @param \PHPUnit\Framework\Test $test
* @param float $time
*/
public function endTest(\PHPUnit\Framework\Test $test, float $time): void
{
$result = null;
switch ($this->testStatus) {
case \PHPUnit\Runner\BaseTestRunner::STATUS_ERROR:
case \PHPUnit\Runner\BaseTestRunner::STATUS_FAILURE:
$result = 'testFailed';
break;
case \PHPUnit\Runner\BaseTestRunner::STATUS_SKIPPED:
$result = 'testIgnored';
break;
}

$name = self::getTestAsString($test);
if ($this->startedTestName != $name) {
$name = $this->startedTestName;
}
$gherkin = self::getGherkinTestLocation($test);
$duration = (int)(round($time, 2) * 1000);
if ($test instanceof \Codeception\Test\Interfaces\ScenarioDriven) {
$steps = $test->getScenario()->getSteps();
$len = sizeof($steps);
$printed = 0;
for ($i = 0; $i < $len; $i++) {
$step = $steps[$i];
if ($step->getAction() == null && $step->getMetaStep()) {
$step = $step->getMetaStep();
}

if ($step instanceof \Codeception\Step\Comment) {
// TODO: render comments in grey color?
// comments are not shown because at the moment it's hard to distinguish them from real tests.
// e.g. comment steps show descriptions from *.feature tests.
continue;
}
$printed++;
$testName = sprintf('%s %s %s',
ucfirst($step->getPrefix()),
$step->getHumanizedActionWithoutArguments(),
$step->getHumanizedArguments()
);

$location = $gherkin != null ? $gherkin : $step->getLine();
$this->printEvent('testStarted',
[
'name' => $testName,
'locationHint' => "file://$location"
]);

$params = ['name' => $testName];
if ($i == $len - 1) {
parent::endTest($test, $time);
$this->printError($test, $result, $testName);
$params['duration'] = $duration;
}
$this->printEvent('testFinished', $params);
}

if ($printed == 0 && $result != null) {
$this->printEvent('testStarted', ['name' => $name]);
parent::endTest($test, $time);
$this->printError($test, $result, $name);
$this->printEvent('testFinished', [
'name' => $name,
'duration' => $duration
]);
}

$this->printEvent('testSuiteFinished', ['name' => $name]);
}
else {
parent::endTest($test, $time);
$this->printError($test, $result, self::getTestAsString($test));

$this->printEvent(
'testFinished',
[
'name' => self::getTestAsString($test),
'duration' => $duration
]
);
}
}

private function printError(\PHPUnit\Framework\Test $test, $result, $name) {
if ($result != null) {
$this->testStatus = \PHPUnit\Runner\BaseTestRunner::STATUS_PASSED;
$key = self::getTestSignature($test);
if (isset($this->failures[$key])) {
$failures = $this->failures[$key];
//TODO: check if it's possible to have sizeof($params) > 1
assert(sizeof($failures) == 1);

$params = $failures[0];
$params['name'] = $name;
$this->printEvent($result, $params);
unset($this->failures[$key]);
}
}
}

/**
* @param string $eventName
* @param array $params
*/
private function printEvent($eventName, $params = [])
{
$this->write("\n##teamcity[$eventName");

if ($this->flowId) {
$params['flowId'] = $this->flowId;
}

foreach ($params as $key => $value) {
$escapedValue = self::escapeValue($value);
$this->write(" $key='$escapedValue'");
}

$this->write("]\n");
}

private static function getGherkinTestLocation(\PHPUnit\Framework\Test $test) {
if ($test instanceof \Codeception\Test\Gherkin) {
$feature = $test->getFeatureNode();
$scenario = $test->getScenarioNode();
if ($feature != null && $scenario != null) {
return "file://" . $test->getFeatureNode()->getFile() . ":" . $test->getScenarioNode()->getLine();
}
}
return null;
}

/**
* @param Exception $e
*
* @return string
*/
private static function getMessage(Exception $e)
{
$message = '';

if (!$e instanceof \PHPUnit\Framework\Exception) {
if (strlen(get_class($e)) != 0) {
$message = $message . get_class($e);
}

if (strlen($message) != 0 && strlen($e->getMessage()) != 0) {
$message = $message . ' : ';
}
}

return $message . $e->getMessage();
}

/**
* @param Exception $e
*
* @return string
*/
private static function getDetails(Exception $e)
{
$stackTrace = \PHPUnit\Util\Filter::getFilteredStacktrace($e);
$previous = $e->getPrevious();

while ($previous) {
$stackTrace .= "\nCaused by\n" .
\PHPUnit\Framework\TestFailure::exceptionToString($previous) . "\n" .
\PHPUnit\Util\Filter::getFilteredStacktrace($previous);

$previous = $previous->getPrevious();
}

return ' ' . str_replace("\n", "\n ", $stackTrace);
}

/**
* @param mixed $value
*
* @return string
*/
private static function getPrimitiveValueAsString($value)
{
if (is_null($value)) {
return 'null';
} elseif (is_bool($value)) {
return $value == true ? 'true' : 'false';
} elseif (is_scalar($value)) {
return print_r($value, true);
}

return;
}

/**
* @param $text
*
* @return string
*/
private static function escapeValue($text)
{
$text = str_replace('|', '||', $text);
$text = str_replace("'", "|'", $text);
$text = str_replace("\n", '|n', $text);
$text = str_replace("\r", '|r', $text);
$text = str_replace(']', '|]', $text);
$text = str_replace('[', '|[', $text);

return $text;
}

/**
* @param string $className
*
* @return string
*/
private static function getFileName($className)
{
$reflectionClass = new ReflectionClass($className);
$fileName = $reflectionClass->getFileName();

return $fileName;
}
}


$app = new \Codeception\Application('Codeception', \Codeception\Codecept::VERSION);

if (version_compare(\Codeception\Codecept::VERSION, "2.2.6") >= 0) {
$app->add(new \Codeception\Command\Run('run'));
$app->run();
}
else {
class PhpStorm_Codeception_Command_Run extends \Codeception\Command\Run {

public function execute(\Symfony\Component\Console\Input\InputInterface $input,
\Symfony\Component\Console\Output\OutputInterface $output)
{
$this->ensureCurlIsAvailable();
$this->options = $input->getOptions();
$this->output = $output;

$config = \Codeception\Configuration::config($this->options['config']);

if (!$this->options['colors']) {
$this->options['colors'] = $config['settings']['colors'];
}
if (!$this->options['silent']) {
$this->output->writeln(
\Codeception\Codecept::versionString() . "\nPowered by " . \PHPUnit\Runner\Version::getVersionString()
);
}
if ($this->options['debug']) {
$this->output->setVerbosity(\Symfony\Component\Console\Output\OutputInterface::VERBOSITY_VERY_VERBOSE);
}

$userOptions = array_intersect_key($this->options, array_flip($this->passedOptionKeys($input)));
$userOptions = array_merge(
$userOptions,
$this->booleanOptions($input, ['xml', 'html', 'json', 'tap', 'coverage', 'coverage-xml', 'coverage-html'])
);
$userOptions['verbosity'] = $this->output->getVerbosity();
$userOptions['interactive'] = !$input->hasParameterOption(['--no-interaction', '-n']);
$userOptions['ansi'] = (!$input->hasParameterOption('--no-ansi') xor $input->hasParameterOption('ansi'));

if ($this->options['no-colors'] || !$userOptions['ansi']) {
$userOptions['colors'] = false;
}
if ($this->options['group']) {
$userOptions['groups'] = $this->options['group'];
}
if ($this->options['skip-group']) {
$userOptions['excludeGroups'] = $this->options['skip-group'];
}
if ($this->options['report']) {
$userOptions['silent'] = true;
}
if ($this->options['coverage-xml'] or $this->options['coverage-html'] or $this->options['coverage-text']) {
$this->options['coverage'] = true;
}
if (!$userOptions['ansi'] && $input->getOption('colors')) {
$userOptions['colors'] = true; // turn on colors even in non-ansi mode if strictly passed
}

$suite = $input->getArgument('suite');
$test = $input->getArgument('test');

if (! \Codeception\Configuration::isEmpty() && ! $test && strpos($suite, $config['paths']['tests']) === 0) {
list(, $suite, $test) = $this->matchTestFromFilename($suite, $config['paths']['tests']);
}

if ($this->options['group']) {
$this->output->writeln(sprintf("[Groups] <info>%s</info> ", implode(', ', $this->options['group'])));
}
if ($input->getArgument('test')) {
$this->options['steps'] = true;
}

if ($test) {
$filter = $this->matchFilteredTestName($test);
$userOptions['filter'] = $filter;
}

$this->codecept = new PhpStorm_Codeception_Codecept($userOptions);

if ($suite and $test) {
$this->codecept->run($suite, $test);
}

if (!$test) {
$suites = $suite ? explode(',', $suite) : \Codeception\Configuration::suites();
$this->executed = $this->runSuites($suites, $this->options['skip']);

if (!empty($config['include']) and !$suite) {
$current_dir = \Codeception\Configuration::projectDir();
$suites += $config['include'];
$this->runIncludedSuites($config['include'], $current_dir);
}

if ($this->executed === 0) {
throw new \RuntimeException(
sprintf("Suite '%s' could not be found", implode(', ', $suites))
);
}
}

$this->codecept->printResult();

if (!$input->getOption('no-exit')) {
if (!$this->codecept->getResult()->wasSuccessful()) {
exit(1);
}
}
}

private function matchFilteredTestName(&$path)
{
if (version_compare(\Codeception\Codecept::VERSION, "2.2.5") >= 0) {
$test_parts = explode(':', $path, 2);
if (count($test_parts) > 1) {
list($path, $filter) = $test_parts;
// use carat to signify start of string like in normal regex
// phpunit --filter matches against the fully qualified method name, so tests actually begin with :
$carat_pos = strpos($filter, '^');
if ($carat_pos !== false) {
$filter = substr_replace($filter, ':', $carat_pos, 1);
}
return $filter;
}
return null;
}
else {
$test_parts = explode(':', $path);
if (count($test_parts) > 1) {
list($path, $filter) = $test_parts;
return $filter;
}
return null;
}
}

private function ensureCurlIsAvailable()
{
if (!extension_loaded('curl')) {
throw new \Exception(
"Codeception requires CURL extension installed to make tests run\n"
. "If you are not sure, how to install CURL, please refer to StackOverflow\n\n"
. "Notice: PHP for Apache/Nginx and CLI can have different php.ini files.\n"
. "Please make sure that your PHP you run from console has CURL enabled."
);
}
}
}

class PhpStorm_Codeception_Codecept extends \Codeception\Codecept {
public function __construct($options = [])
{
parent::__construct($options);

$printer = new PhpStorm_Codeception_ReportPrinter();
$this->runner = new \Codeception\PHPUnit\Runner();
$this->runner->setPrinter($printer);
}
}

$app->add(new PhpStorm_Codeception_Command_Run('run'));
$app->run();
}

现在它可以在 PHPUnit v7.x 和 Codeception 2.4.x 上正常工作

enter image description here

enter image description here

更新:

我有uploaded here对于那些不想执行上述步骤的人,可以提供一个修复该问题的 jar 文件,直到 PhpStorm 正式修复它为止。

更新2:

只是想指出,此修复不为低于 2.4.0 的 codeception 版本提供向后兼容性,我确信 PhpStorm 团队将提供更优雅的解决方案,允许使用 codeception 2.4.x 的项目以及其他使用早期版本的项目。

关于PhpStorm v2017.3.4 与 Codeception v2.4.0 不兼容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49059726/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com