Get bare Behat scenario running

This commit is contained in:
Kamil Kokot
2019-01-09 22:29:50 +01:00
parent 742d3358b5
commit 7250dfca76
4 changed files with 118 additions and 217 deletions

View File

@@ -1,6 +1,7 @@
Feature: Injecting parameters into context Feature: Injecting parameters into context
Background: Background:
Given a working Symfony application with SymfonyExtension configured
Given a context file "features/bootstrap/FeatureContext.php" containing: Given a context file "features/bootstrap/FeatureContext.php" containing:
""" """
<?php <?php
@@ -28,7 +29,15 @@ Feature: Injecting parameters into context
} }
} }
""" """
And an application kernel injecting a parameter into the FeatureContext class And an application kernel configured for SymfonyExtension with YAML services file containing:
"""
services:
FeatureContext:
class: FeatureContext
public: true
arguments:
- "%kernel.environment%"
"""
And a Behat configuration with the minimal working configuration for SymfonyExtension And a Behat configuration with the minimal working configuration for SymfonyExtension
And a Behat configuration with the minimal working configuration for MinkExtension And a Behat configuration with the minimal working configuration for MinkExtension

View File

@@ -1,9 +1,33 @@
Feature: Running bare Behat scenarios Feature: Running bare Behat scenarios
Scenario: Running Behat with SymfonyExtension Scenario: Running Behat with SymfonyExtension
Given a Behat configuration with the minimal working configuration for SymfonyExtension Given a working Symfony application with SymfonyExtension configured
And a Behat configuration with the minimal working configuration for MinkExtension And a Behat configuration containing:
And an application kernel with the minimal working configuration for SymfonyExtension """
And a feature file with passing scenario default:
suites:
default:
contexts:
- App\Tests\SomeContext
"""
And a feature file containing:
"""
Feature:
Scenario:
Then it should pass
"""
And a context file "tests/SomeContext.php" containing:
"""
<?php
namespace App\Tests;
use Behat\Behat\Context\Context;
final class SomeContext implements Context {
/** @Then it should pass */
public function itShouldPass(): void {}
}
"""
When I run Behat When I run Behat
Then it should pass Then it should pass

View File

@@ -36,6 +36,9 @@ final class SymfonyExtension implements Extension
*/ */
private const DRIVER_KERNEL_ID = 'fob_symfony.driver_kernel'; private const DRIVER_KERNEL_ID = 'fob_symfony.driver_kernel';
/** @var bool */
private $minkExtensionFound = false;
public function getConfigKey(): string public function getConfigKey(): string
{ {
return 'fob_symfony'; return 'fob_symfony';
@@ -43,7 +46,14 @@ final class SymfonyExtension implements Extension
public function initialize(ExtensionManager $extensionManager): void public function initialize(ExtensionManager $extensionManager): void
{ {
$this->registerSymfonyDriverFactory($extensionManager); /** @var MinkExtension|null $minkExtension */
$minkExtension = $extensionManager->getExtension('mink');
if (null === $minkExtension) {
return;
}
$minkExtension->registerDriverFactory(new SymfonyDriverFactory('symfony', new Reference(self::DRIVER_KERNEL_ID)));
$this->minkExtensionFound = true;
} }
public function configure(ArrayNodeDefinition $builder): void public function configure(ArrayNodeDefinition $builder): void
@@ -75,9 +85,11 @@ final class SymfonyExtension implements Extension
$this->loadEnvironmentHandler($container); $this->loadEnvironmentHandler($container);
if ($this->minkExtensionFound) {
$this->loadMinkDefaultSession($container); $this->loadMinkDefaultSession($container);
$this->loadMinkParameters($container); $this->loadMinkParameters($container);
} }
}
public function process(ContainerBuilder $container): void public function process(ContainerBuilder $container): void
{ {
@@ -166,15 +178,4 @@ final class SymfonyExtension implements Extension
$container->setDefinition('fob_symfony.mink.parameters', $minkParametersDefinition); $container->setDefinition('fob_symfony.mink.parameters', $minkParametersDefinition);
} }
private function registerSymfonyDriverFactory(ExtensionManager $extensionManager): void
{
/** @var MinkExtension|null $minkExtension */
$minkExtension = $extensionManager->getExtension('mink');
if (null === $minkExtension) {
return;
}
$minkExtension->registerDriverFactory(new SymfonyDriverFactory('symfony', new Reference(self::DRIVER_KERNEL_ID)));
}
} }

