Skip to content

Commit 4152e0f

Browse files
committed
refactor(tests): simplify parallel implementation - build arguments directly for ParaTest
1 parent ffcedf1 commit 4152e0f

1 file changed

Lines changed: 44 additions & 71 deletions

File tree

src/Command/TestsCommand.php

Lines changed: 44 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
use Symfony\Component\Console\Input\InputInterface;
2323
use Symfony\Component\Console\Input\InputOption;
2424
use Symfony\Component\Console\Output\OutputInterface;
25-
use Symfony\Component\Process\Exception\ProcessFailedException;
2625
use Symfony\Component\Process\Process;
2726

2827
/**
@@ -91,7 +90,6 @@ protected function configure(): void
9190
shortcut: 'p',
9291
mode: InputOption::VALUE_OPTIONAL,
9392
description: 'Run tests in parallel using ParaTest. Optional number of workers.',
94-
default: null,
9593
);
9694
}
9795

@@ -108,8 +106,28 @@ protected function configure(): void
108106
*/
109107
protected function execute(InputInterface $input, OutputInterface $output): int
110108
{
109+
$arguments = $this->buildBaseArguments($input);
110+
111+
if (null !== $input->getOption('parallel')) {
112+
return $this->runParallel($input, $output, $arguments);
113+
}
114+
111115
$output->writeln('<info>Running PHPUnit tests...</info>');
112116

117+
$command = new Process([...$arguments, $input->getArgument('path')]);
118+
119+
return parent::runProcess($command, $output);
120+
}
121+
122+
/**
123+
* Builds the base PHPUnit arguments from input options.
124+
*
125+
* @param InputInterface $input the runtime instruction set from the CLI
126+
*
127+
* @return list<string> the base arguments for PHPUnit
128+
*/
129+
private function buildBaseArguments(InputInterface $input): array
130+
{
113131
$arguments = [
114132
$this->getAbsolutePath('vendor/bin/phpunit'),
115133
'--configuration=' . parent::getConfigFile(self::CONFIG),
@@ -124,121 +142,76 @@ protected function execute(InputInterface $input, OutputInterface $output): int
124142
$arguments[] = '--cache-directory=' . $this->resolvePath($input, 'cache-dir');
125143
}
126144

127-
if ($input->getOption('coverage')) {
128-
$output->writeln(
129-
'<info>Generating code coverage reports on path: ' . $this->resolvePath($input, 'coverage') . '</info>'
130-
);
145+
if (null !== $input->getOption('coverage')) {
146+
$coveragePath = $this->resolvePath($input, 'coverage');
131147

132148
foreach ($this->getPsr4Namespaces() as $path) {
133149
$arguments[] = '--coverage-filter=' . $this->getAbsolutePath($path);
134150
}
135151

136152
$arguments[] = '--coverage-text';
137-
$arguments[] = '--coverage-html=' . $this->resolvePath($input, 'coverage');
138-
$arguments[] = '--testdox-html=' . $this->resolvePath($input, 'coverage') . '/testdox.html';
139-
$arguments[] = '--coverage-clover=' . $this->resolvePath($input, 'coverage') . '/clover.xml';
140-
$arguments[] = '--coverage-php=' . $this->resolvePath($input, 'coverage') . '/coverage.php';
153+
$arguments[] = '--coverage-html=' . $coveragePath;
154+
$arguments[] = '--testdox-html=' . $coveragePath . '/testdox.html';
155+
$arguments[] = '--coverage-clover=' . $coveragePath . '/clover.xml';
156+
$arguments[] = '--coverage-php=' . $coveragePath . '/coverage.php';
141157
}
142158

143-
if ($input->getOption('filter')) {
159+
if (null !== $input->getOption('filter')) {
144160
$arguments[] = '--filter=' . $input->getOption('filter');
145161
}
146162

147-
$parallel = $input->getOption('parallel');
148-
149-
if ($parallel !== null) {
150-
return $this->runParallel($input, $output, $parallel, $arguments);
151-
}
152-
153-
$command = new Process([...$arguments, $input->getArgument('path')]);
154-
155-
return parent::runProcess($command, $output);
163+
return $arguments;
156164
}
157165

158166
/**
159167
* Executes PHPUnit in parallel mode using ParaTest.
160168
*
161169
* @param InputInterface $input the runtime instruction set from the CLI
162170
* @param OutputInterface $output the console feedback relay
163-
* @param mixed $workers the number of workers or empty for auto
164-
* @param array<int, string> $baseArguments the base PHPUnit arguments
171+
* @param list<string> $baseArguments the base PHPUnit arguments
165172
*
166173
* @return int the status integer describing the termination code
167174
*/
168175
private function runParallel(
169176
InputInterface $input,
170177
OutputInterface $output,
171-
mixed $workers,
172178
array $baseArguments,
173179
): int {
174180
$output->writeln('<info>Running PHPUnit tests in parallel mode...</info>');
175181

176-
$validParatestOptions = [
177-
'--bootstrap',
178-
'--configuration',
179-
'--cache-directory',
180-
'--filter',
181-
'--group',
182-
'--exclude-group',
183-
'--testsuite',
184-
'--no-test-tokens',
185-
'--stop-on-defect',
186-
'--stop-on-error',
187-
'--stop-on-failure',
188-
'--stop-on-warning',
189-
'--stop-on-risky',
190-
'--stop-on-skipped',
191-
'--stop-on-incomplete',
192-
'--fail-on-incomplete',
193-
'--fail-on-risky',
194-
'--fail-on-skipped',
195-
'--fail-on-warning',
196-
'--fail-on-deprecation',
197-
];
198-
182+
$workers = $input->getOption('parallel');
199183
$arguments = [
200184
$this->getAbsolutePath('vendor/bin/paratest'),
201185
];
202186

203-
if ($workers !== null && $workers !== '') {
187+
if (null !== $workers && '' !== $workers) {
204188
$arguments[] = '--processes=' . (int) $workers;
205189
}
206190

207-
foreach ($baseArguments as $arg) {
208-
$isValid = false;
209-
foreach ($validParatestOptions as $option) {
210-
if (str_starts_with($arg, $option)) {
211-
$isValid = true;
191+
$arguments[] = '--configuration=' . parent::getConfigFile(self::CONFIG);
192+
$arguments[] = '--bootstrap=' . $this->resolvePath($input, 'bootstrap');
212193

213-
break;
214-
}
215-
}
216-
217-
if ($isValid) {
218-
$arguments[] = $arg;
219-
}
194+
if (! $input->getOption('no-cache')) {
195+
$arguments[] = '--cache-directory=' . $this->resolvePath($input, 'cache-dir');
220196
}
221197

222-
$coverage = $input->getOption('coverage');
223-
if ($coverage !== null) {
224-
$output->writeln(
225-
'<info>Generating code coverage reports on path: ' . $this->getAbsolutePath($coverage) . '</info>'
226-
);
198+
if (null !== $input->getOption('coverage')) {
199+
$coveragePath = $this->getAbsolutePath($input->getOption('coverage'));
200+
$output->writeln('<info>Generating code coverage reports on path: ' . $coveragePath . '</info>');
227201

228202
foreach ($this->getPsr4Namespaces() as $path) {
229203
$arguments[] = '--coverage-filter=' . $this->getAbsolutePath($path);
230204
}
231205

232206
$arguments[] = '--coverage-text';
233-
$arguments[] = '--coverage-html=' . $this->getAbsolutePath($coverage);
234-
$arguments[] = '--testdox-html=' . $this->getAbsolutePath($coverage) . '/testdox.html';
235-
$arguments[] = '--coverage-clover=' . $this->getAbsolutePath($coverage) . '/clover.xml';
236-
$arguments[] = '--coverage-php=' . $this->getAbsolutePath($coverage) . '/coverage.php';
207+
$arguments[] = '--coverage-html=' . $coveragePath;
208+
$arguments[] = '--testdox-html=' . $coveragePath . '/testdox.html';
209+
$arguments[] = '--coverage-clover=' . $coveragePath . '/clover.xml';
210+
$arguments[] = '--coverage-php=' . $coveragePath . '/coverage.php';
237211
}
238212

239-
$filter = $input->getOption('filter');
240-
if ($filter !== null) {
241-
$arguments[] = '--filter=' . $filter;
213+
if (null !== $input->getOption('filter')) {
214+
$arguments[] = '--filter=' . $input->getOption('filter');
242215
}
243216

244217
$arguments[] = $input->getArgument('path') ?? './tests';

0 commit comments

Comments
 (0)