Behat internals for advanced usage. Symfony Camp 2016
-
Upload
sergey-polischook -
Category
Software
-
view
44 -
download
0
Transcript of Behat internals for advanced usage. Symfony Camp 2016
Serhii Polishchukspolishchuk[at]oroinc.com
Behat Internalsfor advanced usage
Behat Internals for advanced usage
What I'm tolking aboutTale of contents
● Part1. BDD. Common understanding● Part2. Behat. Inside Out● Part3. Behat+Oro. UI tests implementation
Behat Internals for advanced usage
BDD. Common understandingUnderstanding is deeper than knowledge
● TLD. TDD. BDD.● Two Common Issues.● Who know everything about bugs?● Most wrong thing that ever happen in BDD.● Introducing Gherkin
BDD. Common understanding
TLD. TDD.Write tests before of fafter code?
http://compilehorrors.com/test-driven-development-tdd-vs-test-last-development-tld-a-comparative-study/
● Time required● Learning curve● Code Size● Tests stability
BDD. Common understanding
BDD.You might don't understand code of library, but you should understand the Behavior
BDD. Common understanding
Two Common IssuesIn a any kind of project
1. Building software right2. Building right software
BDD. Common understanding
Building software right
● Design Patterns● SOLID● Tests● Continuous Integration● Deploy● Semantic Versioning
BDD. Common understanding
Building right software
John Ferguson Smart. BDD In action
“According to the Standish Group’s CHAOS studies, on average some 45% of the features delivered into production are never used.”
BDD. Common understanding
Building right software
BDD. Common understanding
Who know everything about bugs?
BDD. Common understanding
Who know everything about bugs?QA know what bugs will happen before developing will finished
BDD. Common understanding
Finally we are all togetherBI, QA and developer can understand each other better, using one unified language
BDD. Common understanding
The most wrong thing that ever happen in BDDBecause it made it usable.
10 years of Doing Behaviour-Driven Development All Wrong (part 1) by Liz Keogh https://youtu.be/2EM4itu7j7I
BDD. Common understanding
Introducing GherkinThe lenguage that we can use to discuss of behavior of your system
Cucumber reference https://cucumber.io/docs/reference
Feature: Refund item
Scenario: Jeff returns a faulty microwave
Given Jeff has bought a microwave for $100
And he has a receipt
When he returns the microwave
Then Jeff should be refunded $100
Behat Internals for advanced usage
Behat. Inside Out
● PHP callback matching● From Console to Browser● Behat as symfony console application● Behat Configuration● Behat Extensions● Behat Controllers● Event Dispatching● Context Initializers
Behat. Inside Out
PHP callback matchingEvery feature step matched to php callback
Behat. Inside Out
From Console to Browser
Behat. Inside Out
Behat as symfony console applicationWith single command
● Create DI Container and process configuration through Extensions● Create behat command and add to application● Command run Controllers in selected order● Controller can return integer status for interrupt execution● ExerciseController collect features and test its
Behat. Inside Out
Behat Extensionsnamespace Behat\Testwork\ServiceContainer;
interface Extension extends CompilerPassInterface{ public function getConfigKey();
public function initialize(ExtensionManager $extensionManager);
public function configure(ArrayNodeDefinition $builder);
public function load(ContainerBuilder $container, array $config);}
namespace Symfony\Component\DependencyInjection\Compiler;
interface CompilerPassInterface{ public function process(ContainerBuilder $container);}
Behat. Inside Out
Behat Extensions
● EnvironmentExtension● GherkinExtension● OutputExtension● TranslatorExtension● ContextExtension● SnippetExtension● MinkExtension● Symfony2Extension● OroTestFrameworkExtension
https://git.io/vXIXC OroTestFrameworkExtension
Behat. Inside Out
Behat Configuration
bin/behat --config-reference Display the configuration reference
default: &default extensions: Behat\MinkExtension: base_url: 'http://localhost.com/' default_session: 'first_session' sessions: second_session: oroSelenium2: wd_host: "http://localhost:8643/wd/hub" first_session: oroSelenium2: wd_host: "http://localhost:8643/wd/hub" Behat\Symfony2Extension: kernel: env: 'prod' debug: false context: path_suffix: 'Tests/Behat/Features' class_suffix: 'Tests\Behat\Context\FeatureContext' Oro\Bundle\TestFrameworkBundle\Behat\ServiceContainer\OroTestFrameworkExtension: shared_contexts: - Oro\Bundle\TestFrameworkBundle\Tests\Behat\Context\OroMainContext - Oro\Bundle\TestFrameworkBundle\Tests\Behat\Context\FixturesContext - Oro\Bundle\ActivityListBundle\Tests\Behat\Context\ActivityContext - Oro\Bundle\DataGridBundle\Tests\Behat\Context\GridContext - Oro\Bundle\SecurityBundle\Tests\Behat\Context\ACLContext suites: []
selenium2: <<: *default extensions: Behat\MinkExtension: sessions: second_session: oroSelenium2: wd_host: 'http://localhost:4444/wd/hub' first_session: oroSelenium2: wd_host: 'http://localhost:4444/wd/hub'
Behat. Inside Out
Behat Controllersnamespace Behat\Testwork\Cli;
final class Command extends \Symfony\Component\Console\Command\Command{ private $controllers = array();
public function __construct($commandName, array $controllers) { $this->controllers = $controllers;
parent::__construct($commandName); }
protected function configure() { foreach ($this->controllers as $controller) { $controller->configure($this); } }
protected function execute(InputInterface $input, OutputInterface $output) { foreach ($this->controllers as $controller) { if (is_int($return = $controller->execute($input, $output))) { return $return; } }
return 0; }}
Behat. Inside Out
Behat Controllers
namespace Behat\Testwork\Cli;
interface Controller{ public function configure(SymfonyCommand $command);
public function execute(InputInterface $input, OutputInterface $output);}
cli.controller.mesure_execution_time: class: Oro\Bundle\TestFrameworkBundle\Behat\Cli\MeasureExecutionTimeController arguments: - '@oro_test.listener.step_duration_measure_subscriber' - '@event_dispatcher' tags: - { name: 'cli.controller', priority: 1100 }
Behat Controller Definition
Behat. Inside Out
Behat Controllersclass AvailableSuitesController implements Controller{ private $suiteRepository;
public function __construct(SuiteRepository $suiteRepository) { $this->suiteRepository = $suiteRepository; }
public function configure(SymfonyCommand $command) { $command ->addOption( '--available-suites', null, InputOption::VALUE_NONE, 'Show all available test suites.'.PHP_EOL. 'Suites can be configured automatically by extensions, and manually by configuration' ); }
public function execute(InputInterface $input, OutputInterface $output) { if (false === $input->getOption('available-suites')) { return; }
foreach ($this->suiteRepository->getSuites() as $suite) { $output->writeln($suite->getName()); }
return 0; }}
Behat. Inside Out
Behat Controllers
● ExerciseController● RerunController● OrderController● AvailableDefinitionsController● FilterController● InitializationController● OutputController● LanguageController● VerbosityController● MeasureExecutionTimeController
Behat. Inside Out
Event Dispatching
Behat. Inside Out
Context InitializersModify context in runtime
namespace Behat\Behat\Context\Initializer;
interface ContextInitializer{ public function initializeContext(Context $context);}
Behat. Inside Out
Context InitializersModify context in runtime
namespace Oro\Bundle\TestFrameworkBundle\Behat\Context\Initializer;
class FixtureLoaderInitializer implements ContextInitializer{ protected $fixtureLoader;
public function __construct(FixtureLoader $fixtureLoader) { $this->fixtureLoader = $fixtureLoader; }
public function initializeContext(Context $context) { if ($context instanceof FixtureLoaderAwareInterface) { $context->setFixtureLoader($this->fixtureLoader); } }}
Behat. Inside Out
Context InitializersModify context in runtime
oro_behat_fixture_loader_initializer: class: Oro\Bundle\TestFrameworkBundle\Behat\Context\Initializer\FixtureLoaderInitializer arguments: - '@oro_test.context.fixture_loader' tags: - { name: 'context.initializer' }
Behat Internals for advanced usage
Behat+Oro. UI tests implementation
● Gherkin syntax. Hunt the value● Gherkin syntax. Scenario definition● Gherkin syntax. Examples● Gherkin syntax. Tables● ACL● Elements. What is element● Elements. Describing element● Pages● Inline fixtures● Alice fixtures● Performance● Tests stability
Behat+Oro. UI tests implementation
Gherkin syntaxHunt the value
Behat+Oro. UI tests implementation
Gherkin syntaxScenario definition
Behat+Oro. UI tests implementation
Gherkin syntaxExamples
Behat+Oro. UI tests implementation
Gherkin syntaxTables
Behat+Oro. UI tests implementation
ACLSeveral users in one scenario
Behat+Oro. UI tests implementation
ElementsWhat is element
Behat+Oro. UI tests implementation
ElementsDescribing element
Behat+Oro. UI tests implementation
Pages
For CRUD pages:● Index page - for list entities with grid● Create page - for page with empty form● Edit page - needs entity title for open● View page - needs entity title for open
Other pages can have any other name
Behat+Oro. UI tests implementation
Inline fixturesWrite fixtures right in scenarios
Behat+Oro. UI tests implementation
Inline fixturesWrite fixtures right in scenarios
Behat+Oro. UI tests implementation
Alice fixturesWrite complicated fixtures with dependencies in yml files
https://github.com/nelmio/alice
Behat+Oro. UI tests implementation
Performanceapplication load + selenium ≈ 90% of test time
Behat+Oro. UI tests implementation
Tests stability
Behat Internals for advanced usage
Q/A
Behat Internals for advanced usage
REFERENCES
● 10 years of Doing Behaviour-Driven Development All Wrong by Liz Keogh https://www.youtube.com/watch?v=2EM4itu7j7I
● Bdd in action by John Ferguson Smart https://www.manning.com/books/bdd-in-action ● Interview with Dan North on Behavior-Driven Development
https://www.youtube.com/watch?v=qWsnmx45734 ● About BDD at Liz Keogh official site https://lizkeogh.com/behaviour-driven-development/ ● Cucumber reference https://cucumber.io/docs/reference ● http://blog.standishgroup.com/ ● Behat in Oro https://github.com/orocrm/platform/tree/master/src/Oro/Bundle/TestFrameworkBundle/Behat ● Behat - A php framework for autotesting your business expectations. http://behat.org/en/latest/