6. HET PROBLEEM
• Verschillend beeld op scope/werking van de oplevering
• De klant weet soms achteraf pas hoe het systeem precies
gebruikt kan worden
• “Het is wel mooi, maar zou x toch y kunnen werken?”
• “Bedankt voor de nieuwe feature, maar nu werkt x niet meer”
7. HET PROBLEEM
• Verschillend beeld op scope/werking van de oplevering
• De klant weet soms achteraf pas hoe het systeem precies
gebruikt kan worden
• “Het is wel mooi, maar zou x toch y kunnen werken?”
• “Bedankt voor de nieuwe feature, maar nu werkt x niet meer”
8. WANT EIGENLIJK...
• ... hebben we een gezamenlijk doel
• ... willen we wat we gaan bouwen zo nauwkeurig mogelijk
definiëren
• ... willen we constante kwaliteit leveren
11. DAT BETEKENT DAT...
• ... we beter, en op gelijk niveau moeten communiceren
• ... we een documentatiesysteem moeten bedenken voor de
afstemming
• ... we regelmatig moeten valideren dat wat we leveren nog
volgens specificaties is
12. DAT BETEKENT DAT...
• ... we beter, en op gelijk niveau moeten communiceren
• ... we een documentatiesysteem moeten bedenken voor de
afstemming
• ... we regelmatig moeten valideren dat wat we leveren nog
volgens specificaties is
Automatiseren?
23. AGILE MANIFESTO
Mensen en hun onderlinge interactie > processen and tools
Werkende software > allesomvattende documentatie
Samenwerking met de klant > contractonderhandelingen
Inspelen op verandering > het volgen van een plan
28. OPSTELLENVAN REQUIREMENTS
• Omschrijven hoe een probleem opgelost wordt
• Gezamenlijk met de klant opstellen
• In de taal (technische) van de klant
• Functioneel gericht, niet technisch gericht
29. Ik wil graag een zoekmachine bouwen, zodat
mijn bezoekers het hele internet kunnen
doorzoeken!
30. Ik wil graag een zoekmachine bouwen, zodat
mijn bezoekers het hele internet kunnen
doorzoeken!
Wow, leuke klus!
Ik ga direct aan de slag
32. Alstublieft! Hier is de zoekmachine, mooi hè?
Jawel, mooie foto op de achtergrond. En
het zoeken werkt, maar ik bedoelde ook
dat bezoekers op afbeeldingen kunnen
zoeken!
33. Alstublieft! Hier is de zoekmachine, mooi hè?
Jawel, mooie foto op de achtergrond. En
het zoeken werkt, maar ik bedoelde ook
dat bezoekers op afbeeldingen kunnen
zoeken!
Ja zeg, daar kom je nu mee
34. Alstublieft! Hier is de zoekmachine, mooi hè?
Jawel, mooie foto op de achtergrond. En
het zoeken werkt, maar ik bedoelde ook
dat bezoekers op afbeeldingen kunnen
zoeken!
Ja zeg, daar kom je nu mee
37. PRAKTIJK
Feature: {feature omschrijving}
{intentie}
As a {personage(s)}
I want {feature}
So that {intentie}
Scenario: {scenario omschrijving}
Given {context}
And {meer context}
When {actie}
Then {resultaat}
Scenario: ...
Informatie: http://dannorth.net/whats-in-a-story/
38. VOORBEELD ZOEKFUNCTIE
Feature: Search on the internet
As a bing.com visitor
I want to use the search engine
So that i can find information on the internet
Scenario: Simple keyword search
Given I am on the homepage
When I search the term “PHP”
Then I should see search results containing “PHP”
39. LEVENDE DOCUMENTATIE
• Alle features en scenario’s bij elkaar zijn de documentatie
• Bij een change request werk je deze documentatie daarom bij
57. INSTALLERENVAN BEHAT
1. Maak een map genaamd “testsuite”
2. Installeer composer (http://docs.behat.org/quick_intro.html#installation)
3. Maak een bestand composer.json met de volgende inhoud:
4. $ php composer.phar install
{
"require": {
"behat/behat": "2.4.*@stable"
},
"minimum-stability": "dev",
"config": {
"bin-dir": "bin/"
}
}
$ curl http://getcomposer.org/installer | php
58. INSTALLERENVAN BEHAT
1. Maak een map genaamd “testsuite”
2. Installeer composer (http://docs.behat.org/quick_intro.html#installation)
3. Maak een bestand composer.json met de volgende inhoud:
4. $ php composer.phar install
{
"require": {
"behat/behat": "2.4.*@stable"
},
"minimum-stability": "dev",
"config": {
"bin-dir": "bin/"
}
}
That’s it!
$ curl http://getcomposer.org/installer | php
59. HELLO BEHAT
1. Initialiseer een Behat testsuite met het commando:
$ bin/behat --init
2. Behat heeft de volgende mappen en bestanden aangemaakt:
3. Run de testsuite: $ bin/behat
60. STEPS? (TERMINOLOGIE)
Feature: {feature omschrijving}
{intentie}
As a {personage(s)}
I want {feature}
So that {intentie}
Scenario: {scenario omschrijving}
Given {context}
And {meer context}
When {actie}
Then {resultaat}
Scenario: ...
61. STEPS? (TERMINOLOGIE)
Feature: {feature omschrijving}
{intentie}
As a {personage(s)}
I want {feature}
So that {intentie}
Scenario: {scenario omschrijving}
Given {context}
And {meer context}
When {actie}
Then {resultaat}
Scenario: ...
Feature, user story, module
62. STEPS? (TERMINOLOGIE)
Feature: {feature omschrijving}
{intentie}
As a {personage(s)}
I want {feature}
So that {intentie}
Scenario: {scenario omschrijving}
Given {context}
And {meer context}
When {actie}
Then {resultaat}
Scenario: ...
Feature, user story, module
Scenario
63. STEPS? (TERMINOLOGIE)
Feature: {feature omschrijving}
{intentie}
As a {personage(s)}
I want {feature}
So that {intentie}
Scenario: {scenario omschrijving}
Given {context}
And {meer context}
When {actie}
Then {resultaat}
Scenario: ...
Feature, user story, module
Scenario
Steps
66. VOORBEELD ZOEKFUNCTIE
Feature: Search on the internet
As a bing.com visitor
I want to use the search engine
So that i can find information on the internet
Scenario: Simple keyword search
Given I am on the homepage
When I search the term “PHP”
Then I should see search results containing “PHP”
features/search.feature
67. STEP DEFINITIES
/**
* @Given /^I am on the homepage$/
*/
public function iAmOnTheHomepage()
{
throw new PendingException();
}
/**
* @When /^I search the term "([^"]*)"$/
*/
public function iSearchTheTerm($arg1)
{
throw new PendingException();
}
Deze kun je in FeatureContext.php plaatsen, echter...
68. MINKEXTENSION
1. Is een set van (basis) voorgedefinieerde steps
2. Maakt gebruik van Mink
3. Maar... niet alle teksten van de steps zijn even bruikbaar
/**
* Opens homepage.
*
* @Given /^(?:|I )am on (?:|the )homepage$/
* @When /^(?:|I )go to (?:|the )homepage$/
*/
public function iAmOnHomepage()
{
$this->getSession()->visit($this->locatePath('/'));
}
71. MINK STEPS
Given /^(?:|I )am on (?:|the )homepage$/
When /^(?:|I )go to (?:|the )homepage$/
Given /^(?:|I )am on "(?P<page>[^"]+)"$/
When /^(?:|I )fill in "(?P<field>(?:[^"]|")*)" with "(?P<value>(?:[^"]|")*)"$/
When /^(?:|I )press "(?P<button>(?:[^"]|")*)"$/
When /^(?:|I )follow "(?P<link>(?:[^"]|")*)"$/
Then /^(?:|I )should be on "(?P<page>[^"]+)"$/
Then /^(?:|I )should see "(?P<text>(?:[^"]|")*)"$/
$ bin/behat -dl
/**
* Clicks link with specified id|title|alt|text.
*
* @When /^(?:|I )follow "(?P<link>(?:[^"]|")*)"$/
*/
public function clickLink($link)
{
$link = $this->fixStepArgument($link);
$this->getSession()->getPage()->clickLink($link);
}
73. STEP DEFINITIES MAKEN
/**
* @When /^I search the term "([^"]*)"$/
*/
public function iSearchTheTerm($searchTerm)
{
$this->fillField('q', $searchTerm); // Mink definities
$this->pressButton('go');
}
/**
* @When /^I search the term "([^"]*)"$/
*/
public function iSearchTheTerm($searchTerm)
{
$page = $this->getSession()->getPage();
$page->fillField('q', $searchTerm);
$page->pressButton('go');
}
76. DE LAATSTE STAP
Then I should see search results containing “PHP”
/**
* @Then /^I should see search results containing (.*)$/
*/
public function iShouldSeeSearchResultsContaining($searchTerm)
{
$searchTerm = quotemeta($searchTerm);
$regex = sprintf('/%s/mi', $searchTerm);
$page = $this->getSession()->getPage();
$elements = $page->findAll('xpath', './/div[@class="sa_mc"]');
foreach ($elements as $element) {
if (!preg_match($regex, $element->getText())) {
throw new Exception('One of the elements did not match the searchterm');
}
}
}
77. PROFIELEN
• Volledige configuratie per omgeving
• Selectie op basis van filters
• Te definieren in behat.yml:
• Aan te roepen met: $ bin/behat --profile profielnaam
default:
extension:
BehatMinkExtensionContextMinkContext
base_url: “http://www.example.org”
profielnaam:
extension:
BehatMinkExtensionContextMinkContext
base_url: “http://acc.example.org”
78. TAGS
• Handig om selectie te maken van features/scenario’s
• Via command line: $ bin/behat --tags “@slow”
• Definieer als filters in profile
@smoke
Feature: Search on the www
@slow
Scenario: ...
search.feature
slowonly:
filters:
tags: “@slow”
behat.yml
fast:
filters:
tags: “~@slow”
behat.yml
79. FILTERS
• Tests groeperen
• Snel vs. traag
• Tags
• Configuratie in behat.yml
smoketests:
filters:
tags: “@smoketest&&~@wip”
development:
filters:
tags: “~@slow&&~@wip”
82. BROWSER CONTROLLERS
Javascript Snelheid Opmerking
Goutte Nee ++ Emulator
Selenium2 Ja -
Sahi Ja ~
Geen response
statuscode, headers,
authenticatie
Zombie.js Ja +
83. SCENARIO OUTLINES
Scenario Outline: Simple keyword search
Given I am on the homepage
When I search the term <searchterm>
Then I should see search results containing <searchterm>
Examples:
| searchterm |
| PHP |
| Java |
| Pie |
| This string is possibly too long and uncommon |
85. MULTILINEVARIABLES
Scenario:
Given I input that spans several lines
"""
Test one
two three
"""
/**
* @Given /^I input that spans several lines$/
*/
public function iInputThatSpansSeveralLines(PyStringNode $string)
{
(string) $string;
$string->getRaw(); // string
$string->getLines(); // array
}
86. TABLES
Scenario:
Given the following users are registered
| name | password |
| Foo | test123 |
| Admin | secret |
When I go to the user overview
Then I should see Foo
And I should see Admin
/**
* @Given /^the following users are registered$/
*/
public function theFollowingUsersAreRegistered(TableNode $table)
{
foreach ($table->getHash() as $row) {
// ... $row['name'], $row['password']
}
}