SlideShare ist ein Scribd-Unternehmen logo
1 von 80
Concise guide to starting
with Behat
Berend de Boer, Xplain Hosting
awesome and affordable Drupal hosting
About me
● First Drupal programmer in New Zealand (2004).
● Host small Drupal sites on Xplain Hosting.
● Large sites: custom setup on AWS; interest.co.nz / LJHooker New
Zealand
Ever touched an old website
and you had no way of telling
everything still worked without
testing everything?
In this talk
● What is Behat?
● How do you get started with Behat?
● How to write tests?
● How to write good tests!
● How to write portable tests, and other common problems.
What is Behat?
Behat allow you to test your entire website.
Behat sees your site just as a customer or tester would. You can even use
an actual browser.
Techie definition:
A php framework
for autotesting
your business expectations.
So how does it work?
Run first test:
behat features/test1.feature
First peek at script test1.feature
Feature: Gain privileged access to site
Scenario: User logs in as admin
Given I am on the homepage
When I follow "Log in"
And I fill in "Username" with "berend"
And I fill in "Password" with "abc123"
And I press "Log in"
Then I should be on "/user/1"
And I should see "Member for"
Goal
● Test entire website.
● As a visitor.
● Readable test: readable by stakeholders.
● Test should not be brittle: if you break your tests all the time, they
won’t be used.
● If your test passes, you can promise the minimum (possibly maximum!)
your website can do.
● Automated.
Install
Install
Don’t install Behat, install the Drupal Extension for Behat.
See here: http://behat-drupal-
extension.readthedocs.io/en/3.1/localinstall.html
Drupal 7/8:
composer require --dev drupal/drupal-extension:dev-master
vendor/bin/behat --init
(Creates features/bootstrap/FeatureContext.php. We’ll come back to that.)
Finally create behat.yml.
behat.yml
default:
suites:
default:
contexts: ...
extensions:
BehatMinkExtension:
goutte: ~
selenium2:
#browser: firefox
browser: chrome
base_url: http://drupalsouth2017.local
DrupalDrupalExtension:
blackbox: ~
Other pieces of the magic
1. Selenium: you must download the “Selenium Standalone Server”
server: http://www.seleniumhq.org/download/
2. And run that with:
java -jar selenium-server-standalone-3.14.0.jar
3. You need a browser specific driver:
a. chromedriver: https://sites.google.com/a/chromium.org/chromedriver/
b. geckodriver: https://github.com/mozilla/geckodriver/releases
4. geckodriver/chromedriver must be in your PATH.
How to write a Behat test
Feature: Gain privileged access to site
Scenario: User logs in as admin
Given I am on the homepage
When I follow "Log in"
And I fill in "Username" with "berend"
And I fill in "Password" with "abc123"
And I press "Log in"
Then I should be on "/user/1"
And I should see "Member for"
.feature file
● File starts with keyword Feature.
● A feature contains one or more Scenarios.
● A scenario contains one or more Steps.
● A step starts with Given, When or Then.
● Extend a step with And or But.
This is actually a language: the Gherkin language.
Goal when writing Gherkin: Business Readable, Domain Specific Language
Feature
When writing a feature:
Feature <name>
<description>
All free format.
Scenario
All scenarios follow this pattern:
1. Get the system into a particular state.
2. Poke it (or tickle it, or …).
3. Examine the new state.
Steps
We use Given to set up the context where the scenario happens, When to
interact with the system somehow, and Then to check that the outcome of
that interaction was what we expected.
Cucumber doesn’t technically distinguish between these three kind of
steps. However, I strongly recommend that you do!
What steps are there?
Behat + Mink come with certain “out of the box” steps:
behat -dl
You can filter them:
behat -d message
Login example
Feature: Gain privileged access to site
Scenario: User logs in as admin
Given I am on the homepage
When I follow "Log in"
And I fill in "Username" with "berend"
And I fill in "Password" with "abc123"
And I press "Log in"
Then I should be on "/user/1"
And I should see "Member for"
Background
Repeating log in steps for every scenario is not good practice: don’t repeat
yourself in programming.
One way to improve this is by using Background: follows Feature, comes
before Scenario.
Background is run before every Scenario in a Feature.
Background example
1. Feature: Adding content
2. Background:
3. When I go to "/user/login"
4. And I fill in "Username" with "berend"
5. And I fill in "Password" with "abc123"
6. And I press "Log in"
7. Then I should be on "/user/1"
8. Scenario: Admin can add content
9. Given I go to "/node/add/page"
10. Then I should see "Not saved yet"
Custom step
Feature: Gain privileged access to site
Scenario: User logs in as admin
Given I am on the homepage
And I follow "Log in"
And I fill in "Username" with "berend"
And I fill in "Password" with "abc123"
And I press "Log in"
When I login
Then I should be on "/user/1"
Problems:
● We need to repeat the login steps for every scenario that needs login.
● username/password hard-coded.
Enter the Drupal driver.
Drupal driver
Drupal driver
Remember this bit from behat.yml?
DrupalDrupalExtension:
blackbox: ~
blackbox is the default driver: no special permissions. Two other drivers:
● Drupal API driver: full programmatic access to Drupal in your own steps.
Only local site.
● Drush driver: uses Drush to access site.
Can work against a remote site.
Install Drupal driver
Add driver to our composer requirements:
composer require --dev drupal/drupal-driver:dev-master
You can now pick your driver:
DrupalDrupalExtension:
blackbox: ~
api_driver: ["drush" | "drupal" ]
Almost there!
@api tag
Finally you need the @api tag in your .feature:
@api
Feature: Gain privileged access to site
If you forget you get a nice message:
No ability to generate random in DrupalDriverBlackboxDriver. Put `@api`
into your feature and add an API driver (ex: `api_driver: drupal`) in behat.yml.
(DrupalDriverExceptionUnsupportedDriverActionException)
Example with Drupal driver
1. @api
2. Feature: Gain privileged access to site
3. Scenario: User logs in as admin
4. Given I am logged in as an "administrator"
A lot shorter! And shorter is better.
Create custom step
Take a look at this:
Scenario: User logs in as admin
Given I am logged in as an "Authenticated user"
And my profile has been filled in
When ...
Behat doesn’t know about this step, but nicely generates a snippet.
Pending step
use BehatBehatTesterExceptionPendingException;
/**
* @Given my profile has been filled in
*/
public function myProfileHasBeenFilledIn() {
throw new PendingException();
}
Steps: doc
Behat uses php-doc annotations to bind patterns to FeatureContext
methods:
1. Comment must start with: /**
2. Write definition keyword: @Given/@When/@Then.
3. The text after the keyword is the step text pattern: I do something
with :argument.
4. All token values of the pattern (e.g. :argument) will be captured and
passed to the method argument with the same name : $argument.
DrupalContext.php
All step definitions are done that way, even the “built-in” steps.
/**
* Creates and authenticates a user with the given role(s).
*
* @Given I am logged in as a user with the :role role(s)
* @Given I am logged in as a/an :role
*/
public function assertAuthenticatedByRole($role) {
}
Back to pending step
use BehatBehatTesterExceptionPendingException;
/**
* @Given my profile has been filled in
*/
public function myProfileHasBeenFilledIn() {
throw new PendingException();
}
Implement step
Possible implementation (simplified):
public function myProfileHasBeenFilledIn() {
$this->assertClick('Edit');
$this->assertUncheckBox('Personal contact form');
$this->selectOption('Time zone', 'UTC');
$this->pressButton('Save');
$this->assertSuccessMessage('The changes have been
saved.');
}
Finding methods
What existing Mink methods to call exactly is outside the scope of this talk.
But use this a lot:
behat -d click
default | [When|*] I click :link
| at
`DrupalDrupalExtensionContextMinkContext::assertClick()`
How to write good Behat tests
Twitter test
Scenario: Retweet
Given I am on the homepage.
When I fill in “What’s happening” with “Hello World”
And I press “Tweet 1”
And I click “Reply”
And I fill in “Tweet your reply” with “Tweet 2”
And press “Reply”
Then “Replies” should be “1”
Better Twitter test
Scenario: Retweet
When I tweet “Hello World”
And I reply to my last tweet with “Tweet 2”
Then “Replies” should be “1”
Account creation steps
But sometimes writing out all the clicks is good! Would you sign up for this
site?
Scenario:
Given I am on a news article page
When I click “comment”
Then I should see “You must be logged in.”
Account creation steps
When I click on “Create account”
And fill in “Email” with “berend@example.com”
And I fill in “Password” with “abc123”
And I check “I am not a robot”
And I click all the street signs
And I click all the street signs again
And again
And I wait for the confirmation email to arrive
Account creation steps
And I click on the link in the confirmation email
And I click on “Login”
And I fill in “Email” with “berend@example.com”
And I fill in “Password” with “abc123”
And I click “Login”
And I find my original news article again.
And I click on “comment”
And I fill in “Comment” with “Finally”
And I press “Save”
Then I appear to be very keen to comment
A better way
Using Behat well:
● Seldom use built-in steps.
● Write your own steps.
● Avoid brittle steps.
● Write steps business analysts can understand.
Sequence to avoid
Don’t:
Scenario: ...
Given ...
And ...
Then ...
Always use this order: Given ... When ... Then.
How to get your company to do
Behat
Get started
● When a bug is reported
● Then write the test that replicates it.
● And the test should fail.
1 scenario (1 failed)
2 steps (1 passed, 1 failed)
● When the bug if fixed.
● Then test should pass.
1 scenario (1 passed)
2 steps (2 passed)
Gherkin’s purposes
Gherkin serves three purposes:
1. documentation and,
2. acceptance tests
3. Bonus: when it yells in red it's talking to you, telling you what code you
should write.
New projects
For new projects:
● Write all requirements as scenarios.
● Implement all steps as deferred.
And my profile has been filled in # FeatureContext::myProfile()
TODO: write pending definition
1 scenario (1 pending)
2 steps (1 passed, 1 pending)
● When they all pass, your project is done. Allows progress tracking!
Not a bug, just a missing scenario
One of the wonderful things I discovered when I first used Cucumber to build a
complete application from the outside-in was when we started manual
exploratory testing and discovered some bugs. Almost without exception, every
one of those bugs could be traced back to a gap in the Cucumber scenarios we’d
written for that part of the system.
Because we’d written the scenarios collaboratively, with businesspeople and
developers working together to get them right, it wasn’t anybody’s fault that
there was a bug. It was just an edge case we hadn’t originally anticipated
Not a bug, just a missing scenario
In my experience, bugs are a big source of friction and unhappiness in software
teams.
Businesspeople blame them on careless developers, and developers blame
them on inadequate requirements from the businesspeople. Actually they’re just
a natural consequence of software development being a really complex
endeavor.
Using Cucumber really helped the team see that closing these gaps is everyone’s
job. The blaming just didn’t happen, and we were a much happier team as a
result.
Who writes features?
Why not let analysts and stakeholders write features?
You as a developer can implement the steps.
How to:
answers to common problems
when using Behat
How to run a single feature
You seldom want to run all features in all scenarios.
1. Run all scenarios of a feature:
behat features/test.feature
2. Run a single scenario:
behat features/test.feature:35
where 35 is the line number of the scenario you want to run.
Transform
1. Scenario: user must validate email before he can login
2. Given the user has created an account
3. When the user attempts to login
4. Then he is informed that his email is not yet validated
5. When the validation email is received
6. And the user visits the “the first link in the email”
7. Then the user can login successfully
Transform function
/**
* @Transform /^the first link in the last email$/
*/
public function castFirstLinkInLastEmail() {
return $this->first_link_in_last_email;
}
Tags - @javascript
Normally you don’t see the browser coming up.
In my live demos that happened, because I used this tag:
@javascript
Feature: ...
can be used both for all scenarios (specify above feature), or per scenario.
Prevent browser from closing
Edit: vendor/behat/mink-selenium2-
driver/src/Selenium2Driver.php
1. public function stop()
2. …
3. $this->started = false;
4. try {
5. $this->wdSession->close();
6. }
7. catch (Exception $e) {
8. …
9. }
Tags - in FeatureContext
FeatureContext is the default class for your steps.
With these tags you can write initialisation and cleanup code:
● @BeforeSuite: run once
● @AfterSuite: run once
● @BeforeScenario: once every scenario
● @AfterScenario: once every scenario
About hooks: http://behat.org/en/latest/user_guide/context/hooks.html
A copy of your production environment may have modules enabled that
make testing hard. Disable them before a run:
use BehatTestworkHookScopeBeforeSuiteScope;
/**
* @BeforeSuite
*/
public static function setup(BeforeSuiteScope $scope) {
module_disable (array ('mollom', 'honeypot'), FALSE);
}
Disable modules - D7
Uninstall modules - D8
In Drupal 8 you can only uninstall:
use BehatTestworkHookScopeBeforeSuiteScope;
/**
* @BeforeSuite
*/
public static function setup(BeforeSuiteScope $scope) {
Drupal::service('module_installer')->uninstall(['mollom']);
}
Regions - behat.yml
Often you want to check for the existence of text or links in particular
“regions” (main region, sidebar, header, footer).
Define them in behat.yml with:
extensions:
DrupalDrupalExtension:
region_map:
content: ".block-system-main-block"
footer: ".site-footer"
Regions - scenario
Scenario: User logs in as admin
Given I am on the homepage
Then I should see "No front page content has been created
yet." in the content region
Portable tests - behat.yml
Write portable tests, don’t hard-code:
One way is to put variables in behat.yml:
default:
suites:
default:
contexts:
- FeatureContext:
inbox:
server: mail.example.com
user: behat
password: abc123
arg2: “This”
Portable tests - __construct()
Your parameters are passed in order you defined, make sure argument
names match:
class FeatureContext extends RawDrupalContext {
public function __construct($inbox, $arg2, $arg3) {
$this->inbox = $parameters['inbox'];
$this->arg2 = $parameters['arg2'];
$this->arg3 = $parameters['arg3'];
}
Environment settings
Environment specific settings can go in environment variable:
BEHAT_PARAMS.
This is a JSON string, more: http://behat-drupal-
extension.readthedocs.io/en/3.1/environment.html
Another Context
Your FeatureContext can become very big very quickly.
You can put code in another context, and new steps will become available.
For example create features/bootstrap/CKEditorContext.php.
class CKEditorContext extends RawMinkContext {
/**
* @Given I fill in the rich text editor :arg1 with :arg2
*/
public function iFillInTheRichTextEditorWith($arg1, $arg2) {
}
Context - behat.yml
Make sure we can find the context by adding it to behat.yml:
default:
suites:
default:
contexts:
- FeatureContext
- ...
- CKEditorContext
Subcontexts - behat.yml
Modules can also make steps available. Setup subcontexts in behat.yml
so behat can find them:
DrupalDrupalExtension:
...
subcontexts:
paths:
- "modules/custom/behat_test"
Subcontexts - php
Define a .behat.inc file in your module such
modules/custom/behat_test/behat_test.behat.inc.
use DrupalDrupalExtensionContextDrupalSubContextBase;
use DrupalDrupalExtensionContextDrupalSubContextInterface;
class BehatTest extends DrupalSubContextBase implements
DrupalSubContextInterface {
/**
* @Given I do something interesting
*/
public function iDoSomethingInteresting() {
}
Finding elements
Often you will need to find elements on a page (input fields, buttons).
Two ways to find them:
● CSS: easier to write.
● XPath: more powerful.
$el = $this->elementTextContains('css', 'h1', 'Payment
processing');
$el = $this->elementTextContains('xpath, '//h1',
'Payment processing');
Headless
Mink provides the web site integration for Behat. Drivers:
● Headless, without support for JavaScript: Goutte.
● Headless, with support for JavaScript: ZombieDriver.
● Headless actual browser: PhantomJS.
● Actual browser: Selenium2Driver.
And more differences: http://mink.behat.org/en/latest/guides/drivers.html
Show failed test in browser
Test in actual browser can be quite slow. But if headless fails, what that?
What happpened?
extensions:
BehatMinkExtension:
zombie:
show_auto: true
show_cmd: "firefox-trunk %s"
Execute javascript
Our UIs can get very fancy with javascript controls. Hard to test.
Run JavaScript from your step definition:
/**
* @Given I fill in the rich text editor :arg1 with :arg2
*/
public function iFillInTheRichTextEditorWith($arg1, $arg2) {
$field = $this->getSession()->getPage()->findField($arg1);
$id = $field->getAttribute('id');
$args = ['ckeditor_instance_id' => $id, 'value' => $arg2];
$args_as_js_object = json_encode($args);
$this->getSession()->executeScript(
"args = {$args_as_js_object};" .
"CKEDITOR.instances[args.ckeditor_instance_id].setData(args.value);"
Tests stop running for no reason
When suddenly your Selenium tests don’t run anymore, it’s most likely
because you received a browser update.
What to do:
1. Update to latest chromedriver/geckodriver.
2. May need to update Selenium.
Reaping full benefits
Do you run your tests all the time?
Continuous integration
● When a change is committed
● Then spin up a new machine
● And deploy the code.
● And run all (or tagged) scenarios.
● Then there should be no failures.
Recap
Benefits
1. How often has an unmaintained website become the gate through
which secrets were stolen? (Equifax)
You can upgrade old websites, and be sure it still works.
2. You can tell how far a project is from being finished.
3. It’s very helpful when maintaining/extending a site.
4. Great tool for specifying what a site needs to do.
Resources
● Read the first 6 chapters of the book!
● Drupal Behat extension: http://behat-drupal-
extension.readthedocs.io/en/3.1/index.html
● Me: berend@xplainhosting.com
● Contact me when your business wants to get started with Behat!
Any questions?

Weitere ähnliche Inhalte

Was ist angesagt?

CICONF 2012 - Don't Make Me Read Your Mind
CICONF 2012 - Don't Make Me Read Your MindCICONF 2012 - Don't Make Me Read Your Mind
CICONF 2012 - Don't Make Me Read Your Mind
ciconf
 
Design patterns revisited with PHP 5.3
Design patterns revisited with PHP 5.3Design patterns revisited with PHP 5.3
Design patterns revisited with PHP 5.3
Fabien Potencier
 
&lt;img src="../i/r_14.png" />
&lt;img src="../i/r_14.png" />&lt;img src="../i/r_14.png" />
&lt;img src="../i/r_14.png" />
tutorialsruby
 
High Performance JavaScript (CapitolJS 2011)
High Performance JavaScript (CapitolJS 2011)High Performance JavaScript (CapitolJS 2011)
High Performance JavaScript (CapitolJS 2011)
Nicholas Zakas
 
Behavior Driven Development - How To Start with Behat
Behavior Driven Development - How To Start with BehatBehavior Driven Development - How To Start with Behat
Behavior Driven Development - How To Start with Behat
imoneytech
 
Don't RTFM, WTFM - Open Source Documentation - German Perl Workshop 2010
Don't RTFM, WTFM - Open Source Documentation - German Perl Workshop 2010Don't RTFM, WTFM - Open Source Documentation - German Perl Workshop 2010
Don't RTFM, WTFM - Open Source Documentation - German Perl Workshop 2010
singingfish
 

Was ist angesagt? (19)

orcreatehappyusers
orcreatehappyusersorcreatehappyusers
orcreatehappyusers
 
CICONF 2012 - Don't Make Me Read Your Mind
CICONF 2012 - Don't Make Me Read Your MindCICONF 2012 - Don't Make Me Read Your Mind
CICONF 2012 - Don't Make Me Read Your Mind
 
Design patterns revisited with PHP 5.3
Design patterns revisited with PHP 5.3Design patterns revisited with PHP 5.3
Design patterns revisited with PHP 5.3
 
What is HTML 5?
What is HTML 5?What is HTML 5?
What is HTML 5?
 
How to make Ajax work for you
How to make Ajax work for youHow to make Ajax work for you
How to make Ajax work for you
 
What you can do In WatiR
What you can do In WatiRWhat you can do In WatiR
What you can do In WatiR
 
Intro to html5 Boilerplate
Intro to html5 BoilerplateIntro to html5 Boilerplate
Intro to html5 Boilerplate
 
Intro to WordPress Plugin Development
Intro to WordPress Plugin DevelopmentIntro to WordPress Plugin Development
Intro to WordPress Plugin Development
 
&lt;img src="../i/r_14.png" />
&lt;img src="../i/r_14.png" />&lt;img src="../i/r_14.png" />
&lt;img src="../i/r_14.png" />
 
Learning from the Best jQuery Plugins
Learning from the Best jQuery PluginsLearning from the Best jQuery Plugins
Learning from the Best jQuery Plugins
 
Mobile HTML, CSS, and JavaScript
Mobile HTML, CSS, and JavaScriptMobile HTML, CSS, and JavaScript
Mobile HTML, CSS, and JavaScript
 
Outside-in Development with Cucumber and Rspec
Outside-in Development with Cucumber and RspecOutside-in Development with Cucumber and Rspec
Outside-in Development with Cucumber and Rspec
 
High Performance JavaScript (CapitolJS 2011)
High Performance JavaScript (CapitolJS 2011)High Performance JavaScript (CapitolJS 2011)
High Performance JavaScript (CapitolJS 2011)
 
Building mobile applications with DrupalGap
Building mobile applications with DrupalGapBuilding mobile applications with DrupalGap
Building mobile applications with DrupalGap
 
Behavior Driven Development - How To Start with Behat
Behavior Driven Development - How To Start with BehatBehavior Driven Development - How To Start with Behat
Behavior Driven Development - How To Start with Behat
 
Don't RTFM, WTFM - Open Source Documentation - German Perl Workshop 2010
Don't RTFM, WTFM - Open Source Documentation - German Perl Workshop 2010Don't RTFM, WTFM - Open Source Documentation - German Perl Workshop 2010
Don't RTFM, WTFM - Open Source Documentation - German Perl Workshop 2010
 
tut0000021-hevery
tut0000021-heverytut0000021-hevery
tut0000021-hevery
 
API Technical Writing
API Technical WritingAPI Technical Writing
API Technical Writing
 
Intro Open Social and Dashboards
Intro Open Social and DashboardsIntro Open Social and Dashboards
Intro Open Social and Dashboards
 

Ähnlich wie Behat - Drupal South 2018

php-and-zend-framework-getting-started
php-and-zend-framework-getting-startedphp-and-zend-framework-getting-started
php-and-zend-framework-getting-started
tutorialsruby
 
php-and-zend-framework-getting-started
php-and-zend-framework-getting-startedphp-and-zend-framework-getting-started
php-and-zend-framework-getting-started
tutorialsruby
 
php-and-zend-framework-getting-started
php-and-zend-framework-getting-startedphp-and-zend-framework-getting-started
php-and-zend-framework-getting-started
tutorialsruby
 
php-and-zend-framework-getting-started
php-and-zend-framework-getting-startedphp-and-zend-framework-getting-started
php-and-zend-framework-getting-started
tutorialsruby
 
Behavior & Specification Driven Development in PHP - #OpenWest
Behavior & Specification Driven Development in PHP - #OpenWestBehavior & Specification Driven Development in PHP - #OpenWest
Behavior & Specification Driven Development in PHP - #OpenWest
Joshua Warren
 

Ähnlich wie Behat - Drupal South 2018 (20)

PHPSpec & Behat: Two Testing Tools That Write Code For You (#phptek edition)
PHPSpec & Behat: Two Testing Tools That Write Code For You (#phptek edition)PHPSpec & Behat: Two Testing Tools That Write Code For You (#phptek edition)
PHPSpec & Behat: Two Testing Tools That Write Code For You (#phptek edition)
 
pnwphp - PHPSpec & Behat: Two Testing Tools That Write Code For You
pnwphp - PHPSpec & Behat: Two Testing Tools That Write Code For Youpnwphp - PHPSpec & Behat: Two Testing Tools That Write Code For You
pnwphp - PHPSpec & Behat: Two Testing Tools That Write Code For You
 
Effizientere WordPress-Plugin-Entwicklung mit Softwaretests
Effizientere WordPress-Plugin-Entwicklung mit SoftwaretestsEffizientere WordPress-Plugin-Entwicklung mit Softwaretests
Effizientere WordPress-Plugin-Entwicklung mit Softwaretests
 
Php[tek] 2016 - BDD with Behat for Beginners
Php[tek] 2016 - BDD with Behat for BeginnersPhp[tek] 2016 - BDD with Behat for Beginners
Php[tek] 2016 - BDD with Behat for Beginners
 
How to build a slack-hubot with js
How to build a slack-hubot with jsHow to build a slack-hubot with js
How to build a slack-hubot with js
 
PHP
PHP PHP
PHP
 
php-and-zend-framework-getting-started
php-and-zend-framework-getting-startedphp-and-zend-framework-getting-started
php-and-zend-framework-getting-started
 
php-and-zend-framework-getting-started
php-and-zend-framework-getting-startedphp-and-zend-framework-getting-started
php-and-zend-framework-getting-started
 
php-and-zend-framework-getting-started
php-and-zend-framework-getting-startedphp-and-zend-framework-getting-started
php-and-zend-framework-getting-started
 
php-and-zend-framework-getting-started
php-and-zend-framework-getting-startedphp-and-zend-framework-getting-started
php-and-zend-framework-getting-started
 
A Docker-based Development Environment Even I Can Understand
A Docker-based Development Environment Even I Can UnderstandA Docker-based Development Environment Even I Can Understand
A Docker-based Development Environment Even I Can Understand
 
Behavior & Specification Driven Development in PHP - #OpenWest
Behavior & Specification Driven Development in PHP - #OpenWestBehavior & Specification Driven Development in PHP - #OpenWest
Behavior & Specification Driven Development in PHP - #OpenWest
 
Behaviour Driven Development con Behat & Drupal
Behaviour Driven Development con Behat & DrupalBehaviour Driven Development con Behat & Drupal
Behaviour Driven Development con Behat & Drupal
 
Behaviour Driven Development con Behat & Drupal
Behaviour Driven Development con Behat & DrupalBehaviour Driven Development con Behat & Drupal
Behaviour Driven Development con Behat & Drupal
 
Introduce cucumber
Introduce cucumberIntroduce cucumber
Introduce cucumber
 
Getting Started with Test Automation: Introduction to Cucumber with Lapis Lazuli
Getting Started with Test Automation: Introduction to Cucumber with Lapis LazuliGetting Started with Test Automation: Introduction to Cucumber with Lapis Lazuli
Getting Started with Test Automation: Introduction to Cucumber with Lapis Lazuli
 
WordCamp SF 2011: Debugging in WordPress
WordCamp SF 2011: Debugging in WordPressWordCamp SF 2011: Debugging in WordPress
WordCamp SF 2011: Debugging in WordPress
 
Grand Rapids PHP Meetup: Behavioral Driven Development with Behat
Grand Rapids PHP Meetup: Behavioral Driven Development with BehatGrand Rapids PHP Meetup: Behavioral Driven Development with Behat
Grand Rapids PHP Meetup: Behavioral Driven Development with Behat
 
Drupal Checklist for Site Builder and Web admin
Drupal Checklist for Site Builder and Web adminDrupal Checklist for Site Builder and Web admin
Drupal Checklist for Site Builder and Web admin
 
[drupalday2017] - Behat per Drupal: test automatici e molto di più
[drupalday2017] - Behat per Drupal: test automatici e molto di più[drupalday2017] - Behat per Drupal: test automatici e molto di più
[drupalday2017] - Behat per Drupal: test automatici e molto di più
 

Kürzlich hochgeladen

%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
masabamasaba
 
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Medical / Health Care (+971588192166) Mifepristone and Misoprostol tablets 200mg
 
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
chiefasafspells
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
Health
 
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
masabamasaba
 
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
masabamasaba
 
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
masabamasaba
 

Kürzlich hochgeladen (20)

Artyushina_Guest lecture_YorkU CS May 2024.pptx
Artyushina_Guest lecture_YorkU CS May 2024.pptxArtyushina_Guest lecture_YorkU CS May 2024.pptx
Artyushina_Guest lecture_YorkU CS May 2024.pptx
 
WSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open Source
WSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open SourceWSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open Source
WSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open Source
 
%in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park %in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park
 
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
 
VTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnVTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learn
 
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
 
WSO2CON 2024 Slides - Open Source to SaaS
WSO2CON 2024 Slides - Open Source to SaaSWSO2CON 2024 Slides - Open Source to SaaS
WSO2CON 2024 Slides - Open Source to SaaS
 
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
Abortion Pill Prices Tembisa [(+27832195400*)] 🏥 Women's Abortion Clinic in T...
 
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
 
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
 
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
 
Announcing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareAnnouncing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK Software
 
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
 
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
 
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
%+27788225528 love spells in Colorado Springs Psychic Readings, Attraction sp...
 
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...
 
%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand
 
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
 
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
 

Behat - Drupal South 2018

  • 1. Concise guide to starting with Behat Berend de Boer, Xplain Hosting awesome and affordable Drupal hosting
  • 2. About me ● First Drupal programmer in New Zealand (2004). ● Host small Drupal sites on Xplain Hosting. ● Large sites: custom setup on AWS; interest.co.nz / LJHooker New Zealand
  • 3. Ever touched an old website and you had no way of telling everything still worked without testing everything?
  • 4. In this talk ● What is Behat? ● How do you get started with Behat? ● How to write tests? ● How to write good tests! ● How to write portable tests, and other common problems.
  • 5.
  • 6. What is Behat? Behat allow you to test your entire website. Behat sees your site just as a customer or tester would. You can even use an actual browser. Techie definition: A php framework for autotesting your business expectations.
  • 7. So how does it work? Run first test: behat features/test1.feature
  • 8. First peek at script test1.feature Feature: Gain privileged access to site Scenario: User logs in as admin Given I am on the homepage When I follow "Log in" And I fill in "Username" with "berend" And I fill in "Password" with "abc123" And I press "Log in" Then I should be on "/user/1" And I should see "Member for"
  • 9. Goal ● Test entire website. ● As a visitor. ● Readable test: readable by stakeholders. ● Test should not be brittle: if you break your tests all the time, they won’t be used. ● If your test passes, you can promise the minimum (possibly maximum!) your website can do. ● Automated.
  • 11. Install Don’t install Behat, install the Drupal Extension for Behat. See here: http://behat-drupal- extension.readthedocs.io/en/3.1/localinstall.html Drupal 7/8: composer require --dev drupal/drupal-extension:dev-master vendor/bin/behat --init (Creates features/bootstrap/FeatureContext.php. We’ll come back to that.) Finally create behat.yml.
  • 12. behat.yml default: suites: default: contexts: ... extensions: BehatMinkExtension: goutte: ~ selenium2: #browser: firefox browser: chrome base_url: http://drupalsouth2017.local DrupalDrupalExtension: blackbox: ~
  • 13. Other pieces of the magic 1. Selenium: you must download the “Selenium Standalone Server” server: http://www.seleniumhq.org/download/ 2. And run that with: java -jar selenium-server-standalone-3.14.0.jar 3. You need a browser specific driver: a. chromedriver: https://sites.google.com/a/chromium.org/chromedriver/ b. geckodriver: https://github.com/mozilla/geckodriver/releases 4. geckodriver/chromedriver must be in your PATH.
  • 14.
  • 15. How to write a Behat test Feature: Gain privileged access to site Scenario: User logs in as admin Given I am on the homepage When I follow "Log in" And I fill in "Username" with "berend" And I fill in "Password" with "abc123" And I press "Log in" Then I should be on "/user/1" And I should see "Member for"
  • 16. .feature file ● File starts with keyword Feature. ● A feature contains one or more Scenarios. ● A scenario contains one or more Steps. ● A step starts with Given, When or Then. ● Extend a step with And or But. This is actually a language: the Gherkin language. Goal when writing Gherkin: Business Readable, Domain Specific Language
  • 17. Feature When writing a feature: Feature <name> <description> All free format.
  • 18. Scenario All scenarios follow this pattern: 1. Get the system into a particular state. 2. Poke it (or tickle it, or …). 3. Examine the new state.
  • 19. Steps We use Given to set up the context where the scenario happens, When to interact with the system somehow, and Then to check that the outcome of that interaction was what we expected. Cucumber doesn’t technically distinguish between these three kind of steps. However, I strongly recommend that you do!
  • 20. What steps are there? Behat + Mink come with certain “out of the box” steps: behat -dl You can filter them: behat -d message
  • 21. Login example Feature: Gain privileged access to site Scenario: User logs in as admin Given I am on the homepage When I follow "Log in" And I fill in "Username" with "berend" And I fill in "Password" with "abc123" And I press "Log in" Then I should be on "/user/1" And I should see "Member for"
  • 22. Background Repeating log in steps for every scenario is not good practice: don’t repeat yourself in programming. One way to improve this is by using Background: follows Feature, comes before Scenario. Background is run before every Scenario in a Feature.
  • 23. Background example 1. Feature: Adding content 2. Background: 3. When I go to "/user/login" 4. And I fill in "Username" with "berend" 5. And I fill in "Password" with "abc123" 6. And I press "Log in" 7. Then I should be on "/user/1" 8. Scenario: Admin can add content 9. Given I go to "/node/add/page" 10. Then I should see "Not saved yet"
  • 24. Custom step Feature: Gain privileged access to site Scenario: User logs in as admin Given I am on the homepage And I follow "Log in" And I fill in "Username" with "berend" And I fill in "Password" with "abc123" And I press "Log in" When I login Then I should be on "/user/1"
  • 25. Problems: ● We need to repeat the login steps for every scenario that needs login. ● username/password hard-coded. Enter the Drupal driver. Drupal driver
  • 26. Drupal driver Remember this bit from behat.yml? DrupalDrupalExtension: blackbox: ~ blackbox is the default driver: no special permissions. Two other drivers: ● Drupal API driver: full programmatic access to Drupal in your own steps. Only local site. ● Drush driver: uses Drush to access site. Can work against a remote site.
  • 27. Install Drupal driver Add driver to our composer requirements: composer require --dev drupal/drupal-driver:dev-master You can now pick your driver: DrupalDrupalExtension: blackbox: ~ api_driver: ["drush" | "drupal" ] Almost there!
  • 28. @api tag Finally you need the @api tag in your .feature: @api Feature: Gain privileged access to site If you forget you get a nice message: No ability to generate random in DrupalDriverBlackboxDriver. Put `@api` into your feature and add an API driver (ex: `api_driver: drupal`) in behat.yml. (DrupalDriverExceptionUnsupportedDriverActionException)
  • 29. Example with Drupal driver 1. @api 2. Feature: Gain privileged access to site 3. Scenario: User logs in as admin 4. Given I am logged in as an "administrator" A lot shorter! And shorter is better.
  • 30. Create custom step Take a look at this: Scenario: User logs in as admin Given I am logged in as an "Authenticated user" And my profile has been filled in When ... Behat doesn’t know about this step, but nicely generates a snippet.
  • 31. Pending step use BehatBehatTesterExceptionPendingException; /** * @Given my profile has been filled in */ public function myProfileHasBeenFilledIn() { throw new PendingException(); }
  • 32. Steps: doc Behat uses php-doc annotations to bind patterns to FeatureContext methods: 1. Comment must start with: /** 2. Write definition keyword: @Given/@When/@Then. 3. The text after the keyword is the step text pattern: I do something with :argument. 4. All token values of the pattern (e.g. :argument) will be captured and passed to the method argument with the same name : $argument.
  • 33. DrupalContext.php All step definitions are done that way, even the “built-in” steps. /** * Creates and authenticates a user with the given role(s). * * @Given I am logged in as a user with the :role role(s) * @Given I am logged in as a/an :role */ public function assertAuthenticatedByRole($role) { }
  • 34. Back to pending step use BehatBehatTesterExceptionPendingException; /** * @Given my profile has been filled in */ public function myProfileHasBeenFilledIn() { throw new PendingException(); }
  • 35. Implement step Possible implementation (simplified): public function myProfileHasBeenFilledIn() { $this->assertClick('Edit'); $this->assertUncheckBox('Personal contact form'); $this->selectOption('Time zone', 'UTC'); $this->pressButton('Save'); $this->assertSuccessMessage('The changes have been saved.'); }
  • 36. Finding methods What existing Mink methods to call exactly is outside the scope of this talk. But use this a lot: behat -d click default | [When|*] I click :link | at `DrupalDrupalExtensionContextMinkContext::assertClick()`
  • 37. How to write good Behat tests
  • 38. Twitter test Scenario: Retweet Given I am on the homepage. When I fill in “What’s happening” with “Hello World” And I press “Tweet 1” And I click “Reply” And I fill in “Tweet your reply” with “Tweet 2” And press “Reply” Then “Replies” should be “1”
  • 39. Better Twitter test Scenario: Retweet When I tweet “Hello World” And I reply to my last tweet with “Tweet 2” Then “Replies” should be “1”
  • 40. Account creation steps But sometimes writing out all the clicks is good! Would you sign up for this site? Scenario: Given I am on a news article page When I click “comment” Then I should see “You must be logged in.”
  • 41. Account creation steps When I click on “Create account” And fill in “Email” with “berend@example.com” And I fill in “Password” with “abc123” And I check “I am not a robot” And I click all the street signs And I click all the street signs again And again And I wait for the confirmation email to arrive
  • 42. Account creation steps And I click on the link in the confirmation email And I click on “Login” And I fill in “Email” with “berend@example.com” And I fill in “Password” with “abc123” And I click “Login” And I find my original news article again. And I click on “comment” And I fill in “Comment” with “Finally” And I press “Save” Then I appear to be very keen to comment
  • 43. A better way Using Behat well: ● Seldom use built-in steps. ● Write your own steps. ● Avoid brittle steps. ● Write steps business analysts can understand.
  • 44. Sequence to avoid Don’t: Scenario: ... Given ... And ... Then ... Always use this order: Given ... When ... Then.
  • 45. How to get your company to do Behat
  • 46. Get started ● When a bug is reported ● Then write the test that replicates it. ● And the test should fail. 1 scenario (1 failed) 2 steps (1 passed, 1 failed) ● When the bug if fixed. ● Then test should pass. 1 scenario (1 passed) 2 steps (2 passed)
  • 47. Gherkin’s purposes Gherkin serves three purposes: 1. documentation and, 2. acceptance tests 3. Bonus: when it yells in red it's talking to you, telling you what code you should write.
  • 48. New projects For new projects: ● Write all requirements as scenarios. ● Implement all steps as deferred. And my profile has been filled in # FeatureContext::myProfile() TODO: write pending definition 1 scenario (1 pending) 2 steps (1 passed, 1 pending) ● When they all pass, your project is done. Allows progress tracking!
  • 49. Not a bug, just a missing scenario One of the wonderful things I discovered when I first used Cucumber to build a complete application from the outside-in was when we started manual exploratory testing and discovered some bugs. Almost without exception, every one of those bugs could be traced back to a gap in the Cucumber scenarios we’d written for that part of the system. Because we’d written the scenarios collaboratively, with businesspeople and developers working together to get them right, it wasn’t anybody’s fault that there was a bug. It was just an edge case we hadn’t originally anticipated
  • 50. Not a bug, just a missing scenario In my experience, bugs are a big source of friction and unhappiness in software teams. Businesspeople blame them on careless developers, and developers blame them on inadequate requirements from the businesspeople. Actually they’re just a natural consequence of software development being a really complex endeavor. Using Cucumber really helped the team see that closing these gaps is everyone’s job. The blaming just didn’t happen, and we were a much happier team as a result.
  • 51. Who writes features? Why not let analysts and stakeholders write features? You as a developer can implement the steps.
  • 52. How to: answers to common problems when using Behat
  • 53. How to run a single feature You seldom want to run all features in all scenarios. 1. Run all scenarios of a feature: behat features/test.feature 2. Run a single scenario: behat features/test.feature:35 where 35 is the line number of the scenario you want to run.
  • 54. Transform 1. Scenario: user must validate email before he can login 2. Given the user has created an account 3. When the user attempts to login 4. Then he is informed that his email is not yet validated 5. When the validation email is received 6. And the user visits the “the first link in the email” 7. Then the user can login successfully
  • 55. Transform function /** * @Transform /^the first link in the last email$/ */ public function castFirstLinkInLastEmail() { return $this->first_link_in_last_email; }
  • 56. Tags - @javascript Normally you don’t see the browser coming up. In my live demos that happened, because I used this tag: @javascript Feature: ... can be used both for all scenarios (specify above feature), or per scenario.
  • 57. Prevent browser from closing Edit: vendor/behat/mink-selenium2- driver/src/Selenium2Driver.php 1. public function stop() 2. … 3. $this->started = false; 4. try { 5. $this->wdSession->close(); 6. } 7. catch (Exception $e) { 8. … 9. }
  • 58. Tags - in FeatureContext FeatureContext is the default class for your steps. With these tags you can write initialisation and cleanup code: ● @BeforeSuite: run once ● @AfterSuite: run once ● @BeforeScenario: once every scenario ● @AfterScenario: once every scenario About hooks: http://behat.org/en/latest/user_guide/context/hooks.html
  • 59. A copy of your production environment may have modules enabled that make testing hard. Disable them before a run: use BehatTestworkHookScopeBeforeSuiteScope; /** * @BeforeSuite */ public static function setup(BeforeSuiteScope $scope) { module_disable (array ('mollom', 'honeypot'), FALSE); } Disable modules - D7
  • 60. Uninstall modules - D8 In Drupal 8 you can only uninstall: use BehatTestworkHookScopeBeforeSuiteScope; /** * @BeforeSuite */ public static function setup(BeforeSuiteScope $scope) { Drupal::service('module_installer')->uninstall(['mollom']); }
  • 61. Regions - behat.yml Often you want to check for the existence of text or links in particular “regions” (main region, sidebar, header, footer). Define them in behat.yml with: extensions: DrupalDrupalExtension: region_map: content: ".block-system-main-block" footer: ".site-footer"
  • 62. Regions - scenario Scenario: User logs in as admin Given I am on the homepage Then I should see "No front page content has been created yet." in the content region
  • 63. Portable tests - behat.yml Write portable tests, don’t hard-code: One way is to put variables in behat.yml: default: suites: default: contexts: - FeatureContext: inbox: server: mail.example.com user: behat password: abc123 arg2: “This”
  • 64. Portable tests - __construct() Your parameters are passed in order you defined, make sure argument names match: class FeatureContext extends RawDrupalContext { public function __construct($inbox, $arg2, $arg3) { $this->inbox = $parameters['inbox']; $this->arg2 = $parameters['arg2']; $this->arg3 = $parameters['arg3']; }
  • 65. Environment settings Environment specific settings can go in environment variable: BEHAT_PARAMS. This is a JSON string, more: http://behat-drupal- extension.readthedocs.io/en/3.1/environment.html
  • 66. Another Context Your FeatureContext can become very big very quickly. You can put code in another context, and new steps will become available. For example create features/bootstrap/CKEditorContext.php. class CKEditorContext extends RawMinkContext { /** * @Given I fill in the rich text editor :arg1 with :arg2 */ public function iFillInTheRichTextEditorWith($arg1, $arg2) { }
  • 67. Context - behat.yml Make sure we can find the context by adding it to behat.yml: default: suites: default: contexts: - FeatureContext - ... - CKEditorContext
  • 68. Subcontexts - behat.yml Modules can also make steps available. Setup subcontexts in behat.yml so behat can find them: DrupalDrupalExtension: ... subcontexts: paths: - "modules/custom/behat_test"
  • 69. Subcontexts - php Define a .behat.inc file in your module such modules/custom/behat_test/behat_test.behat.inc. use DrupalDrupalExtensionContextDrupalSubContextBase; use DrupalDrupalExtensionContextDrupalSubContextInterface; class BehatTest extends DrupalSubContextBase implements DrupalSubContextInterface { /** * @Given I do something interesting */ public function iDoSomethingInteresting() { }
  • 70. Finding elements Often you will need to find elements on a page (input fields, buttons). Two ways to find them: ● CSS: easier to write. ● XPath: more powerful. $el = $this->elementTextContains('css', 'h1', 'Payment processing'); $el = $this->elementTextContains('xpath, '//h1', 'Payment processing');
  • 71. Headless Mink provides the web site integration for Behat. Drivers: ● Headless, without support for JavaScript: Goutte. ● Headless, with support for JavaScript: ZombieDriver. ● Headless actual browser: PhantomJS. ● Actual browser: Selenium2Driver. And more differences: http://mink.behat.org/en/latest/guides/drivers.html
  • 72. Show failed test in browser Test in actual browser can be quite slow. But if headless fails, what that? What happpened? extensions: BehatMinkExtension: zombie: show_auto: true show_cmd: "firefox-trunk %s"
  • 73. Execute javascript Our UIs can get very fancy with javascript controls. Hard to test. Run JavaScript from your step definition: /** * @Given I fill in the rich text editor :arg1 with :arg2 */ public function iFillInTheRichTextEditorWith($arg1, $arg2) { $field = $this->getSession()->getPage()->findField($arg1); $id = $field->getAttribute('id'); $args = ['ckeditor_instance_id' => $id, 'value' => $arg2]; $args_as_js_object = json_encode($args); $this->getSession()->executeScript( "args = {$args_as_js_object};" . "CKEDITOR.instances[args.ckeditor_instance_id].setData(args.value);"
  • 74. Tests stop running for no reason When suddenly your Selenium tests don’t run anymore, it’s most likely because you received a browser update. What to do: 1. Update to latest chromedriver/geckodriver. 2. May need to update Selenium.
  • 76. Do you run your tests all the time?
  • 77. Continuous integration ● When a change is committed ● Then spin up a new machine ● And deploy the code. ● And run all (or tagged) scenarios. ● Then there should be no failures.
  • 78. Recap
  • 79. Benefits 1. How often has an unmaintained website become the gate through which secrets were stolen? (Equifax) You can upgrade old websites, and be sure it still works. 2. You can tell how far a project is from being finished. 3. It’s very helpful when maintaining/extending a site. 4. Great tool for specifying what a site needs to do.
  • 80. Resources ● Read the first 6 chapters of the book! ● Drupal Behat extension: http://behat-drupal- extension.readthedocs.io/en/3.1/index.html ● Me: berend@xplainhosting.com ● Contact me when your business wants to get started with Behat! Any questions?

Hinweis der Redaktion

  1. What happens is obviously is that old websites don’t get maintained.
  2. Intend to be a complete guide. Not just an intro. Hope to inspire you to really use Behat during development and maintenance.
  3. Everything I know I got from this book!
  4. Module tests just test a module. Very limited view.
  5. Did you note you never have to click on end user agreements with free software? Following a bit boring, just download the slides if you want to follow it.
  6. For techies. Note the dev-master, very important!
  7. Behat has nothing to do with web site testing. Behat\MinkExtension provides access to a browser: either headless, or an actual one.
  8. We’re going back to our first script. Again, not limited to web testing, can test anything.
  9. Demonstration
  10. Back to the same feature, let’s improve this.
  11. Say you can have multiple scenarios.
  12. Back to the same feature, let’s improve this.
  13. Second improvement: basically pulling in more steps.
  14. Note the master branch again!
  15. No new steps gained, they were already present, but didn’t work. Also no hard-coded username/password.
  16. Highlight the following in: bit. This is intro to third way.
  17. Run test5.feature to show the snippet that is generated. Probably have been waiting to see how the magic works!
  18. So contrast a feature with previous slide: how hard is it to sign up?
  19. No wonder this site gets only trolls.
  20. https://pt.slideshare.net/lhridley/php-dev-behat
  21. Expand on previous slides: he let’s analysts and stakeholders write features.
  22. Introduce that my Behat environment probably worked a bit differently then people had seen if they had tried Behat.
  23. You don’t have to run all tests all the time.
  24. See line 6
  25. http://behat.org/en/latest/user_guide/context/definitions.html#step-argument-transformations
  26. Say I cheated.
  27. Separate tags with spaces.
  28. More cheating, perhaps demonstrate.
  29. At end of session. Demonstrate:
  30. How did we get that snippet.
  31. Make sure @api is defined in .feature file, else this won't work: obviously needs the Drupal driver, and inherit from RawDrupalContext.
  32. You can define as many regions as you want.
  33. Demonstrate with example what happens.
  34. http://mink.behat.org/en/latest/guides/session.html
  35. Even I am guilty of not running all tests.
  36. This is old tech, done in the 90s.