Easy:) Tests with Selenide and Easyb

Iakiv Kramarenko
Conventions :)
●

Sympathy colors***:
Green

=

Orange

Red

=

=

*** often are subjective and applied to specific contex...
●

At project with no Web UI automation, no unit testing

●

With 4(5) Manual QA
–

●

Using checklists + long detailed En...
Testing single page web app
●

Ajax

●

only <div>, <a>, <input>
–

Inconsistent implementation

●

No confident urls

●

...
Met Requirements
●

Automate high level scenarios
–
–

●

use AC from stories
existed Manual Scenarios

Use 3rd party solu...
Dreaming of framework...
●

Fast in development
–

Using instruments quite agile to adapt to project specifics

●

Extreme...
“Raw” Webdriver with tunings
(HtmlElements, Matchers, etc.)
●

No convenient and concise Ajax support out of the box

●

C...
Concordion
●

Hard to extend
–

Custom commands (asserts)

<html xmlns:concordion="http://www.concordion.org/2007/concordi...
Thucydides
●

No convenient Ajax support
–

Asserts and Conditions are bound
●

●

Framework, not a Lib
–

Not agile
●

●
...
= Redundancy
Not BDD
Easy:) Instruments
@Test
public void userCanLoginByUsername() {
open("/login");
$(By.name("user.name")).setValue("johny");
$("#submit").click...
Selenide Pros
●

Wrapper over Selenium with Concise API

●

Lib, not a Framework
–

●

You still have your raw WebDriver w...
Killer Feature
Selenide Conditions
public static final Condition checked = new Condition("checked") {
@Override
public boolean apply(WebElement element) {
re...
Or even shorter
public static final Condition checked = new Condition("checked") {

@Override
public boolean apply(WebElem...
Custom Condition Examples
Aliases
Implementation
public static final Condition checked =
Condition.hasClass("checked");

public static final Condition enabl...
Usage
showPasswordCheckBox().shouldBe(not(checked));

applyButton().shouldBe(enabled);

treeItem.shouldBe(expanded);
Usage: is
public static void ensureExpanded(SelenideElement item){
if (item.is(not(expanded))){

}
}

expand(item);
Own implementation
Implementation (1)
public static final Condition inRadioMode(final String radioMode){
return new Condition("in radio mode:...
Implementation (2)
public static final Condition faded = new Condition("faded
with backdrop" )
{
@Override
public boolean ...
Implementation (3)
public static Condition leftSliderPosition(final Integer
position)
{
return new Condition("left slider ...
Usage
tabContainer().shouldBe(faded);

accessRadioButtons().shouldBe(inRadioMode(PRIVATE));

scheduler.shouldHave(leftSlid...
Composition*

* public static final will be omitted for simplicity
Implementation
Condition loadingDialog = condition(loadingDialog(), exist);
Condition applyButtonDisabled = condition(prim...
Usage
//fill page with valid/invalid data...

Page.save()
Page.shouldBe(and(
failedToSave,
with(usernameValidation(), curr...
Selenide Cons
●

Young:)
–

Many things can be improved
●

Error messages

●

Condition helpers

●

Screenshot API

–
–

●...
Easyb Pros
●

Gherkin (given/when/then) and its implementation live at
the same file
–

better maintainability

–

more DR...
Easyb Cons
●

bad support of framework from authors.

●

some features are broken
–

●

no tags per scenario/step
–

●
●

...
Easyb Selenide Integration
Problem
Selenide shoulds vs Easyb shoulds
Easyb catches any 'should' (shouldBe, shouldHave, ...)
except “should” and “shou...
Solution => Decorators
showPasswordCheckBox().shouldNot(be(checked));
showPasswordCheckBox().should(be(not(checked)));
All Together :)
Preconditions to BDD
Team is competent :)

●

●

PO knows what is
Criteria of Good Requirement
Manual QA knows how to writ...
Pending Easyb Story by PO
description "Products List page"
scenario "Add new product", {
given "On Products List page"
the...
Pending Detailed Easyb Story by
Manual QA
description "Products List page"
scenario "Add new product", {
given "On Product...
Implemented Easyb Story
description "ProductsList test"
tags "functional"
BaseTest.setup()
scenario "Add new product", {
g...
Easyb Report
Failed
Easyb
Report
Alternative: TestNG test
public class ProductManagement extends AbstractTest {
@Test
public void testNewProductCanBeAdded(...
Alternative: TestNG Report
Failed TestNG Report
When Easyb ?
●

“Somebody” wants Gherkin
–

Automation resources are
limited, and help may come from
PO or Manual QA provi...
When TestNG/Junit ?
●

When you have strong 'agile' devs/automation which know why
what and how to test and do write tests...
Ideas for improvements
●

Kill Kenny
–

if he is the only who wants Gherkin:)

–

and stay KISS with TestNG/Junit

●

Cont...
Q&A
Resources, Links
●

●

●

Src of example test framework:
https://github.com/yashaka/gribletest
Application under test used...
●

To Artem Chernysh for implementation of main base part
of the test framework for this presentation
–

●

To Maksym Barv...
Contacts
●

yashaka@gmail.com

●

skype: yashaolin

●

http://www.linkedin.com/in/iakivkramarenko
Easy tests with Selenide and Easyb
Easy tests with Selenide and Easyb
Easy tests with Selenide and Easyb
Easy tests with Selenide and Easyb
Upcoming SlideShare
Loading in …5
×

Easy tests with Selenide and Easyb

3,174 views

Published on

Selenide is simple and powerful in use wrapper-library over Selenium. But what the point just of shorter lines of code? In this talk we will see how to tame your webui mustang with Selenide and put it into fence of simple BDD stories with Easyb. We also consider pros and cons of the approach and compare to available alternatives.

Published in: Education

Easy tests with Selenide and Easyb

  1. 1. Easy:) Tests with Selenide and Easyb Iakiv Kramarenko
  2. 2. Conventions :) ● Sympathy colors***: Green = Orange Red = = *** often are subjective and applied to specific context ;)
  3. 3. ● At project with no Web UI automation, no unit testing ● With 4(5) Manual QA – ● Using checklists + long detailed End to End test cases With 1 QA Automation found
  4. 4. Testing single page web app ● Ajax ● only <div>, <a>, <input> – Inconsistent implementation ● No confident urls ● One current Frame/Page with content per user step – Deep structure: ● – Authorization > Menus > SubMenus > Tabs > Extra > Extra Modal dialogs
  5. 5. Met Requirements ● Automate high level scenarios – – ● use AC from stories existed Manual Scenarios Use 3rd party solutions – ● Java Desired Involve Manual QA – – ● provide easy to use solution BDD Desired In Tough Deadlines :)
  6. 6. Dreaming of framework... ● Fast in development – Using instruments quite agile to adapt to project specifics ● Extremely easy to use and learn ● Simple DSL for tests ● BDD – light and DRY as much as possible
  7. 7. “Raw” Webdriver with tunings (HtmlElements, Matchers, etc.) ● No convenient and concise Ajax support out of the box ● Code redundancy – Driver creation – Finding elements – Assert element states ● Harmcrest Matchers are easy, but assertThat() knows nothing about Ajax – HtmlElements gives powerful but bulky “waiting” decorators (see links [1][2])
  8. 8. Concordion ● Hard to extend – Custom commands (asserts) <html xmlns:concordion="http://www.concordion.org/2007/concordion"> <body> <p concordion:assertEquals="getGreeting()">Hello World!</p> </body> </html>
  9. 9. Thucydides ● No convenient Ajax support – Asserts and Conditions are bound ● ● Framework, not a Lib – Not agile ● ● Hard to extend It's hard to use some patterns (e.g. LoadableComponent) Monstrous Manual :)
  10. 10. = Redundancy
  11. 11. Not BDD
  12. 12. Easy:) Instruments
  13. 13. @Test public void userCanLoginByUsername() { open("/login"); $(By.name("user.name")).setValue("johny"); $("#submit").click(); $(".loading_progress").should(disappear); $("#username").shouldHave(text("Hello, Johny!")); }
  14. 14. Selenide Pros ● Wrapper over Selenium with Concise API ● Lib, not a Framework – ● You still have your raw WebDriver when needed should style asserts – Independent from Conditions – Waiting for conditions (Ajax friendly) ● Screenshot reporting on each failed should ● Screenshot API – – ● Providing screenshots' context Get all screenshots for context Actively supported by authors
  15. 15. Killer Feature Selenide Conditions
  16. 16. public static final Condition checked = new Condition("checked") { @Override public boolean apply(WebElement element) { return isChecked(element); } @Override public String actualValue(WebElement element) { return isChecked(element) ? "checked" : "unchecked"; } @Override public String toString(){ return "checked"; } };
  17. 17. Or even shorter public static final Condition checked = new Condition("checked") { @Override public boolean apply(WebElement element) { return isChecked(element); } };
  18. 18. Custom Condition Examples
  19. 19. Aliases
  20. 20. Implementation public static final Condition checked = Condition.hasClass("checked"); public static final Condition enabled = Condition.hasNotClass("disabled"); public static final Condition expanded = Condition.attribute("area-expanded", "true");
  21. 21. Usage showPasswordCheckBox().shouldBe(not(checked)); applyButton().shouldBe(enabled); treeItem.shouldBe(expanded);
  22. 22. Usage: is public static void ensureExpanded(SelenideElement item){ if (item.is(not(expanded))){ } } expand(item);
  23. 23. Own implementation
  24. 24. Implementation (1) public static final Condition inRadioMode(final String radioMode){ return new Condition("in radio mode: " + radioMode) { @Override public boolean apply(WebElement webElement) { boolean res = true; for(WebElement mode: Mode.modes(webElement)){ if (Mode.value(mode).equals(radioMode)){ res = res && mode.getAttribute("class").contains("active"); } else { res = res && ! } } } }; } return res; mode.getAttribute("class").contains("active");
  25. 25. Implementation (2) public static final Condition faded = new Condition("faded with backdrop" ) { @Override public boolean apply(WebElement element) { return backDropFor(element).exists(); } };
  26. 26. Implementation (3) public static Condition leftSliderPosition(final Integer position) { return new Condition("left slider position " + position) { @Override public boolean apply(WebElement webElement) { return getLeftSliderCurrentPosition(webElement).equals(position); } }; }
  27. 27. Usage tabContainer().shouldBe(faded); accessRadioButtons().shouldBe(inRadioMode(PRIVATE)); scheduler.shouldHave(leftSliderPosition(100));
  28. 28. Composition* * public static final will be omitted for simplicity
  29. 29. Implementation Condition loadingDialog = condition(loadingDialog(), exist); Condition applyButtonDisabled = condition(primeBtn(), disabled); Condition cancelButtonDisabled = condition(scndBtn(), disabled); Condition processed = with_(no(Modal.dialog())); Condition loaded = and(processed, with_(no(loadingDialog)), with_(applyButtonDisabled)); Condition savedForSure = and(loaded, with_(saveSuccessMsg())); Condition failedToSave = and( processed, with_(no(loadingDialog)), with_(not(applyButtonDisabled)), with_(no(saveSuccessMsg())), with_(not(cancelButtonDisabled)), with_(saveErrorsMsg()));
  30. 30. Usage //fill page with valid/invalid data... Page.save() Page.shouldBe(and( failedToSave, with(usernameValidation(), currentPassValidation()), with(no(newPassValidation(), matchPassValidation())))) //fix errors and save... Page.shouldBe(savedForSure)
  31. 31. Selenide Cons ● Young:) – Many things can be improved ● Error messages ● Condition helpers ● Screenshot API – – ● Tones of them have been resolved so far Others can be implemented as your own extensions Not all-powerfull – For some things you will still need raw WebDriver
  32. 32. Easyb Pros ● Gherkin (given/when/then) and its implementation live at the same file – better maintainability – more DRY code ● no implementation => “pending” test ● simple but nice looking reports ● groovy as a script language for tests – scenarios are ordered
  33. 33. Easyb Cons ● bad support of framework from authors. ● some features are broken – ● no tags per scenario/step – ● ● ● before_each only tags per story Stack trace of error messages is clipped No out of the box way to put listeners on steps/scenarios “Shared steps” feature is present but not quite handy
  34. 34. Easyb Selenide Integration
  35. 35. Problem Selenide shoulds vs Easyb shoulds Easyb catches any 'should' (shouldBe, shouldHave, ...) except “should” and “shouldNot” showPasswordCheckBox().shouldNot(checked); //Less readable:(
  36. 36. Solution => Decorators showPasswordCheckBox().shouldNot(be(checked)); showPasswordCheckBox().should(be(not(checked)));
  37. 37. All Together :)
  38. 38. Preconditions to BDD Team is competent :) ● ● PO knows what is Criteria of Good Requirement Manual QA knows how to write “Automatable” Scenarios
  39. 39. Pending Easyb Story by PO description "Products List page" scenario "Add new product", { given "On Products List page" then "new product can be added" }
  40. 40. Pending Detailed Easyb Story by Manual QA description "Products List page" scenario "Add new product", { given "On Products List page" and "No custom product with 'Product_1' name exist" then "new product with 'Product_1' name can be added" and "after relogin still present" }
  41. 41. Implemented Easyb Story description "ProductsList test" tags "functional" BaseTest.setup() scenario "Add new product", { given "On ProductsList page",{ ProductsList.page().get() } and "No custom product with '" + TEST_PRODUCT + "' name exist", { Table.ensureHasNo(cellByText(TEST_PRODUCT)) } then "new product with '" + TEST_PRODUCT + "' name can be added", { ProductsList.addProductForSure(TEST_PRODUCT) } and "after relogin still present", { cleanReLogin() Table.cellByText(TEST_PRODUCT).should(be(visible)); } }
  42. 42. Easyb Report
  43. 43. Failed Easyb Report
  44. 44. Alternative: TestNG test public class ProductManagement extends AbstractTest { @Test public void testNewProductCanBeAdded() { ProductsList.page().get(); Table.ensureHasNo(cellByText(TEST_PRODUCT)); ProductsList.addProductForSure(TEST_PRODUCT); cleanReLogin(); Table.cellByText(TEST_PRODUCT).should(Be.visible); } }
  45. 45. Alternative: TestNG Report
  46. 46. Failed TestNG Report
  47. 47. When Easyb ? ● “Somebody” wants Gherkin – Automation resources are limited, and help may come from PO or Manual QA providing detailed 'steps to code' ● Detailed reporting of test steps ● Ordered tests execution (as present in the file)
  48. 48. When TestNG/Junit ? ● When you have strong 'agile' devs/automation which know why what and how to test and do write tests. – Hence you never need pretty looking reports to please your manager customer because you just have high quality product.
  49. 49. Ideas for improvements ● Kill Kenny – if he is the only who wants Gherkin:) – and stay KISS with TestNG/Junit ● Contribute to Easyb:) ● Bless Selenide:) – Authors will contribute nevertheless
  50. 50. Q&A
  51. 51. Resources, Links ● ● ● Src of example test framework: https://github.com/yashaka/gribletest Application under test used in easyb examples: http://grible.org/download.php Instruments – http://selenide.org/ – http://easyb.org/
  52. 52. ● To Artem Chernysh for implementation of main base part of the test framework for this presentation – ● To Maksym Barvinskyi for application under test – ● https://github.com/elaides/gribletest http://grible.org/ To Andrei Solntsev, creator of Selenide, for close collaboration on Selenide Q&A, and new features implemented:)
  53. 53. Contacts ● yashaka@gmail.com ● skype: yashaolin ● http://www.linkedin.com/in/iakivkramarenko

×