Skip to content

Commit 693a638

Browse files
authored
Merge pull request #254 from stronk7/new_behat_phpunit_options
New behat phpunit options
2 parents d313896 + 632a21f commit 693a638

File tree

8 files changed

+247
-56
lines changed

8 files changed

+247
-56
lines changed

docs/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ This project adheres to [Semantic Versioning](http://semver.org/).
99
The format of this change log follows the advice given at [Keep a CHANGELOG](http://keepachangelog.com).
1010

1111
## [Unreleased]
12+
### Added
13+
- Added support for the `--tags` and `--name` options to the `behat` command.
14+
- Added support for the `--configure`, `--testsuite` and `--filter` options to the `phpunit` command.
15+
1216
### Changed
1317
- ACTION SUGGESTED: If you are using GitHub Actions, it's recomended to use `!cancelled()` instead of `always()` for moodle-plugin-ci tests. Adding a final step that always returns failure when the workflow is cancelled will ensure that cancelled workflows are not marked as successful. For a working example, please reference the updated `gha.dist.yml` file.
1418
- ACTION SUGGESTED: For some (unknown) reason, Travis environments with PHP 8.2 have started to fail with error:

docs/CLI.md

Lines changed: 64 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ Run Behat on a plugin
241241

242242
### Usage
243243

244-
* `behat [-m|--moodle MOODLE] [-p|--profile PROFILE] [--suite SUITE] [--start-servers] [--auto-rerun AUTO-RERUN] [--dump] [--] <plugin>`
244+
* `behat [-m|--moodle MOODLE] [-p|--profile PROFILE] [--suite SUITE] [--tags TAGS] [--name NAME] [--start-servers] [--auto-rerun AUTO-RERUN] [--dump] [--] <plugin>`
245245

246246
Run Behat on a plugin
247247

@@ -269,7 +269,7 @@ Path to Moodle
269269

270270
#### `--profile|-p`
271271

272-
Behat profile to use
272+
Behat profile option to use
273273

274274
* Accept value: yes
275275
* Is value required: yes
@@ -279,14 +279,34 @@ Behat profile to use
279279

280280
#### `--suite`
281281

282-
Behat suite to use (Moodle theme)
282+
Behat suite option to use (Moodle theme)
283283

284284
* Accept value: yes
285285
* Is value required: yes
286286
* Is multiple: no
287287
* Is negatable: no
288288
* Default: `'default'`
289289

290+
#### `--tags`
291+
292+
Behat tags option to use. If not set, defaults to the component name
293+
294+
* Accept value: yes
295+
* Is value required: yes
296+
* Is multiple: no
297+
* Is negatable: no
298+
* Default: `''`
299+
300+
#### `--name`
301+
302+
Behat name option to use
303+
304+
* Accept value: yes
305+
* Is value required: yes
306+
* Is multiple: no
307+
* Is negatable: no
308+
* Default: `''`
309+
290310
#### `--start-servers`
291311

292312
Start Selenium and PHP servers
@@ -1955,7 +1975,7 @@ Run PHPUnit on a plugin
19551975

19561976
### Usage
19571977

1958-
* `phpunit [-m|--moodle MOODLE] [--coverage-text] [--coverage-clover] [--coverage-pcov] [--coverage-xdebug] [--coverage-phpdbg] [--fail-on-incomplete] [--fail-on-risky] [--fail-on-skipped] [--fail-on-warning] [--testdox] [--] <plugin>`
1978+
* `phpunit [-m|--moodle MOODLE] [-c|--configuration CONFIGURATION] [--testsuite TESTSUITE] [--filter FILTER] [--testdox] [--coverage-text] [--coverage-clover] [--coverage-pcov] [--coverage-xdebug] [--coverage-phpdbg] [--fail-on-incomplete] [--fail-on-risky] [--fail-on-skipped] [--fail-on-warning] [--] <plugin>`
19591979

19601980
Run PHPUnit on a plugin
19611981

@@ -1981,6 +2001,46 @@ Path to Moodle
19812001
* Is negatable: no
19822002
* Default: `'.'`
19832003

2004+
#### `--configuration|-c`
2005+
2006+
PHPUnit configuration XML file (relative to plugin directory)
2007+
2008+
* Accept value: yes
2009+
* Is value required: yes
2010+
* Is multiple: no
2011+
* Is negatable: no
2012+
* Default: `NULL`
2013+
2014+
#### `--testsuite`
2015+
2016+
PHPUnit testsuite option to use (must exist in the configuration file being used)
2017+
2018+
* Accept value: yes
2019+
* Is value required: yes
2020+
* Is multiple: no
2021+
* Is negatable: no
2022+
* Default: `NULL`
2023+
2024+
#### `--filter`
2025+
2026+
PHPUnit filter option to use
2027+
2028+
* Accept value: yes
2029+
* Is value required: yes
2030+
* Is multiple: no
2031+
* Is negatable: no
2032+
* Default: `NULL`
2033+
2034+
#### `--testdox`
2035+
2036+
Enable testdox formatter
2037+
2038+
* Accept value: no
2039+
* Is value required: no
2040+
* Is multiple: no
2041+
* Is negatable: no
2042+
* Default: `false`
2043+
19842044
#### `--coverage-text`
19852045

19862046
Generate and print code coverage report in text format
@@ -2071,16 +2131,6 @@ Treat tests with warnings as failures
20712131
* Is negatable: no
20722132
* Default: `false`
20732133

2074-
#### `--testdox`
2075-
2076-
Enable testdox formatter
2077-
2078-
* Accept value: no
2079-
* Is value required: no
2080-
* Is multiple: no
2081-
* Is negatable: no
2082-
* Default: `false`
2083-
20842134
#### `--help|-h`
20852135

20862136
Display help for the given command. When no command is given display help for the list command

src/Command/BehatCommand.php

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,11 @@ protected function configure(): void
5858
parent::configure();
5959

6060
$this->setName('behat')
61-
->addOption('profile', 'p', InputOption::VALUE_REQUIRED, 'Behat profile to use', 'default')
62-
->addOption('suite', null, InputOption::VALUE_REQUIRED, 'Behat suite to use (Moodle theme)', 'default')
61+
->addOption('profile', 'p', InputOption::VALUE_REQUIRED, 'Behat profile option to use', 'default')
62+
->addOption('suite', null, InputOption::VALUE_REQUIRED, 'Behat suite option to use (Moodle theme)', 'default')
63+
->addOption('tags', null, InputOption::VALUE_REQUIRED, 'Behat tags option to use. ' .
64+
'If not set, defaults to the component name', '')
65+
->addOption('name', null, InputOption::VALUE_REQUIRED, 'Behat name option to use', '')
6366
->addOption('start-servers', null, InputOption::VALUE_NONE, 'Start Selenium and PHP servers')
6467
->addOption('auto-rerun', null, InputOption::VALUE_REQUIRED, 'Number of times to rerun failures', 2)
6568
->addOption('dump', null, InputOption::VALUE_NONE, 'Print contents of Behat failure HTML files')
@@ -89,14 +92,19 @@ protected function execute(InputInterface $input, OutputInterface $output): int
8992

9093
$cmd = [
9194
'php', 'admin/tool/behat/cli/run.php',
92-
'--tags=@' . $this->plugin->getComponent(),
9395
'--profile=' . $input->getOption('profile'),
9496
'--suite=' . $input->getOption('suite'),
97+
'--tags=' . ($input->getOption('tags') ?: '@' . $this->plugin->getComponent()),
9598
'--auto-rerun=' . $input->getOption('auto-rerun'),
9699
'--verbose',
97100
'-vvv',
98101
];
99102

103+
$name = $input->getOption('name');
104+
if (!empty($name) && is_string($name)) {
105+
$cmd[] = '--name=\'' . $name . '\'';
106+
}
107+
100108
if ($output->isDecorated()) {
101109
$cmd[] = '--colors';
102110
}

src/Command/PHPUnitCommand.php

Lines changed: 56 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,20 @@ protected function configure(): void
2929

3030
$this->setName('phpunit')
3131
->setDescription('Run PHPUnit on a plugin')
32+
->addOption(
33+
'configuration',
34+
'c',
35+
InputOption::VALUE_REQUIRED,
36+
'PHPUnit configuration XML file (relative to plugin directory)'
37+
)
38+
->addOption(
39+
'testsuite',
40+
null,
41+
InputOption::VALUE_REQUIRED,
42+
'PHPUnit testsuite option to use (must exist in the configuration file being used)'
43+
)
44+
->addOption('filter', null, InputOption::VALUE_REQUIRED, 'PHPUnit filter option to use')
45+
->addOption('testdox', null, InputOption::VALUE_NONE, 'Enable testdox formatter')
3246
->addOption('coverage-text', null, InputOption::VALUE_NONE, 'Generate and print code coverage report in text format')
3347
->addOption('coverage-clover', null, InputOption::VALUE_NONE, 'Generate code coverage report in Clover XML format')
3448
->addOption('coverage-pcov', null, InputOption::VALUE_NONE, 'Use the pcov extension to calculate code coverage')
@@ -37,8 +51,7 @@ protected function configure(): void
3751
->addOption('fail-on-incomplete', null, InputOption::VALUE_NONE, 'Treat incomplete tests as failures')
3852
->addOption('fail-on-risky', null, InputOption::VALUE_NONE, 'Treat risky tests as failures')
3953
->addOption('fail-on-skipped', null, InputOption::VALUE_NONE, 'Treat skipped tests as failures')
40-
->addOption('fail-on-warning', null, InputOption::VALUE_NONE, 'Treat tests with warnings as failures')
41-
->addOption('testdox', null, InputOption::VALUE_NONE, 'Enable testdox formatter');
54+
->addOption('fail-on-warning', null, InputOption::VALUE_NONE, 'Treat tests with warnings as failures');
4255
}
4356

4457
protected function initialize(InputInterface $input, OutputInterface $output): void
@@ -80,6 +93,28 @@ protected function execute(InputInterface $input, OutputInterface $output): int
8093
private function resolveOptions(InputInterface $input): array
8194
{
8295
$options = [];
96+
97+
if ($input->getOption('configuration')) {
98+
$options[] = [
99+
'--configuration',
100+
$this->plugin->directory . '/' . $input->getOption('configuration'),
101+
];
102+
}
103+
104+
if ($input->getOption('testsuite')) {
105+
$options[] = [
106+
'--testsuite',
107+
$input->getOption('testsuite'),
108+
];
109+
}
110+
111+
if ($input->getOption('filter')) {
112+
$options[] = [
113+
'--filter',
114+
$input->getOption('filter'),
115+
];
116+
}
117+
83118
if ($this->supportsCoverage() && $input->getOption('coverage-text')) {
84119
$options[] = [
85120
'--coverage-text',
@@ -103,16 +138,25 @@ private function resolveOptions(InputInterface $input): array
103138
];
104139
}
105140
}
106-
if (is_file($this->plugin->directory . '/phpunit.xml')) {
107-
$options[] = [
108-
'--configuration',
109-
$this->plugin->directory,
110-
];
111-
} else {
112-
$options[] = [
113-
'--testsuite',
114-
$this->plugin->getComponent(),
115-
];
141+
142+
// Only can set configuration or testsuite here (auto) if the former has not been set via command line option.
143+
if (!$input->getOption('configuration')) {
144+
// Use default configuration (phpunit.xml) only if it exists.
145+
if (is_file($this->plugin->directory . '/phpunit.xml')) {
146+
$options[] = [
147+
'--configuration',
148+
$this->plugin->directory . '/phpunit.xml',
149+
];
150+
} else {
151+
// Fallback to try to use the best testsuite potentially available.
152+
// Only can set automatic testsuite if it has not been passed via command line option.
153+
if (!$input->getOption('testsuite')) {
154+
$options[] = [
155+
'--testsuite',
156+
$this->plugin->getComponent() . '_testsuite', // This is our best guess.
157+
];
158+
}
159+
}
116160
}
117161

118162
return array_merge(...$options); // Merge all options into a single array.

tests/Command/BehatCommandTest.php

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121

2222
class BehatCommandTest extends MoodleTestCase
2323
{
24-
protected function executeCommand($pluginDir = null, $moodleDir = null): CommandTester
24+
protected function executeCommand($pluginDir = null, $moodleDir = null, array $cmdOptions = []): CommandTester
2525
{
2626
if ($pluginDir === null) {
2727
$pluginDir = $this->pluginDir;
@@ -38,10 +38,15 @@ protected function executeCommand($pluginDir = null, $moodleDir = null): Command
3838
$application->add($command);
3939

4040
$commandTester = new CommandTester($application->find('behat'));
41-
$commandTester->execute([
42-
'plugin' => $pluginDir,
43-
'--moodle' => $moodleDir,
44-
]);
41+
$cmdOptions = array_merge(
42+
[
43+
'plugin' => $pluginDir,
44+
'--moodle' => $moodleDir,
45+
],
46+
$cmdOptions
47+
);
48+
$commandTester->execute($cmdOptions);
49+
$this->lastCmd = $command->execute->lastCmd; // We need this for assertions against the command run.
4550

4651
return $commandTester;
4752
}
@@ -50,6 +55,28 @@ public function testExecute()
5055
{
5156
$commandTester = $this->executeCommand();
5257
$this->assertSame(0, $commandTester->getStatusCode());
58+
$this->assertMatchesRegularExpression('/php.*admin.tool.behat.cli.run/', $this->lastCmd);
59+
$this->assertMatchesRegularExpression('/--profile=default.*--suite=default/', $this->lastCmd);
60+
$this->assertMatchesRegularExpression('/--tags=@local_ci/', $this->lastCmd);
61+
$this->assertMatchesRegularExpression('/--verbose.*-vvv/', $this->lastCmd);
62+
}
63+
64+
public function testExecuteWithTags()
65+
{
66+
$commandTester = $this->executeCommand(null, null, ['--tags' => '@tag1&&@tag2']);
67+
$this->assertSame(0, $commandTester->getStatusCode());
68+
$this->assertMatchesRegularExpression('/--tags=@tag1&&@tag2/', $this->lastCmd);
69+
$this->assertDoesNotMatchRegularExpression('/--tags=@local_ci/', $this->lastCmd);
70+
}
71+
72+
public function testExecuteWithName()
73+
{
74+
$featureName = 'With "double quotes" and \'single quotes\'';
75+
// Note that everything is escaped for shell execution, plus own regexp quoting.
76+
$expectedName = preg_quote(escapeshellarg("--name='$featureName'"));
77+
$commandTester = $this->executeCommand(null, null, ['--name' => $featureName]);
78+
$this->assertSame(0, $commandTester->getStatusCode());
79+
$this->assertMatchesRegularExpression("/{$expectedName}/", $this->lastCmd);
5380
}
5481

5582
public function testExecuteNoFeatures()
@@ -70,6 +97,7 @@ public function testExecuteNoPlugin()
7097
public function testExecuteNoMoodle()
7198
{
7299
$this->expectException(\InvalidArgumentException::class);
100+
// TODO: Check what's happening here. moodleDir should be the 2nd parameter, but then the test fails.
73101
$this->executeCommand($this->moodleDir . '/no/moodle');
74102
}
75103
}

0 commit comments

Comments
 (0)