Upload
gaspar-nagy
View
228
Download
3
Embed Size (px)
Citation preview
Behavior Driven Web UI Automationwith Selenium and Cucumber/SpecFlowBDDx, London11th November 2016
Gáspár Nagycoach • trainer • bdd addict • creator of specflow
@gasparnagy • [email protected]
Copyright © Gaspar NagyCopyright © Gaspar Nagy
bddaddict.com
bdd addict
given.when.then
CAUTION!
on the stage
Copyright © Gaspar NagyCopyright © Gaspar Nagy
There are problems with UI testing!
scriptexpressed
using UI terms
modeling gapbetween UI terms and
domain model terms
sloooowfor a bigger app the
feedback loop gets
uselessly long
brittlebrowsers changing,
environment
changes, cross-
platform issues, etc.
Copyright © Gaspar NagyCopyright © Gaspar Nagy
You are here*!*hopefully
Copyright © Gaspar NagyCopyright © Gaspar Nagy
A decent app
Copyright © Gaspar NagyCopyright © Gaspar Nagy
With an ugly test…
Copyright © Gaspar NagyCopyright © Gaspar Nagy
Unclear
purposeCode
duplication
Anti-
semantic
locators
Wrong
abstraction
Timing
issues
Copyright © Gaspar NagyCopyright © Gaspar Nagy
Unclear purpose – BDD
• Automated tests are investments for the future
• Tests without clearly specified goal are only good until they pass
• BDD/SpecFlow/Cucumber are great tools for helping you to connect purpose for the automation steps
• Scenario title – defines the goal (“The one where …”)
• Scenario steps – provide a functional grouping for the automation steps
Copyright © Gaspar NagyCopyright © Gaspar Nagy
Introduce SpecFlow/Cucumber
Copyright © Gaspar NagyCopyright © Gaspar Nagy
Introduce SpecFlow/Cucumber
Copyright © Gaspar NagyCopyright © Gaspar Nagy
Code duplication – Page Objects
• A small change in the application should only make a small impact on the automation solution
• Automated tests should support you for applying changes and not hold you back
• Page Objects can help you to encapsulate the automation logic for particular UI elements
• Page Objects mirror the page structure
• They represent an automation layer below the step definitions
• Driver pattern is a generalization of the page object pattern for non-UI automation tasks
• They can serve as the interface for switching from UI automation to API-level automation
Copyright © Gaspar NagyCopyright © Gaspar Nagy
Introduce Page Objects
Copyright © Gaspar NagyCopyright © Gaspar Nagy
Introduce Page Objects
Copyright © Gaspar NagyCopyright © Gaspar Nagy
Introduce Page Objects
Copyright © Gaspar NagyCopyright © Gaspar Nagy
Copyright © Gaspar NagyCopyright © Gaspar Nagy
Anti-semantic locators
• Think about how your users identify the different information (text, data, controls, buttons, etc.) on the page
• If the user can find them, you will also find them… be smart!
Copyright © Gaspar NagyCopyright © Gaspar Nagy
Locators – Match your solution to the domain
• If the solution is modeled on the basis of the problem space, the elements will have semantic identification
• Question title – title column in DB – Title property in code - #Title
[FindsBy(How = How.Id)] public IWebElement Title { get; set; }
Copyright © Gaspar NagyCopyright © Gaspar Nagy
Problem vs. solution domain
Concept by Matt Wynne, see also http://dannorth.net/2011/01/31/whose-domain-is-it-anyway/
Problem Domain Solution Domain
Tweet• Tweet
• Retweet
Message• Send
• Forward
Copyright © Gaspar NagyCopyright © Gaspar Nagy
Locating by ID is not enough!
[FindsBy(How = How.Id, Using = "fabric_input")]public IWebElement Fabric { get; set; }
fabric
fabric_input
fabric_list
fabric_open
@Html.Kendo().ComboBox().Name("fabric")
These are
internal for
the control!
Copyright © Gaspar NagyCopyright © Gaspar Nagy
Locating by ID is not enough!
[FindsBy(How = How.Id, Using = "cb9eb8be-71…")]public IWebElement Khaki { get; set; }
Copyright © Gaspar NagyCopyright © Gaspar Nagy
Be careful with Selenium IDE
[FindsBy(How = How.CssSelector, Using = "input.btn.btn-default")]public IWebElement Fabric { get; set; }
There was only one button on the page that time!
Copyright © Gaspar NagyCopyright © Gaspar Nagy
Define your own location strategy and implement it as a custom locator!
[FindsBy(How = How.Custom, CustomFinderType = typeof(TableFieldLocator)]
public IWebElement UserName { get; set; }
form
This is a
generic
lookup
strategy
User Name
Password
input
input
Copyright © Gaspar NagyCopyright © Gaspar Nagy
public IWebElement UserName { get; set; }
Apply conventions with decorators and find the tester’s nirvana…
form
This is the
app-specific
lookup
strategy
User Name
Password
input
input
Copyright © Gaspar NagyCopyright © Gaspar Nagy
Unclear
purposeCode
duplication
Anti-
semantic
locators
Wrong
abstraction
Timing
issues
Copyright © Gaspar NagyCopyright © Gaspar Nagy
Wrong abstraction
Copyright © Gaspar NagyCopyright © Gaspar Nagy
Concept is an idea or mental picture of a group or class of objects formed by combining all their
aspects
This
gonna
save it!
Copyright © Gaspar NagyCopyright © Gaspar Nagy
UI Concepts
Counter concept,
divs and spans
Short-text entering
concept, input
@type=text
Multi-line text
entering concept,
div+javascriptSingle-choice
concept,
set of input
@type=radioSubmit concept,
span+javascript
Copyright © Gaspar NagyCopyright © Gaspar Nagy
Encapsulate automation logic of UI concepts
• Selenium’s PageFactory can only map IWebElement or List<IWebElement>
• Defining a static helper method is already a good solution• like FillInTextBox(IWebElement elm, string value)
• A factory infrastructure, similar to the PageFactory makes it even better
Copyright © Gaspar NagyCopyright © Gaspar Nagy
A concept-based page
express concepts
interact on concept
level
Copyright © Gaspar NagyCopyright © Gaspar Nagy
Thread.Sleep(3000);
Copyright © Gaspar NagyCopyright © Gaspar Nagy
Why do we have this timing problem?
Copyright © Gaspar NagyCopyright © Gaspar Nagy
An example
Enter text
Post form
Working, working…
Observe result
title.SendKeys(…);
button.Click();
driver.FindElement(…);
Copyright © Gaspar NagyCopyright © Gaspar Nagy
Let’s add some waiting to it!
Thread.Sleep(2000);
var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5));wait.Until(d => d.FindElement(By...));
driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(5));...driver.FindElement(By...);
Static waiting
Busy/active waiting
Implicit busy waiting
Copyright © Gaspar NagyCopyright © Gaspar Nagy
An example
Enter text
Post form
Working, working…
Observe result
title.SendKeys(…);
button.Click();
driver.FindElement(…);
The thing you are waiting for is here!
You are waiting here!
Copyright © Gaspar NagyCopyright © Gaspar Nagy
Waiting at the observation step…
• Establishes an implicit dependency between the automation code triggering the action (Click) and the assertion (FindElement)
• This makes the code brittle, because• you cannot compose new tests easily from the automation steps (e.g. the same
assertion after another action)
• the code will be sensitive to the order of the assertions
• tests will be slowed down unnecessarily
Your user knows* when the action is done*hopefully
• Maybe there is a progress indicator
• Maybe they look at the browser icon
• Maybe they’ll wait till they see the end of the page
Copyright © Gaspar NagyCopyright © Gaspar Nagy
An example
Enter text
Post form
Working, working…
Observe result
title.SendKeys(…);
button.SubmitClick();
driver.FindElement(…);
Result page loaded
Copyright © Gaspar NagyCopyright © Gaspar Nagy
Define the waiting conditions for the interactions of the UI concepts!
This is an example…
• Submit concept – a concept that can trigger a server-side processing and results either in an error or a success
• Success is indicated by a fully loaded page with a success message
• Error is indicated by …
• Fully loaded page means that the footer is visible
• Solution: Implement SubmitConcept.Click() in a way that it clicks the button and is waiting either for the success or the error condition
Copyright © Gaspar NagyCopyright © Gaspar Nagy
Other conditions
• Wait until progress indicator is unloaded
• Wait until injected JavaScript signals that the operation has finished
• Wait until protractor signals
• You can even put Thread.Sleep there… only to that single place!
For all these, you need to isolate Submit/Click from other clicks
*maybe
Gáspár Nagycoach • trainer • bdd addict • creator of specflow
@gasparnagy • [email protected]
Gáspár Nagycoach • trainer • bdd addict • creator of specflow
@gasparnagy • [email protected]
Thank you!