Using subcontexts with Behat and Mink
Using subcontexts with Behat and Mink is easy. You only need to remember to only extend MinkContext (or use Mink as subcontext) once, because it has some basic step definitions already defined and Behat doesn’t allow redundant step definitions.
My base FeatureContext
file looks something like the below:
<?php use Behat\Behat\Context\ClosuredContextInterface, Behat\Behat\Context\TranslatedContextInterface, Behat\Behat\Context\BehatContext, Behat\Behat\Exception\PendingException; use Behat\Gherkin\Node\PyStringNode, Behat\Gherkin\Node\TableNode; use Behat\MinkExtension\Context\MinkContext; use Behat\Behat\Context\Step; /** * Features context. */ class FeatureContext extends MinkContext { public function __construct(array $parameters) { // Initialize your context here // ... $this->useContext('SubContext', new SubContext($parameters)); } }
And here’s my SubContext
template file:
<?php use Behat\Behat\Context\ClosuredContextInterface, Behat\Behat\Context\TranslatedContextInterface, Behat\Behat\Context\BehatContext, Behat\Behat\Exception\PendingException; use Behat\Gherkin\Node\PyStringNode, Behat\Gherkin\Node\TableNode; use Behat\Behat\Context\Step; /** * Features context. */ class SubContext extends BehatContext { /** * Initializes context. * Every scenario gets it's own context object. * * @param array $parameters context parameters */ public function __construct(array $parameters) { // Initialize your context here // ... } /** * Get Mink session from MinkContext */ public function getSession($name = null) { return $this->getMainContext()->getSession($name); } /** * Write your subcontext methods below. * Remember that this class extends BehatContext, not MinkContext */ }
Note that it extends BehatContext
and not MinkContext
as this is not allowed – I used MinkContext
already as a base of my FeatureContext
class.
Also, the getSession()
proxy method is created, as it is probably the most used one across the suite.
Now, whenever you want to call a method from main context, use:
$this->getMainContext()->methodName($args);
To communicate between subcontexts use:
$this->getMainContext()->getSubcontext('SubContext')->methodName($args);
Comments
Diego Lewin on
Thanks, I had the redundant step definitions exception :)
cmorell85 on
Excelent!!!Thanks a lot!
Jonathan RAMIER on
thanks a lot, I resolved my exception with your post
Max Heckel on
Helped me get it working! Thanks!
matthewmarichiba on
Thanks for this. I’m not sure why this content isn’t part of the core Mink docs. I presume everyone eventually wants to break their step definitions into multiple files, given a big enough project, but Behat & Mink docs don’t make it obvious how to do so. The way you’ve laid it out here worked for me and seems elegant.