Skip to content

Commit

Permalink
Merge pull request #179 from loic425/php-config/suites
Browse files Browse the repository at this point in the history
PHP Config - Suites
  • Loading branch information
carlos-granados authored Dec 9, 2024
2 parents 21caa65 + 218b760 commit fd57ec8
Showing 1 changed file with 223 additions and 102 deletions.
325 changes: 223 additions & 102 deletions user_guide/configuration/suites.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,71 +10,146 @@ With suites you can configure Behat to test different kinds of features
using different kinds of contexts and doing so in one run. Test suites are
really powerful and ``behat.yml`` makes them that much more powerful:

.. code-block:: yaml
# behat.yml
default:
suites:
core_features:
paths: [ '%paths.base%/features/core' ]
contexts: [ CoreDomainContext ]
user_features:
paths: [ '%paths.base%/features/web' ]
filters: { role: user }
contexts: [ UserContext ]
admin_features:
paths: [ '%paths.base%/features/web' ]
filters: { role: admin }
contexts: [ AdminContext ]
.. code-block:: php
<?php
// behat.php
use App\Tests\Behat\Context\AdminContext;
use App\Tests\Behat\Context\CoreDomainContext;
use App\Tests\Behat\Context\UserContext;
use Behat\Config\Config;
use Behat\Config\Config\Filter\RoleFilter;
use Behat\Config\Profile;
use Behat\Config\Suite;
$profile = new Profile('default')
->withSuite(
new Suite('core_features')
->withPaths('%paths.base%/features/core')
->withContexts(CoreDomainContext::class)
)
->withSuite(
new Suite('user_features')
->withFilter(new RoleFilter('user'))
->withPaths('%paths.base%/features/web')
->withContexts(UserContext::class)
)
->withSuite(
new Suite('admin_features')
->withFilter(new RoleFilter('admin'))
->withPaths('%paths.base%/features/web')
->withContexts(AdminContext::class)
)
;
return new Config()
->withProfile($profile)
;
.. note::

On PHP < 8.4, you need to wrap new invocations with parentheses before calling config object methods.

.. code-block:: php
// ...
// $profile = new Profile('default')
$profile = (new Profile('default'))
->withSuite(
// new Suite('core_features')
(new Suite('core_features'))
->withPaths('%paths.base%/features/core')
->withContexts(CoreDomainContext::class)
)
// ...
Suite Paths
-----------

One of the most obvious settings of the suites is the ``paths``
configuration:

.. code-block:: yaml
.. code-block:: php
<?php
// behat.php
# behat.yml
use Behat\Config\Config;
use Behat\Config\Profile;
use Behat\Config\Suite;
default:
suites:
core_features:
paths:
- '%paths.base%/features'
- '%paths.base%/test/features'
- '%paths.base%/vendor/.../features'
$profile = new Profile('default')
->withSuite(
new Suite('core_features')
->withPaths(
'%paths.base%/features',
'%paths.base%/test/features',
'%paths.base%/vendor/.../features',
)
)
;
return (new Config())
->withProfile($profile)
;
As you might imagine, this option tells Behat where to search for test features.
You could, for example, tell Behat to look into the
``features/web`` folder for features and test them with ``WebContext``:

.. code-block:: yaml
.. code-block:: php
# behat.yml
<?php
// behat.php
default:
suites:
web_features:
paths: [ '%paths.base%/features/web' ]
contexts: [ WebContext ]
use App\Tests\Behat\Context\WebContext;
use Behat\Config\Config;
use Behat\Config\Profile;
use Behat\Config\Suite;
You then might want to also describe some API-specific features in
``features/api`` and test them with an API-specific ``ApiContext``. Easy:
$profile = new Profile('default')
->withSuite(
new Suite('web_features')
->withPaths('%paths.base%/features/web')
->withContexts(WebContext::class)
)
;
.. code-block:: yaml
return new Config()
->withProfile($profile)
;
# behat.yml
You then might want to also describe some API-specific features in
``features/api`` and test them with an API-specific ``ApiContext``. Easy:

default:
suites:
web_features:
paths: [ '%paths.base%/features/web' ]
contexts: [ WebContext ]
api_features:
paths: [ '%paths.base%/features/api' ]
contexts: [ ApiContext ]
.. code-block:: php
<?php
// behat.php
use App\Tests\Behat\Context\ApiContext;
use App\Tests\Behat\Context\WebContext;
use Behat\Config\Config;
use Behat\Config\Profile;
use Behat\Config\Suite;
$profile = new Profile('default')
->withSuite(
new Suite('web_features')
->withPaths('%paths.base%/features/web')
->withContexts(WebContext::class)
)
->withSuite(
new Suite('api_features')
->withPaths('%paths.base%/features/api')
->withContexts(ApiContext::class)
)
;
return new Config()
->withProfile($profile)
;
This will cause Behat to:

