22 июля 2018 г., 14:04:38 2252 PHP codeception php testing 0 Комментариев
Данное решение подойдет только для тех, кто разбил тесты на модули, а не тестирует сразу весь проект.
Когда ваш проект большой и все ООП, то это кушает много памяти. А вы еще, как на зло, заюзали некогда очень популярный среди разработчиков на PHP - Codeception
. Я не буду здесь критиковать Codeception
, личный выбор каждого, но, ИМХО, если встанет выбор между Codeception
и PHPUnit
, то выбирайте второе. ;) Но, здесь мы собрались по другой причине...
Причина написания данной статьи является выход таймаута или переполнение памяти при запуске тестов, что никак не решается в Codeception
из коробки, но прекрасно решается в PHPUnit
.
Но, все решаемо и я поделюсь с вами небольшим куском кода, который вы можете доработать, или использовать, как есть.
Для работы над понадобятся следующие пакеты:
А также, Composer
и codeception.yml
в корне проекта, где перечислены модули для тестирования в секции include
.
Создадим файл /bin/iso-test
с таким содержанием:
#!/usr/bin/env php <?php require_once __DIR__ '/../vendor/autoload.php'; use Symfony\Component\Process\Process; use Symfony\Component\Yaml\Yaml as YamlDecoder; use Zend\Config\Reader\Yaml as YamlConfig; $codeceptionConfig = (new YamlConfig([YamlDecoder::class, 'parse']))->fromFile(__DIR__ . '/../codeception.yml'); $beginTime = new DateTime(); $totalMemory = []; $k = count($codeceptionConfig['include']); $i = 1; foreach ($codeceptionConfig['include'] as $name) { echo colorStr(sprintf("(%d/%d) Wait...\n", $i++, $k), 'blue'); $process = new Process( __DIR__ . '/../vendor/bin/codecept run --ansi -c ' . $name, null, null, null, 300 ); $process->start(); $process->wait(function ($type, $buffer) { echo $buffer; }); if (!$process->isSuccessful()) { echo $process->getErrorOutput(); exit($process->getExitCode()); } $totalMemory[] = fetchMemory($process->getOutput()); echo PHP_EOL; } echo colorStr('Done!', 'green') . PHP_EOL; echo colorStr( sprintf( 'Time: %s, Memory: %.2fMB', (new DateTime())->diff($beginTime)->format('%H:%I:%S'), calcMemory($totalMemory) ), 'cyan' ) . PHP_EOL; function fetchMemory(string $output): array { $matches = []; preg_match('/Memory: (\d+(\.\d+|)(\w+))/', $output, $matches); return [$matches[3], (float)$matches[1]]; } function calcMemory(array $totalMemory): float { $result = []; foreach ($totalMemory as $memory) { switch ($memory[0]) { case 'GB': $result[] = $memory[1] * 1024; break; case 'MB': $result[] = $memory[1]; break; case 'KB': $result[] = $memory[1] / 1024; break; default: throw new DomainException('Fatal error while calculation total memory'); } } return array_sum($result) / count($result); } function colorStr($str, $code) { return sprintf('%s[%dm%s%s[0m', chr(27), getColorCode($code), $str, chr(27)); } function getColorCode($name) { $styles = [ 'red' => 31, 'green' => 32, 'yellow' => 33, 'blue' => 34, 'magenta' => 35, 'cyan' => 36, 'white' => 37, ]; return $styles[$name]; }
Файл codeception.yml
должен содержать секцию include
, т.к. именно по этой секции мы и запускаем наши тесты изолированно:
include: - module/Application - module/Amazon # и еще куча других модулей paths: output: _codeceptOutput
По результата запуска php bin/iso-test
вы можете получить такой вывод в случае успеха:
Done! Time: 00:13:01, Memory: 49.58MB
, где указано общее время выполнения всех тестов и среднее значение использованной памяти. Если во время выполнения произошла ошибка и тест не прошел, то процесс будет прерван.
Данное решение хорошо спасает, т.к. аналогично запущенные тесты просто через vendor/bin/codecept run
потребовали бы минимум 1024Мб
свободной оперативной памяти и данные число постоянно бы росло, как на дрожжах.
Комментарии [0]
Новый комментарий