SlideShare a Scribd company logo
1 of 32
Acceptance Testing with
SerenityJS / BDD
Harry Kalligeros
Frontend Developer @ TRASYS
Agenda
 The application under test
 What is BDD
 What is Cucumber
 How Cucumber integrates with:
◦ Protractor API
◦ Page object pattern
◦ SerenityJS Framework / Screenplay
pattern
 SerenityJS architecture
 Run the tests and view the reports
The application under test
Behavior Driven Development
(BDD)
 Behavior Driven Development is
the process of exploring,
discovering, defining and driving
the desired behavior of a software
system by using conversation,
concrete examples and
automated tests
BDD in a nutshell
Cucumber
 It is a language, a process, and a tool
 Provides a single source of truth of
software behavior
 Appeals to both non-technical and
technical project members
 Combines into one format
◦ automated acceptance tests
◦ functional requirements
◦ software documentation
Feature: Browse the speakers
As Harry (a conference visitor)
I want to browse the Speakers or search for some
of them by their name.
I would like also to read more about a specific
speaker, his interests, his skills etc.
@issues:JIRA-1,JIRA-2
Scenario: Access to the Speakers page
Given that Harry visits the conference page
When he navigates to menu called 'Speakers’
Then he sees a page titled 'Speakers’
Scenario: Searching for a speaker
Given that Harry visits the conference page
When he searches for speakers named 'Jason’
Then he sees only the speakers with the name
| Jason Poon |
| Jason Lengstorf |
Scenario
SOLID Principles
 Single Responsibility Principle
 Open Closed Principle
 Liskov Substitution Principle
 Interface Segregation Principle
 Dependency Inversion Principle