View File

@@ -59,13 +59,77 @@ final class TestContext implements Context
self::$filesystem->remove(self::$workingDir); self::$filesystem->remove(self::$workingDir);
} }
/**
* @Given a working Symfony application with SymfonyExtension configured
*/
public function workingSymfonyApplicationWithExtension(): void
{
$this->thereIsConfiguration(<<<'CON'
default:
extensions:
FriendsOfBehat\SymfonyExtension:
kernel:
class: App\Kernel
CON
);
$this->thereIsFile('vendor/autoload.php', sprintf(<<<'CON'
<?php
declare(strict_types=1);
$loader = require '%s';
$loader->addPsr4('App\\', __DIR__ . '/../src/');
$loader->addPsr4('App\\Tests\\', __DIR__ . '/../tests/');
return $loader;
CON
, __DIR__ . '/../../../vendor/autoload.php'));
$this->thereIsFile('src/Kernel.php', <<<'CON'
<?php
namespace App;
use Symfony\Component\HttpKernel\Kernel as HttpKernel;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\Config\Loader\LoaderInterface;
class Kernel extends HttpKernel
{
public function registerBundles()
{
return [
new \Symfony\Bundle\FrameworkBundle\FrameworkBundle(),
new \FriendsOfBehat\SymfonyExtension\Bundle\FriendsOfBehatSymfonyExtensionBundle(),
];
}
public function registerContainerConfiguration(LoaderInterface $loader)
{
$loader->load(function (ContainerBuilder $container): void {
$container->loadFromExtension('framework', [
'test' => $this->getEnvironment() === 'test',
'secret' => 'Pigeon',
]);
});
$loader->load(__DIR__ . '/../config/services.yaml');
}
}
CON
);
$this->thereIsFile('config/services.yaml', '');
}
/** /**
* @Given /^a Behat configuration containing(?: "([^"]+)"|:)$/ * @Given /^a Behat configuration containing(?: "([^"]+)"|:)$/
*/ */
public function thereIsConfiguration($content): void public function thereIsConfiguration($content): void
{ {
$mainConfigFile = sprintf('%s/behat.yml', self::$workingDir); $mainConfigFile = sprintf('%s/behat.yml', self::$workingDir);
$newConfigFile = sprintf('%s/behat-%s.yml', self::$workingDir, md5($content)); $newConfigFile = sprintf('%s/behat-%s.yml', self::$workingDir, md5((string) $content));
self::$filesystem->dumpFile($newConfigFile, (string) $content); self::$filesystem->dumpFile($newConfigFile, (string) $content);
@@ -79,21 +143,6 @@ final class TestContext implements Context
self::$filesystem->dumpFile($mainConfigFile, Yaml::dump($mainBehatConfiguration)); self::$filesystem->dumpFile($mainConfigFile, Yaml::dump($mainBehatConfiguration));
} }
/**
* @Given /^a Behat configuration with the minimal working configuration for SymfonyExtension$/
*/
public function thereIsConfigurationWithMinimalWorkingConfigurationForSymfonyExtension(): void
{
$this->thereIsConfiguration(<<<'CON'
default:
extensions:
FriendsOfBehat\SymfonyExtension:
kernel:
path: app/AppKernel.php
class: AppKernel
CON
);
}
/** /**
* @Given /^a Behat configuration with the minimal working configuration for MinkExtension$/ * @Given /^a Behat configuration with the minimal working configuration for MinkExtension$/
@@ -121,84 +170,6 @@ CON
self::$filesystem->dumpFile(self::$workingDir . '/' . $file, (string) $content); self::$filesystem->dumpFile(self::$workingDir . '/' . $file, (string) $content);
} }
/**
* @Given /^an application kernel with the minimal working configuration for SymfonyExtension$/
*/
public function thereIsKernelWithMinimalWorkingConfiguration(): void
{
$this->thereIsFile('app/AppKernel.php', <<<'CON'
<?php
use Symfony\Component\HttpKernel\Kernel;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\Config\Loader\LoaderInterface;
class AppKernel extends Kernel
{
public function registerBundles()
{
return [
new \Symfony\Bundle\FrameworkBundle\FrameworkBundle(),
new \FriendsOfBehat\SymfonyExtension\Bundle\FriendsOfBehatSymfonyExtensionBundle(),
];
}
public function registerContainerConfiguration(LoaderInterface $loader)
{
$loader->load(function (ContainerBuilder $container): void {
$container->loadFromExtension('framework', [
'test' => $this->getEnvironment() === 'test',
'secret' => 'Pigeon',
]);
});
}
}
CON
);
}
/**
* @Given /^an application kernel injecting a parameter into the FeatureContext class$/
*/
public function thereIsKernelInjectingParameterIntoFeatureContextClass(): void
{
$this->thereIsFile('app/AppKernel.php', <<<'CON'
<?php
use Symfony\Component\HttpKernel\Kernel;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\Config\Loader\LoaderInterface;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Parameter;
class AppKernel extends Kernel
{
public function registerBundles()
{
return [
new \Symfony\Bundle\FrameworkBundle\FrameworkBundle(),
new \FriendsOfBehat\SymfonyExtension\Bundle\FriendsOfBehatSymfonyExtensionBundle(),
];
}
public function registerContainerConfiguration(LoaderInterface $loader)
{
$loader->load(function (ContainerBuilder $container): void {
$container->loadFromExtension('framework', [
'test' => $this->getEnvironment() === 'test',
'secret' => 'Pigeon',
]);
$contextDefinition = new Definition(FeatureContext::class, [new Parameter('kernel.environment')]);
$contextDefinition->setAutoconfigured(true);
$container->setDefinition(FeatureContext::class, $contextDefinition);
});
}
}
CON
);
}
/** /**
* @Given /^a feature file containing(?: "([^"]+)"|:)$/ * @Given /^a feature file containing(?: "([^"]+)"|:)$/
*/ */
@@ -207,110 +178,6 @@ CON
$this->thereIsFile(sprintf('features/%s.feature', md5(uniqid('', true))), $content); $this->thereIsFile(sprintf('features/%s.feature', md5(uniqid('', true))), $content);
} }
/**
* @Given /^a feature file with passing scenario$/
*/
public function thereIsFeatureFileWithPassingScenario(): void
{
$this->thereIsFile('features/bootstrap/FeatureContext.php', <<<'CON'
<?php
declare(strict_types=1);
class FeatureContext implements \Behat\Behat\Context\Context
{
/** @Then it passes */
public function itPasses() {}
}
CON
);
$this->thereIsFeatureFile(<<<FEA
Feature: Passing feature
Scenario: Passing scenario
Then it passes
FEA
);
}
/**
* @Given /^a feature file with failing scenario$/
*/
public function thereIsFeatureFileWithFailingScenario(): void
{
$this->thereIsFile('features/bootstrap/FeatureContext.php', <<<'CON'
<?php
declare(strict_types=1);
class FeatureContext implements \Behat\Behat\Context\Context
{
/** @Then it fails */
public function itFails() { throw new \RuntimeException(); }
}
CON
);
$this->thereIsFeatureFile(<<<FEA
Feature: Failing feature
Scenario: Failing scenario
Then it fails
FEA
);
}
/**
* @Given /^a feature file with scenario with missing step$/
*/
public function thereIsFeatureFileWithScenarioWithMissingStep(): void
{
$this->thereIsFile('features/bootstrap/FeatureContext.php', <<<'CON'
<?php
declare(strict_types=1);
class FeatureContext implements \Behat\Behat\Context\Context {}
CON
);
$this->thereIsFeatureFile(<<<FEA
Feature: Feature with missing step
Scenario: Scenario with missing step
Then it does not have this step
FEA
);
}
/**
* @Given /^a feature file with scenario with pending step$/
*/
public function thereIsFeatureFileWithScenarioWithPendingStep(): void
{
$this->thereIsFile('features/bootstrap/FeatureContext.php', <<<'CON'
<?php
declare(strict_types=1);
class FeatureContext implements \Behat\Behat\Context\Context
{
/** @Then it has this step as pending */
public function itFails() { throw new \Behat\Behat\Tester\Exception\PendingException(); }
}
CON
);
$this->thereIsFeatureFile(<<<FEA
Feature: Feature with pending step
Scenario: Scenario with pending step
Then it has this step as pending
FEA
);
}
/** /**
* @When /^I run Behat$/ * @When /^I run Behat$/
*/ */