behat internals for advanced usage. symfony camp 2016

Post on 13-Apr-2017

41 Views

Category:

Software

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

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/

top related