Read more:
https://scotch.io/bar-talk/s-o-l-i-d-the-first-five-principles-of-object-oriented-design
Feature: Browse the speakers
As Harry (a conference visitor) I want to browse
the Speakers
Scenario: Access to the Speakers page
Given that Harry visits the conference page
When he navigates to menu called 'Speakers’
Then he sees a page titled 'Speakers’
When he navigates to menu called 'Speakers’
Step implementation
A
scenario A step
@when(/^s?he navigates to menu called '(.*)'$/)
public navigateToMenuCalled(name: string) {
return element(by.css('.navbar-nav’))
element(by.linkText(name)).click();
The step
definition
return element(by.css('.navbar-nav’))
.element(by.linkText(name)).click();
ProtractorAPI
Page Objects
Search box
Title
Grid Widget
Page Object (example)
export class SpeakersPageImpl {
private rootElement = element(
by.css('app-speakers'));
private title = this.rootElement.element(
by.css('.speakers-title'));
private searchBox = this.rootElement.element(
by.css('.speakers-searchbox'));
private speakersGrid: GridWidget = new
GridWidgetImpl(this.rootElement);
Page Object (example)
public getTitle(): Promise<string> {
return this.title.getText();
}
public getResultsCount(): Promise<number> {
return this.speakersGrid.getResultsCount();
}
public searchSpeaker(name: string): Promise<void> {
this.searchBox.clear();
return this.searchBox.sendKeys(name.trim());
}
}
Feature: Browse the speakers
As Harry (a conference visitor) I want to browse
the Speakers
Scenario: Access to the Speakers page
Given that Harry visits the conference page
When he navigates to menu called 'Speakers’
Then he sees a page titled 'Speakers’
When he navigates to menu called 'Speakers’
The Page Object pattern
A
scenario A step
@when(/^s?he navigates to menu called '(.*)'$/)
public navigateToMenuCalled(name: string) {
return this.homePagePO.clickOnMenu(name);
}
return this.homePagePO.clickOnMenu(name);
export class HomePageImpl implements HomePage {
private mainMenu = element(by.css('.navbar-nav'));
public clickOnMenu(name: string): Promise<void> {
return this.mainMenu.element(by.linkText(
name)).click();
}
The step
definition
return this.mainMenu.element(by.linkText(
name)).click();PO
Implementation
Pageobjectpattern
Page Objects – PROs
 DRY (Don’t repeat yourself)
 Encapsulation
 Abstraction
Page Objects – CONs
 They easily become bloated and
cumbersome
 They often violate the Single
Responsibility Principle
 They may need modifications to
extend, in order to be reused to
slightly different pages
Read more:
https://dzone.com/articles/page-objects-refactored-solid-steps-to-the-screenp
Serenity/JS BDD
 Layered approach with the Screenplay
Pattern
 Living documentation with narrative
reports
 Follows the SOLID design principles
 Integration with Cucumber, Mocha and
Chai
The Serenity/JS layered
architecture
 Tests or scenarios
 “Steps”
 Page Objects,
Widgets, or other
UI components
Goal
s
Task
s
Interactions
The Screenplay Pattern
User-centered model
Small reusable interaction
components
Tests written in a narrative
style
Obeys the SOLID principles
Tests are easily scalable and
maintainable
The Screenplay Pattern
 The Scenario has Roles and a Goal
 The Role is played by Actors
 The Actor
◦ has Abilities
◦ performs Tasks
◦ interacts with the system through
Actions
◦ asks Questions about the State of
Element on the Screen
Screenplay pattern
Feature: Browse the speakers
As Harry (a conference visitor) I want to browse
the Speakers
Scenario: Access to the Speakers page
Given that Harry visits the conference page
When he navigates to menu called 'Speakers’
Then he sees a page titled 'Speakers’
When he navigates to menu called 'Speakers’
The Serenity/JS layered
architecture
A goal
A task
@when(/^s?he navigates to menu called '(.*)'$/)
public navigateToMenuCalled(name: string) {
return this.stage.theActorInTheSpotlight()
.attemptsTo(
NavigateToMenu.called(name)
);
}
NavigateToMenu.called(name)
The task
definition
export class NavigateToMenu implements Task {
...
@step('{0} navigates to menu called "#name"')
performAs(actor: PerformsTasks) {
return actor.attemptsTo(
Click.on(MainMenu.menuItem(this.name)));
}}
An interaction Click.on(MainMenu.menuItem(this.name)));
Screenplaypattern
The actor
The actor
let harry = Actor.named(‘Harry’);
Actor has abilities
let harry = Actor.named(‘Harry’).whoCan(
BrowseTheWeb.using(protractor.browser),
Authenticate.with(username, password)
);
Tasks
let admin =
Actor.named(‘Administrator’);
admin.attemptsTo(
Start.withTheConferenceHomepage(),
NavigateToMenu.called('Admin'),
Login.withCredentials()
);
Tasks in step definitions
 Integration with Cucumber
@when(/^s?he searches for speakers named '(.*)'$/)
searchSpeakerByName(name: string) {
return this.stage.theActorInTheSpotlight()
.attemptsTo(
NavigateToMenu.called('Speakers'),
SearchSpeaker.called(name)
);
}
Task composition
export class BookWorkshopTickets implements Task {
…
performAs(actor: PerformsTasks): PromiseLike<void>
{
return actor.attemptsTo(
BookTickets
.in(TicketsPageUI.WorkshopsTab)
.ofType(this.workshop)
.ofQuantity(this.noOfTickets)
);
}
}
Tasks are made up of
interactions
export class FillPersonalInfo implements Task {
performAs(actor: PerformsTasks): PromiseLike<void> {
return actor.attemptsTo(
Scroll.to(TicketsPageUI.ContinueButton),
Click.on(TicketsPageUI.ContinueButton),
Enter.theValue(fullName)
.into(RegistrationForm.Fullname),
Enter.theValue(nickname)
.into(RegistrationForm.Nickname),
DatePick.on(RegistrationForm.DateOfBirth)
.theDate(_dateOfBirth),
Select.theValue(country)
.from(RegistrationForm.Country),
Click.on(RegistrationForm.ContinueButton)
);
}
}
Actor asks Questions
export class Speakers implements
Question<Promise<boolean>> {
static TitleDisplayed: Question<PromiseLike<string>> =
Text.of(SpeakersUI.Title);
}
@then(/^he sees a page titled '(.*)'$/)
seePageTitle(name: string) {
return this.stage.theActorInTheSpotlight()
.attemptsTo(
See.if(Speakers.TitleDisplayed,
actual => expect(actual)
.to.eventually.eql(name)
)
);
}
File structure
 Page objects  SerenityJS
SerenityJS Demo
 Typescript 2.5.3
 Angular 5.2.1
 Angular-cli 1.6.5
 CucumberJS 1.3.3
 Cucumber – TS Flow 1.1.2
 Chai 1.4.2
 Chai as promised 7.1.1
 SerenityJS 1.10.6
 Protractor 5.3.0
Technlology stack
SerenityJS Demo
 https://github.com/harry-kalligeros/serenityjs-
demo
Get source code
Questions

More Related Content

Similar to Serenityjs bdd

2010 07-18.wa.rails tdd-6
2010 07-18.wa.rails tdd-62010 07-18.wa.rails tdd-6
2010 07-18.wa.rails tdd-6
Marakana Inc.
 
jQuery Mobile
jQuery MobilejQuery Mobile
jQuery Mobile
mowd8574
 
BDD approach with Selenium RC
BDD approach with Selenium RCBDD approach with Selenium RC
BDD approach with Selenium RC
Mykola Kolisnyk
 

Similar to Serenityjs bdd (20)

jQuery UI and Plugins
jQuery UI and PluginsjQuery UI and Plugins
jQuery UI and Plugins
 
07_UIAndroid.pdf
07_UIAndroid.pdf07_UIAndroid.pdf
07_UIAndroid.pdf
 
Cross-Platform Native Mobile Development with Eclipse
Cross-Platform Native Mobile Development with EclipseCross-Platform Native Mobile Development with Eclipse
Cross-Platform Native Mobile Development with Eclipse
 
How to increase Performance of Web Application using JQuery
How to increase Performance of Web Application using JQueryHow to increase Performance of Web Application using JQuery
How to increase Performance of Web Application using JQuery
 
2010 07-18.wa.rails tdd-6
2010 07-18.wa.rails tdd-62010 07-18.wa.rails tdd-6
2010 07-18.wa.rails tdd-6
 
Efficient Rails Test-Driven Development - Week 6
Efficient Rails Test-Driven Development - Week 6Efficient Rails Test-Driven Development - Week 6
Efficient Rails Test-Driven Development - Week 6
 
08ui.pptx
08ui.pptx08ui.pptx
08ui.pptx
 
Android development with Scala and SBT
Android development with Scala and SBTAndroid development with Scala and SBT
Android development with Scala and SBT
 
Supercharge your ui
Supercharge your uiSupercharge your ui
Supercharge your ui
 
Escape from the automation hell
Escape from the automation hellEscape from the automation hell
Escape from the automation hell
 
Continuous integration using thucydides(bdd) with selenium
Continuous integration using thucydides(bdd) with seleniumContinuous integration using thucydides(bdd) with selenium
Continuous integration using thucydides(bdd) with selenium
 
Implementing cast in android
Implementing cast in androidImplementing cast in android
Implementing cast in android
 
jQuery Mobile
jQuery MobilejQuery Mobile
jQuery Mobile
 
Writing automation tests with python selenium behave pageobjects
Writing automation tests with python selenium behave pageobjectsWriting automation tests with python selenium behave pageobjects
Writing automation tests with python selenium behave pageobjects
 
Behaviour-Driven Development for Conversational Applications
Behaviour-Driven Development for Conversational ApplicationsBehaviour-Driven Development for Conversational Applications
Behaviour-Driven Development for Conversational Applications
 
Android TV: Building apps with Google’s Leanback Library
Android TV: Building apps with  Google’s Leanback LibraryAndroid TV: Building apps with  Google’s Leanback Library
Android TV: Building apps with Google’s Leanback Library
 
Continuous integration using thucydides(bdd) with selenium
Continuous integration using thucydides(bdd) with  seleniumContinuous integration using thucydides(bdd) with  selenium
Continuous integration using thucydides(bdd) with selenium
 
BDD approach with Selenium RC
BDD approach with Selenium RCBDD approach with Selenium RC
BDD approach with Selenium RC
 
A Deep Dive into the W3C WebDriver Specification
A Deep Dive into the W3C WebDriver SpecificationA Deep Dive into the W3C WebDriver Specification
A Deep Dive into the W3C WebDriver Specification
 
Writing extensible plugins
Writing extensible pluginsWriting extensible plugins
Writing extensible plugins
 

Recently uploaded

%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
masabamasaba
 

Recently uploaded (20)

WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital TransformationWSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
 
AzureNativeQumulo_HPC_Cloud_Native_Benchmarks.pdf
AzureNativeQumulo_HPC_Cloud_Native_Benchmarks.pdfAzureNativeQumulo_HPC_Cloud_Native_Benchmarks.pdf
AzureNativeQumulo_HPC_Cloud_Native_Benchmarks.pdf
 
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...
 
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
 
WSO2Con204 - Hard Rock Presentation - Keynote
WSO2Con204 - Hard Rock Presentation - KeynoteWSO2Con204 - Hard Rock Presentation - Keynote
WSO2Con204 - Hard Rock Presentation - Keynote
 
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
 
WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?
 
WSO2CON2024 - It's time to go Platformless
WSO2CON2024 - It's time to go PlatformlessWSO2CON2024 - It's time to go Platformless
WSO2CON2024 - It's time to go Platformless
 
WSO2CON 2024 - IoT Needs CIAM: The Importance of Centralized IAM in a Growing...
WSO2CON 2024 - IoT Needs CIAM: The Importance of Centralized IAM in a Growing...WSO2CON 2024 - IoT Needs CIAM: The Importance of Centralized IAM in a Growing...
WSO2CON 2024 - IoT Needs CIAM: The Importance of Centralized IAM in a Growing...
 
WSO2Con2024 - From Blueprint to Brilliance: WSO2's Guide to API-First Enginee...
WSO2Con2024 - From Blueprint to Brilliance: WSO2's Guide to API-First Enginee...WSO2Con2024 - From Blueprint to Brilliance: WSO2's Guide to API-First Enginee...
WSO2Con2024 - From Blueprint to Brilliance: WSO2's Guide to API-First Enginee...
 
WSO2Con2024 - Facilitating Broadband Switching Services for UK Telecoms Provi...
WSO2Con2024 - Facilitating Broadband Switching Services for UK Telecoms Provi...WSO2Con2024 - Facilitating Broadband Switching Services for UK Telecoms Provi...
WSO2Con2024 - Facilitating Broadband Switching Services for UK Telecoms Provi...
 
WSO2CON2024 - Why Should You Consider Ballerina for Your Next Integration
WSO2CON2024 - Why Should You Consider Ballerina for Your Next IntegrationWSO2CON2024 - Why Should You Consider Ballerina for Your Next Integration
WSO2CON2024 - Why Should You Consider Ballerina for Your Next Integration
 
AI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplateAI & Machine Learning Presentation Template
AI & Machine Learning Presentation Template
 
Architecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the pastArchitecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the past
 
%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
 
WSO2Con2024 - Software Delivery in Hybrid Environments
WSO2Con2024 - Software Delivery in Hybrid EnvironmentsWSO2Con2024 - Software Delivery in Hybrid Environments
WSO2Con2024 - Software Delivery in Hybrid Environments
 
WSO2CON 2024 Slides - Unlocking Value with AI
WSO2CON 2024 Slides - Unlocking Value with AIWSO2CON 2024 Slides - Unlocking Value with AI
WSO2CON 2024 Slides - Unlocking Value with AI
 
WSO2CON 2024 - How to Run a Security Program
WSO2CON 2024 - How to Run a Security ProgramWSO2CON 2024 - How to Run a Security Program
WSO2CON 2024 - How to Run a Security Program
 
WSO2CON 2024 - Unlocking the Identity: Embracing CIAM 2.0 for a Competitive A...
WSO2CON 2024 - Unlocking the Identity: Embracing CIAM 2.0 for a Competitive A...WSO2CON 2024 - Unlocking the Identity: Embracing CIAM 2.0 for a Competitive A...
WSO2CON 2024 - Unlocking the Identity: Embracing CIAM 2.0 for a Competitive A...
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
 

Serenityjs bdd

  • 1. Acceptance Testing with SerenityJS / BDD Harry Kalligeros Frontend Developer @ TRASYS
  • 2. Agenda  The application under test  What is BDD  What is Cucumber  How Cucumber integrates with: ◦ Protractor API ◦ Page object pattern ◦ SerenityJS Framework / Screenplay pattern  SerenityJS architecture  Run the tests and view the reports
  • 4. Behavior Driven Development (BDD)  Behavior Driven Development is the process of exploring, discovering, defining and driving the desired behavior of a software system by using conversation, concrete examples and automated tests
  • 5. BDD in a nutshell
  • 6. Cucumber  It is a language, a process, and a tool  Provides a single source of truth of software behavior  Appeals to both non-technical and technical project members  Combines into one format ◦ automated acceptance tests ◦ functional requirements ◦ software documentation
  • 7. Feature: Browse the speakers As Harry (a conference visitor) I want to browse the Speakers or search for some of them by their name. I would like also to read more about a specific speaker, his interests, his skills etc. @issues:JIRA-1,JIRA-2 Scenario: Access to the Speakers page Given that Harry visits the conference page When he navigates to menu called 'Speakers’ Then he sees a page titled 'Speakers’ Scenario: Searching for a speaker Given that Harry visits the conference page When he searches for speakers named 'Jason’ Then he sees only the speakers with the name | Jason Poon | | Jason Lengstorf | Scenario
  • 8. SOLID Principles  Single Responsibility Principle  Open Closed Principle  Liskov Substitution Principle  Interface Segregation Principle  Dependency Inversion Principle Read more: https://scotch.io/bar-talk/s-o-l-i-d-the-first-five-principles-of-object-oriented-design
  • 9. Feature: Browse the speakers As Harry (a conference visitor) I want to browse the Speakers Scenario: Access to the Speakers page Given that Harry visits the conference page When he navigates to menu called 'Speakers’ Then he sees a page titled 'Speakers’ When he navigates to menu called 'Speakers’ Step implementation A scenario A step @when(/^s?he navigates to menu called '(.*)'$/) public navigateToMenuCalled(name: string) { return element(by.css('.navbar-nav’)) element(by.linkText(name)).click(); The step definition return element(by.css('.navbar-nav’)) .element(by.linkText(name)).click(); ProtractorAPI
  • 11. Page Object (example) export class SpeakersPageImpl { private rootElement = element( by.css('app-speakers')); private title = this.rootElement.element( by.css('.speakers-title')); private searchBox = this.rootElement.element( by.css('.speakers-searchbox')); private speakersGrid: GridWidget = new GridWidgetImpl(this.rootElement);
  • 12. Page Object (example) public getTitle(): Promise<string> { return this.title.getText(); } public getResultsCount(): Promise<number> { return this.speakersGrid.getResultsCount(); } public searchSpeaker(name: string): Promise<void> { this.searchBox.clear(); return this.searchBox.sendKeys(name.trim()); } }
  • 13. Feature: Browse the speakers As Harry (a conference visitor) I want to browse the Speakers Scenario: Access to the Speakers page Given that Harry visits the conference page When he navigates to menu called 'Speakers’ Then he sees a page titled 'Speakers’ When he navigates to menu called 'Speakers’ The Page Object pattern A scenario A step @when(/^s?he navigates to menu called '(.*)'$/) public navigateToMenuCalled(name: string) { return this.homePagePO.clickOnMenu(name); } return this.homePagePO.clickOnMenu(name); export class HomePageImpl implements HomePage { private mainMenu = element(by.css('.navbar-nav')); public clickOnMenu(name: string): Promise<void> { return this.mainMenu.element(by.linkText( name)).click(); } The step definition return this.mainMenu.element(by.linkText( name)).click();PO Implementation Pageobjectpattern
  • 14. Page Objects – PROs  DRY (Don’t repeat yourself)  Encapsulation  Abstraction
  • 15. Page Objects – CONs  They easily become bloated and cumbersome  They often violate the Single Responsibility Principle  They may need modifications to extend, in order to be reused to slightly different pages Read more: https://dzone.com/articles/page-objects-refactored-solid-steps-to-the-screenp
  • 16. Serenity/JS BDD  Layered approach with the Screenplay Pattern  Living documentation with narrative reports  Follows the SOLID design principles  Integration with Cucumber, Mocha and Chai
  • 17. The Serenity/JS layered architecture  Tests or scenarios  “Steps”  Page Objects, Widgets, or other UI components Goal s Task s Interactions
  • 18. The Screenplay Pattern User-centered model Small reusable interaction components Tests written in a narrative style Obeys the SOLID principles Tests are easily scalable and maintainable
  • 19. The Screenplay Pattern  The Scenario has Roles and a Goal  The Role is played by Actors  The Actor ◦ has Abilities ◦ performs Tasks ◦ interacts with the system through Actions ◦ asks Questions about the State of Element on the Screen
  • 21. Feature: Browse the speakers As Harry (a conference visitor) I want to browse the Speakers Scenario: Access to the Speakers page Given that Harry visits the conference page When he navigates to menu called 'Speakers’ Then he sees a page titled 'Speakers’ When he navigates to menu called 'Speakers’ The Serenity/JS layered architecture A goal A task @when(/^s?he navigates to menu called '(.*)'$/) public navigateToMenuCalled(name: string) { return this.stage.theActorInTheSpotlight() .attemptsTo( NavigateToMenu.called(name) ); } NavigateToMenu.called(name) The task definition export class NavigateToMenu implements Task { ... @step('{0} navigates to menu called "#name"') performAs(actor: PerformsTasks) { return actor.attemptsTo( Click.on(MainMenu.menuItem(this.name))); }} An interaction Click.on(MainMenu.menuItem(this.name))); Screenplaypattern The actor
  • 22. The actor let harry = Actor.named(‘Harry’);
  • 23. Actor has abilities let harry = Actor.named(‘Harry’).whoCan( BrowseTheWeb.using(protractor.browser), Authenticate.with(username, password) );
  • 25. Tasks in step definitions  Integration with Cucumber @when(/^s?he searches for speakers named '(.*)'$/) searchSpeakerByName(name: string) { return this.stage.theActorInTheSpotlight() .attemptsTo( NavigateToMenu.called('Speakers'), SearchSpeaker.called(name) ); }
  • 26. Task composition export class BookWorkshopTickets implements Task { … performAs(actor: PerformsTasks): PromiseLike<void> { return actor.attemptsTo( BookTickets .in(TicketsPageUI.WorkshopsTab) .ofType(this.workshop) .ofQuantity(this.noOfTickets) ); } }
  • 27. Tasks are made up of interactions export class FillPersonalInfo implements Task { performAs(actor: PerformsTasks): PromiseLike<void> { return actor.attemptsTo( Scroll.to(TicketsPageUI.ContinueButton), Click.on(TicketsPageUI.ContinueButton), Enter.theValue(fullName) .into(RegistrationForm.Fullname), Enter.theValue(nickname) .into(RegistrationForm.Nickname), DatePick.on(RegistrationForm.DateOfBirth) .theDate(_dateOfBirth), Select.theValue(country) .from(RegistrationForm.Country), Click.on(RegistrationForm.ContinueButton) ); } }
  • 28. Actor asks Questions export class Speakers implements Question<Promise<boolean>> { static TitleDisplayed: Question<PromiseLike<string>> = Text.of(SpeakersUI.Title); } @then(/^he sees a page titled '(.*)'$/) seePageTitle(name: string) { return this.stage.theActorInTheSpotlight() .attemptsTo( See.if(Speakers.TitleDisplayed, actual => expect(actual) .to.eventually.eql(name) ) ); }
  • 29. File structure  Page objects  SerenityJS
  • 30. SerenityJS Demo  Typescript 2.5.3  Angular 5.2.1  Angular-cli 1.6.5  CucumberJS 1.3.3  Cucumber – TS Flow 1.1.2  Chai 1.4.2  Chai as promised 7.1.1  SerenityJS 1.10.6  Protractor 5.3.0 Technlology stack

Editor's Notes

  1. Behavior driven development είναι μια πειθαρχημένη διαδικασία ανάπτυξης λογισμικού κατά την οποία συνεργάζονται ο ιδιοκτήτης του προϊόντος, ο αναλυτής και ο τεστερ για να προσδιορίσουν τη συμπεριφορά του λογισμικού μέσα από σαφή παραδείγματα και αυτοματοποιημένα τεστ Η συμπεριφορά του λογισμικού καταγράφεται υπο τη μορφή κριτηρίων αποδοχής (acceptance criteria) και αποτελεί ταυτόχρονα και τεκμηρίωση για το παραγόμενο προϊόν. Behavior -> Conversation -> User stories -> Written down in DSL (text based language) -> Scenarios ( = Examples) -> Automated tests Behavior-driven development specifies that tests of any unit of software should be specified in terms of the desired behavior of the unit.[2][4][11] Borrowing from agile software development the "desired behavior" in this case consists of the requirements set by the business — that is, the desired behavior that has business value for whatever entity commissioned the software unit under construction.[2][11] Within BDD practice, this is referred to as BDD being an "outside-in" activity.[12] Behavioral specifications Following this fundamental choice, a second choice made by BDD relates to how the desired behavior should be specified. In this area BDD chooses to use a semi-formal format for behavioral specification which is borrowed from user story specifications from the field of object-oriented analysis and design. The scenario aspect of this format may be regarded as an application of Hoare logic to behavioral specification of software units using the Domain Language of the situation. BDD specifies that business analysts and developers should collaborate in this area and should specify behavior in terms of user stories, which are each explicitly written down in a dedicated document.[11][12] Each user story should, in some way, follow the following structure:[2][12]
  2. S.R.P for short - this principle states that: A class should have one and only one reason to change, meaning that a class should have only one job. Objects or entities should be open for extension, but closed for modification. Let q(x) be a property provable about objects of x of type T. Then q(y) should be provable for objects y of type S where S is a subtype of T. A client should never be forced to implement an interface that it doesn't use or clients shouldn't be forced to depend on methods they do not use. Entities must depend on abstractions not on concretions. It states that the high level module must not depend on the low level module, but they should depend on abstractions.
  3. Many teams use the Page Object pattern to reduce duplication and make maintenance easier. Page Objects raise the level of abstraction from fields and buttons, to screens and web pages. A Page Object hides the details of how to locate an element behind a friendlier-looking API. DRY - Don’t Repeat Yourself. Avoid repeating the same information in more than one place - as this makes it easier to update when it changes. For example, many of your tests will start by logging in to the application. If we just copy/pasted the first example into every test, then if the CSS selector for the username textbox changes, we’d have to change it in every test. If instead every test accesses it via the LoginPage class, we only have to change the selector in a single place. It’s usually best to assume that everything will change eventually. Abstraction. We have moved from describing CSS selectors and keyboard/mouse actions to describing intent. The top example is full of details we need to consider together to work out what the test is trying to do, whereas in the second the details are ‘abstracted away’, replaced with an effortless statement of what we want to achieve. This also helps us fix code when it’s broken: the method name tells us what the intent of the code is - so if it does something else we know it’s broken. Encapsulation. By making the selectors into private fields in the PageObject class, we hide them from external view and ensure they’re only accessible where they’re needed. This simplifies the public interface of the class and makes it easier to use it correctly. If they were publicly available then the next person might (reasonably) expect it was ok to refer to them directly from their test. In general your life will be easier if a class exposes either information or operations - but not both.
  4. Over-encapsulation. Encapsulation (and software design in general) can be great for reducing the cost of anticipated changes but often increases the cost of unanticipated changes. For example, if we want to add new test functionality that re-uses the username and password selectors, we can’t do it without first modifying the PageObject, as the selectors aren’t ‘visible’ outside of it. This makes it harder to try things out quickly and increases the costs of adding new tests. Re-use between pages. Test code for functionality that occurs on many pages (e.g. a search box), shouldn’t need to be duplicated on every PageObject that needs it. Mix-ins and traits can be used to great effect, but in languages that don’t support them single-inheritance creates rigid hierarchies which cause more problems than they solve. If PageX needs test functionality A, B and C, what order do they all have to inherit each other - and if it loses functionality C later, how does the order have to change? Time spent debating these questions is time not spent adding tests. Separation of concerns. We separated our intent from our implementation, which is a great start - but our PageObject class still contains information about how to find elements on a page, what actions we can perform on them, and what business tasks we’re trying to accomplish with them.
  5. Proposed by Antony Marcano 2007 https://serenitydojo.teachable.com/blog/1107150/user-centric-and-task-driven-automation The primary role of automated acceptance tests is to illustrate how a user interacts with the system. They should give us more confidence that the application does all that we expect of it. This role as feedback and living documentation tools is critical; if you can’t tell what a test does in functional terms, how can you have confidence when it passes? And how can you know what to do with the test if it fails? Too often, our acceptance tests end up as sequences of “click”s and “select”s running against a web application. This makes our tests hard to understand and hard to maintain. User-centric, task-driven test automation shows us a better way. Nouns and Verbs Another way of thinking about user-centric test design is in terms of what we model. When we build an application, we reason in terms of domain objects. We might reason in terms of Customers, Destinations, and Travel Insurance Policies. And when we implement the application, we might think about the screens and fields that will represent these concepts.
  6. Proposed by Antony Marcano 2007 https://serenitydojo.teachable.com/blog/1107150/user-centric-and-task-driven-automation The primary role of automated acceptance tests is to illustrate how a user interacts with the system. They should give us more confidence that the application does all that we expect of it. This role as feedback and living documentation tools is critical; if you can’t tell what a test does in functional terms, how can you have confidence when it passes? And how can you know what to do with the test if it fails? Too often, our acceptance tests end up as sequences of “click”s and “select”s running against a web application. This makes our tests hard to understand and hard to maintain. User-centric, task-driven test automation shows us a better way. Nouns and Verbs Another way of thinking about user-centric test design is in terms of what we model. When we build an application, we reason in terms of domain objects. We might reason in terms of Customers, Destinations, and Travel Insurance Policies. And when we implement the application, we might think about the screens and fields that will represent these concepts.