rector / behastan
Static analysis for Behat definitions and context files
Fund package maintenance!
tomasvotruba
www.paypal.me/rectorphp
Installs: 47 689
Dependents: 0
Suggesters: 0
Security: 0
Stars: 11
Watchers: 1
Forks: 1
Open Issues: 1
pkg:composer/rector/behastan
Requires
- php: >=7.2
This package is auto-updated.
Last update: 2026-01-25 17:51:52 UTC
README
Find unused and duplicated definitions easily – without running Behat tests.
Install
composer require rector/behastan --dev
Usage
vendor/bin/behastan analyse tests
Do you want to skip some rule? You can:
vendor/bin/behastan analyse tests --skip=<rule-identifier> # e.g. vendor/bin/behastan analyse tests --skip=duplicated-contents
Here are the available rules:
1. Find duplicated definitions contents (duplicated-contents)
Some definitions have similar patterns, even identical contents:
use Behat\Step\When; #[When('load a user profile')] public function loadAUserProfile() { $this->loadRoute('/user-profile'); } #[When('load user profile')] public function loadUserProfile() { $this->loadRoute('/user-profile'); }
Better use a one definition with single pattern, to make your tests more precise and easier to maintain.
2. Find duplicated patterns (duplicated-patterns)
Same as services, there should be unique definition patterns:
use Behat\Step\When; #[When('load homepage')] public function loadUserProfile() { $this->loadRoute('/homepage'); } #[When('load homepage')] public function loadUserProfile() { $this->loadRoute('/homepage/default'); }
Make them unique with different behavior, or merge them and use one definition instead.
3. Find unused definitions (unused-definitions)
Behat uses @When(), @Then() and @Given() annotations or attributes to define a class method that is called in *.feature files. Sometimes test change and lines from *.feature files are deleted. But what about definitions?
# some *.feature file Scenario: Load admin dashboard - When load admin dashboard + When load homepage
↓
use Behat\Step\When; #[When('load admin dashboard')] public function loadAdminDashboard() { $this->loadRoute('/admin/dashboard'); }
This rule spots definitions that are no longer needed, so you can remove them.
4. Find duplicate scenario titles (duplicate-scenario-titles)
In Behat, each scenario should have a unique name to ensure clarity and avoid confusion during test execution and later debugging. This rule identifies scenarios that share the same name within your feature files:
Feature: User Authentication Scenario: User logs in successfully When the user enters valid credentials Then login should be successful Scenario: User logs in successfully When the user enters invalid credentials Then an error message should be displayed
5. Rerport redundant regex definitions (redundant-regex-definitions)
When defining step definitions in Behat, it's common to use regular expressions to match patterns. However, sometimes these regex patterns can be overly complex or redundant, making them harder to read and maintain. This rule identifies such redundant regex definitions:
-#[When('#I have apples#')] +#[When('I have apples')] public function iHaveApples() { // ... }
Protip: Add this command to your CI, to get instant feedback of any changes in every pull-request.
That's it!
Happy coding!