Har du prøvet at stå i den situation, at det du har bygget virker, men at det ikke var præcist som kunden forventede?
Eller har du oplevet, at noget der plejede at virke, pludselig ikke gør det længere?
Så er det måske tid til at overveje at gøre dine specifikationer og acceptkriterier testbare.
Behat er et værktøj, der gør det muligt at skrive specifikationer i almindeligt sprog og eksekvere dem som automatiske tests i en browser.
Slides er fra gå-hjem møde den 4. december 2013, hvor Rikke Simonsen demonstrerede, hvordan Behat og metoden bag (BDD) kan bruges i en udviklingsproces, og hvilke fordele det giver. Lige fra bedre beskrivelse af krav, til overholdelse af acceptkriterier, regressionstest og levende dokumentation.
2. Rikke Simonsen
rikke@reload.dk
Teknisk tester hos Reload! A/S
Oversat til dansk:
“Skriver specifikationer
sammen med kunden
og implementerer dem
som automatiserede tests”
torsdag den 5. december 13
2
3. Hvad vil jeg tale om?
torsdag den 5. december 13
3
9. Specifikationsdrevet udvikling
Hvorfor?
“Hvis du kan svare ja
på nogle af disse spørgsmål
så er det måske på tide
at overveje
at gøre jeres specifikationer
eksekverbare”
torsdag den 5. december 13
9
14. Testdrevet udvikling (TDD)
•
•
•
Ryd op i produktionskode
Ryd op i testkode
Kør test igen
•
•
torsdag den 5. december 13
•
•
Skriv en test der fejler
Kør den fejlende test
Skriv kode der implementerer funktionalitet og test
Kør test der passerer
14
16. Behavior Driven Development
BDD blev udviklet af Dan North i 2009
på baggrund af en række spørgsmål han stødte
på i testdrevet udvikling:
Hvor skal man starte i processen?
Hvad skal testes og hvad skal ikke?
Hvor meget skal man teste på een gang?
Hvad skal man kalde testene?
Hvordan tolker man en test der fejler?
torsdag den 5. december 13
16
17. Behavior Driven Development
Dan North foreslog at:
Unit test navne skulle være hele sætninger, der begyndte med
ordet "Should" og skulle skrives i den rækkefølge, der giver
mest værdi for forretningen.
Testbeskrivelsen skulle skrives som brugerhistorie:
"Som [ rolle ] vil jeg have [ funktion], så [ værdi ]."
Godkendelseskriterier skulle skrives i form af scenarier:
Givet [ indledende kontekst ] , når [ begivenhed indtræffer ], så
[ giv resultat ]
http://dannorth.net/whats-in-a-story/
torsdag den 5. december 13
17
22. •
Framework til at teste forretningsmæssige og funktionelle krav
•
Test skrives i det menneskelæsbare sprog Gherkin
•
Og eksekveres som automatiserede tests
•
Testene kan køres med eller uden browser
•
Der findes udvidelser der giver adgang til foruddefinerede
sætninger (kaldet steps)
torsdag den 5. december 13
22
24. Kør din første feature
Trin 4:
$bin/behat --init
Trin 5:
$vim features/your_first.feature
Feature: Your first feature
In order to start using Behat
As a manager or developer
I want to try
Scenario:
Given there is something
When I do something
Then I should see something
Trin 6:
torsdag den 5. december 13
$bin/behat your_first.feature
24
25. Skriv din test i Gherkin
Feature: [Title of the feature]
In order to [achieve some goal]
As a [user/role]
I want to [do action]
Background: [Optional
description]
Given [Precondition]
Scenario: [Optional description]
Given [Precondition]
When [Statement]
And [another statement]
Then [Postcondition]
But [another postcondition]
[more scenarios]
torsdag den 5. december 13
25
26. Skriv din test i Gherkin (på dansk)
Egenskab: [Titel på feature]
For at [opnå et givent mål]
Som [bruger/rolle]
Vil jeg have [feature]
Baggrund: [Valgfri beskrivelse]
Givet [Forudsætning]
Scenarie: [Valgfri beskrivelse]
Givet [Forudsætning]
Når [Erklæring]
Og [en anden erklæring]
Så [Postcondition]
Men [en anden postcondition]
[Flere scenarier]
torsdag den 5. december 13
26
27. Eksempel 1
Egenskab: Arrangementssøgning
For at kunne finde et arrangement
Som bruger
Vil jeg kunne søge på del af titel
Baggrund:
Givet arrangementet “Automatiseret test
af Drupal Sites med behat” eksisterer
Scenarie: Søgning på del af titel
Givet jeg er på siden “Arrangementer”
Når jeg søger efter arrangementer med
titlen “Behat”
Så skal søgningen returnere
arrangementet “Automatiseret test af
Drupal Sites med behat”
torsdag den 5. december 13
27
28. Eksempel 2
Egenskab: Arrangementssøgning
For at kunne finde et arrangement
Som bruger
Vil jeg kunne søge på del af titel
Baggrund:
Givet arrangementet “Automatiseret test
af Drupal Sites med behat” eksisterer
Scenarie: Søgning på del af titel
Givet jeg er på siden “/arrangementer”
Når jeg indtaster “Behat” i feltet
“#search”
Og jeg trykker på knappen “Søg”
Og jeg venter på at “Søgeresultat”
dukker op
Så skal jeg se teksten “Automatiseret test
af Drupal Sites med behat” i
“Søgeresultat” regionen
torsdag den 5. december 13
28
30. Behat parametre
Arguments:
features
Could be:
Feature(s) to run.
- a dir (features/)
- a feature (*.feature)
torsdag den 5. december 13
Options:
--format (-f)
How to format features. pretty is default.
Default formatters are:
- pretty: Prints the feature as is.
- progress: Prints one character per step.
- html: Generates a nice looking HTML report.
- junit: Generates a report similar to Ant+JUnit.
- failed: Prints list of failed scenarios.
--out
Write formatter output to a file/directory
instead of STDOUT (output_path).
--lang
Print formatter output in particular language.
--definitions (-d) Print all available step definitions:
- use -dl to just list definition expressions.
- use -di to show definitions with extended info.
- use -d 'needle' to find specific definitions.
Use --lang to see definitions in specific language.
--name
Only execute the feature elements which match
part of the given name or regex.
--tags
Only execute the features or scenarios with tags
matching tag filter expression.
--append-snippets Appends snippets for undefined steps into
main context.
--help (-h)
Display this help message.
--config (-c)
Specify config file to use.
--profile (-p)
Specify config profile to use.
30
32. Mink Extension
Given /^(?:|I )am on (?:|the )homepage$/
When /^(?:|I )go to "(?P<page>[^"]+)"$/
When /^(?:|I )press "(?P<button>(?:[^"]|")*)"$/
When /^(?:|I )follow "(?P<link>(?:[^"]|")*)"$/
When /^(?:|I )fill in "(?P<field>(?:[^"]|")*)" with "(?P<value>(?:[^"]|")*)"$/
When /^(?:|I )select "(?P<option>(?:[^"]|")*)" from "(?P<select>(?:[^"]|")*)"$/
When /^(?:|I )check "(?P<option>(?:[^"]|")*)"$/
When /^(?:|I )uncheck "(?P<option>(?:[^"]|")*)"$/
When /^(?:|I )attach the file "(?P[^"]*)" to "(?P<field>(?:[^"]|")*)"$/
Then /^(?:|I )should be on "(?P<page>[^"]+)"$/
Then /^(?:|I )should be on (?:|the )homepage$/
Then /^(?:|I )should see "(?P<text>(?:[^"]|")*)"$/
Then /^(?:|I )should not see "(?P<text>(?:[^"]|")*)"$/
Then /^the (?i)url(?-i) should match (?P<pattern>"([^"]|")*")$/
Then /^the response status code should be (?P<code>d+)$/
Then /^the checkbox "(?P<checkbox>(?:[^"]|")*)" is (?:unchecked|not checked)$/
Then /^print current URL$/
Then /^print last response$/
Then /^show last response$/
torsdag den 5. december 13
32
33. Mink Extension
// @Givet /^(?:|jeg )er på hjemmesiden$/
/**
* Opens homepage.
*
* @Given /^(?:|I )am on (?:|the )homepage$/
* @When /^(?:|I )go to (?:|the )homepage$/
*/
public function iAmOnHomepage()
{
$this->getSession()->visit($this->locatePath('/'));
}
torsdag den 5. december 13
33
34. Drupal Extension
Given /^I am viewing (?:a|an) "(?P<type>[^"]*)" node with the title "(?P<title>[^"]*)"$/
Given /^"(?P<type>[^"]*)" nodes:$/
Then /^I should be able to edit (?:a|an) "([^"]*)" node$/
Given /^(?:a|an) "(?P<vocabulary>[^"]*)" term with the name "(?P<name>[^"]*)"$/
Given /^users:$/
Given /^"(?P<vocabulary>[^"]*)" terms:$/
Then /^I should see the error message(?:| containing) "([^"]*)"$/
Then /^I should see the success message(?:| containing) "([^"]*)"$/
Given /^I run drush "(?P<command>[^"]*)" "(?P<arguments>[^"]*)"$/
Then /^drush output should contain "(?P<output>[^"]*)"$/
Given /^I press "(?P<button>[^"]*)" in the "(?P<region>[^"]*)"(?:| region)$/
Given /^(?:|I )fill in "(?P<value>(?:[^"]|")*)" for "(?P<field>(?:[^"]|")*)" in the
"(?P<region>[^"]*)"(?:| region)$/
Given /^I click "(?P<link>[^"]*)" in the "(?P<row_text>[^"]*)" row$/
Given /^the cache has been cleared$/
Given /^I run cron$/
torsdag den 5. december 13
34
35. Drupal Extension Drivers
Feature
Blackbox
Drush
Drupal API
Map Regions
Yes
Yes
Yes
Create users
No
Yes
Yes
Create nodes
No
No
Yes
Create vocabularies
No
No
Yes
Create taxonomy
terms
Run tests and site on
different servers
No
No
Yes
Yes
Yes
No
torsdag den 5. december 13
35