Expand Down Expand Up @@ -103,27 +178,36 @@ criteria. The Gherkin parser comes bundled with a set of cool filters
such as *tags* and *name* filters. You can use these filters to run
features with specific tag (or name) in specific contexts:

.. code-block:: yaml
# behat.yml
default:
suites:
web_features:
paths: [ '%paths.base%/features' ]
contexts: [ WebContext ]
filters:
tags: '@web'
api_features:
paths: [ '%paths.base%/features' ]
contexts: [ ApiContext ]
filters:
tags: '@api'
.. note::

The ``@`` character is a special and requires the tag to be
put in quotes.
.. code-block:: php
<?php
// behat.php
use App\Tests\Behat\Context\ApiContext;
use App\Tests\Behat\Context\WebContext;
use Behat\Config\Config;
use Behat\Config\Filter\TagFilter;
use Behat\Config\Profile;
use Behat\Config\Suite;
$profile = new Profile('default')
->withSuite(
new Suite('web_features')
->withFilter(new TagFilter('@web'))
->withPaths('%paths.base%/features')
->withContexts(WebContext::class)
)
->withSuite(
new Suite('api_features')
->withFilter(new TagFilter('@api'))
->withPaths('%paths.base%/features')
->withContexts(ApiContext::class)
)
;
return new Config()
->withProfile($profile)
;
This configuration will tell Behat to run features and scenarios
tagged as ``@web`` in ``WebContext`` and features and scenarios
Expand All @@ -132,22 +216,36 @@ in the same folder. How cool is that? But it gets even better,
because Gherkin 4+ (used in Behat 3+) added a very special *role*
filter. That means, you can now have nice actor-based suites:

.. code-block:: yaml
# behat.yml
default:
suites:
user_features:
paths: [ '%paths.base%/features' ]
contexts: [ UserContext ]
filters:
role: user
admin_features:
paths: [ '%paths.base%/features' ]
contexts: [ AdminContext ]
filters:
role: admin
.. code-block:: php
<?php
// behat.php
use App\Tests\Behat\Context\AdminContext;
use App\Tests\Behat\Context\UserContext;
use Behat\Config\Config;
use Behat\Config\Filter\RoleFilter;
use Behat\Config\Profile;
use Behat\Config\Suite;
$profile = new Profile('default')
->withSuite(
new Suite('user_features')
->withFilter(new RoleFilter('user'))
->withPaths('%paths.base%/features')
->withContexts(UserContext::class)
)
->withSuite(
new Suite('api_features')
->withFilter(new RoleFilter('admin'))
->withPaths('%paths.base%/features')
->withContexts(AdminContext::class)
)
;
return (new Config())
->withProfile($profile)
;
A Role filter takes a look into the feature description block:

Expand All @@ -172,14 +270,22 @@ option to override the filters at the command line.

This is achieved by specifying the filter in the gherkin configuration:

.. code-block:: yaml
.. code-block:: php
<?php
// behat.php
use Behat\Config\Config;
use Behat\Config\Filter\TagFilter;
use Behat\Config\Profile;
# behat.yml
$profile = new Profile('default')
->withFilter(new TagFilter('~@wip'))
;
default:
gherkin:
filters:
tags: '~@wip'
return new Config()
->withProfile($profile)
;
In this instance, scenarios tagged as @wip will be ignored unless the CLI
command is run with a custom filter, e.g.:
Expand All @@ -203,20 +309,35 @@ against different contexts *or* the same contexts configured differently.
This basically means that you can use the same subset of features to
develop different layers of your application with Behat:

.. code-block:: yaml
# behat.yml
default:
suites:
domain_features:
paths: [ '%paths.base%/features' ]
contexts: [ DomainContext ]
web_features:
paths: [ '%paths.base%/features' ]
contexts: [ WebContext ]
filters:
tags: '@web'
.. code-block:: php
<?php
// behat.php
use App\Tests\Behat\Context\DomainContext;
use App\Tests\Behat\Context\WebContext;
use Behat\Config\Config;
use Behat\Config\Filter\TagFilter;
use Behat\Config\Profile;
use Behat\Config\Suite;
$profile = new Profile('default')
->withSuite(
new Suite('domain_features')
->withPaths('%paths.base%/features')
->withContexts(DomainContext::class)
)
->withSuite(
new Suite('web_features')
->withFilter(new TagFilter('@web'))
->withPaths('%paths.base%/features')
->withContexts(WebContext::class)
)
;
return new Config()
->withProfile($profile)
;
In this case, Behat will first run all the features from the ``features/``
folder in ``DomainContext`` and then only those tagged with ``@web`` in
Expand Down

0 comments on commit fd57ec8

Please sign in to comment.