-
-
Notifications
You must be signed in to change notification settings - Fork 612
Description
Description
Currently, Behat supports configuration through YAML files. While YAML is straightforward for many use cases, offering support for PHP configuration files could bring added flexibility and advantages, such as:
- Enhanced readability for developers familiar with PHP syntax.
- Leveraging PHP logic (e.g., conditions, constants, or reusable configurations).
- Improved IDE support and type checking.
Proposal
Introduce support for configuring Behat using PHP files alongside the existing YAML configuration. This would involve:
- Parsing configurations from a behat.php file if present.
- Maintaining backward compatibility with YAML configuration files (behat.yml, behat.yaml).
- Providing a basic example of a PHP configuration file in the documentation.
Benefits
- Greater flexibility in defining configurations.
- Ability to dynamically generate configurations based on environment or context.
- Seamless integration with PHP constants, variables, and classes.
Example
Here’s an example of what a PHP configuration file (behat.php) could look like:
use Behat\Config\Config;
return new Config([
'default' => [
'gherkin' => [
'filters' => [
'tags' => '~@php8'
],
],
],
]);Implementation Notes
- Extend the Behat configuration loader to check for behat.php.
- Update the documentation to explain the new option and its use cases.
Future helpers
We can do everything with a simple array. But to improve the DX, we can add some helpers to the Config object.
Importing Configuration Files
To make configurations modular and reusable, the PHP file should support importing other files.
It's already possible with the previous proposal:
use Behat\Config\Config;
return new Config([
'imports' => [
__DIR__.'/other-config.php'
],
])But we need some helpers to improve the DX.
For instance:
use Behat\Config\Config;
$config = new Config();
$config->import('config/suites.php');
return $config;We can import several configuration files with the same "import" method.
use Behat\Config\Config;
$config = new Config();
$config->import([
'config/extensions.php',
'config/suites.php',
]);
return $config;We can also introduce more smart imports.
use Behat\Config\Config;
$config = new Config();
$config->import('config/**/**.php');
return $config;Adding suites
Here's is just a proposal, it needs to be discussed.
use App\Tests\Behat\Context\FirstContext;
use App\Tests\Behat\Context\SecondContext;
use Behat\Config\Config;
use Behat\Config\Profile;
use Behat\Config\Suite;
$defaultProfile = (new Profile('default'))
->withSuite($adminDashboardSuite);
;
$defaultProfile->withSuite(
new Suite(
name: 'admin_dashboard',
settings: [
'contexts' => [
FirstContext::class,
SecondContext::class,
],
'filters' => [
'tags' => '@admin&&@dashboard'
],
],
)
);
return new (Config())
->withProfile($defaultProfile)
;or using more helpers
use App\Tests\Behat\Context\FirstContext;
use App\Tests\Behat\Context\SecondContext;
use Behat\Config\Config;
use Behat\Config\Profile;
use Behat\Config\Suite;
$adminDashboardSuite = (new Suite(name: 'admin_dashboard'))
->withFilters(['tags' => ['@admin&&@dashboard']])
->withContexts(
FirstContext::class,
SecondContext::class
)
;
$defaultProfile = (new Profile('default'))
->withSuite($adminDashboardSuite)
;
return (new Config())
->withProfile($defaultProfile)
;Overall solution
The main config file
use Behat\Config\Config;
use Behat\Config\Extension;
use Behat\Config\Profile;
use FriendsOfBehat\MinkDebugExtension;
use Robertfausk\Behat\PantherExtension;
$defaultProfile = (new profile('default'))
->import('config/suites/**/**.php')
->withFormatters([
'pretty' => [
'verbose' => true,
'paths' => false,
'snippets' => false,
],
])
->withExtension(new Extension(PantherExtension::class))
->withExtension(new Extension(MinkDebugExtension::class, [
'directory' => 'etc/build',
'clean_start' => true,
'screenshot' => true,
]))
;
return (new Config())->withProfile($defaultProfile);A first suite config file
// config/suites/admin_dashboard.php
use App\Tests\Behat\Context\FirstContext;
use App\Tests\Behat\Context\SecondContext;
use Behat\Config\Config;
use Behat\Config\Profile;
use Behat\Config\Suite;
use App\Tests\Behat\Context\FirstContext;
use App\Tests\Behat\Context\SecondContext;
use Behat\Config\Config;
use Behat\Config\Profile;
use Behat\Config\Suite;
$suite = (new Suite(name: 'admin_dashboard'))
->withFilters(['tags' => ['@admin&&@dashboard']])
->withContexts(
FirstContext::class,
SecondContext::class,
)
;
return (new Config())
->withProfile((new Profile('default'))
->withSuite($suite)
)
;Maybe that would be better like this. It could be a shortcut to add suites.
use App\Tests\Behat\Context\FirstContext;
use App\Tests\Behat\Context\SecondContext;
use Behat\Config\Config;
use Behat\Config\Suite;
$suite = (new Suite(name: 'admin_dashboard'))
->withFilters(['tags' => ['@admin&&@dashboard']])
->withContexts(
FirstContext::class,
SecondContext::class,
)
;
$config = (new Config())
->withSuite(suite: $suite, profile: 'default')
;