easy tests with selenide and easyb

57
Easy:) Tests with Selenide and Easyb Iakiv Kramarenko

Upload: yasha-kramarenko

Post on 05-Dec-2014

1.134 views

Category:

Education


6 download

DESCRIPTION

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.

TRANSCRIPT

Page 1: Easy tests with Selenide and Easyb

Easy:) Tests with Selenide and Easyb

Iakiv Kramarenko

Page 2: Easy tests with Selenide and Easyb

Conventions :)

● Sympathy colors***:

Green =

Orange =

Red =

*** often are subjective and applied to specific context ;)

Page 3: Easy tests with Selenide and Easyb

● 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

Page 4: Easy tests with Selenide and Easyb

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

Page 5: Easy tests with Selenide and Easyb

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 :)

Page 6: Easy tests with Selenide and Easyb

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

Page 7: Easy tests with Selenide and Easyb
Page 8: Easy tests with Selenide and Easyb

“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])

Page 9: Easy tests with Selenide and Easyb

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>

Page 10: Easy tests with Selenide and Easyb

Thucydides

● No convenient Ajax support

– Asserts and Conditions are bound● Hard to extend

● Framework, not a Lib

– Not agile● It's hard to use some patterns (e.g. LoadableComponent)

● Monstrous Manual :)

Page 11: Easy tests with Selenide and Easyb

= Redundancy

Page 12: Easy tests with Selenide and Easyb

Not BDD

Page 13: Easy tests with Selenide and Easyb

Easy:) Instruments

Page 14: Easy tests with Selenide and Easyb
Page 15: Easy tests with Selenide and Easyb

@Test

public void userCanLoginByUsername() {

open("/login");

$(By.name("user.name")).setValue("johny");

$("#submit").click();

$(".loading_progress").should(disappear);

$("#username").shouldHave(text("Hello, Johny!"));

}

Page 16: Easy tests with Selenide and Easyb

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

Page 17: Easy tests with Selenide and Easyb

Killer FeatureSelenide Conditions

Page 18: Easy tests with Selenide and Easyb

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";

}

};

Page 19: Easy tests with Selenide and Easyb

Or even shorter

public static final Condition checked = new Condition("checked") {

@Override

public boolean apply(WebElement element) {

return isChecked(element);

}

};

Page 20: Easy tests with Selenide and Easyb

Custom Condition Examples

Page 21: Easy tests with Selenide and Easyb

Aliases

Page 22: Easy tests with Selenide and Easyb

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");

Page 23: Easy tests with Selenide and Easyb

Usage

showPasswordCheckBox().shouldBe(not(checked));

applyButton().shouldBe(enabled);

treeItem.shouldBe(expanded);

Page 24: Easy tests with Selenide and Easyb

Usage: is

public static void ensureExpanded(SelenideElement item){

if (item.is(not(expanded))){

expand(item); }}

Page 25: Easy tests with Selenide and Easyb

Own implementation

Page 26: Easy tests with Selenide and Easyb

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 && !

mode.getAttribute("class").contains("active"); } } return res; } };}

Page 27: Easy tests with Selenide and Easyb

Implementation (2)

public static final Condition faded = new Condition("faded with backdrop") {

@Override public boolean apply(WebElement element) {

return backDropFor(element).exists(); }};

Page 28: Easy tests with Selenide and Easyb

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); } };}

Page 29: Easy tests with Selenide and Easyb

Usage

tabContainer().shouldBe(faded);

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

scheduler.shouldHave(leftSliderPosition(100));

Page 30: Easy tests with Selenide and Easyb

Composition*

* public static final will be omitted for simplicity

Page 31: Easy tests with Selenide and Easyb

ImplementationCondition 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()));

Page 32: Easy tests with Selenide and Easyb

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)

Page 33: Easy tests with Selenide and Easyb

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

Page 34: Easy tests with Selenide and Easyb
Page 35: Easy tests with Selenide and Easyb

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

Page 36: Easy tests with Selenide and Easyb

Easyb Cons

● bad support of framework from authors.● some features are broken

– before_each

● no tags per scenario/step– 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

Page 37: Easy tests with Selenide and Easyb

Easyb Selenide Integration

Page 38: Easy tests with Selenide and Easyb

Problem Selenide shoulds vs Easyb shoulds

Easyb catches any 'should' (shouldBe, shouldHave, ...) except “should” and “shouldNot”

showPasswordCheckBox().shouldNot(checked);

//Less readable:(

Page 39: Easy tests with Selenide and Easyb

Solution => Decorators

showPasswordCheckBox().shouldNot(be(checked));

showPasswordCheckBox().should(be(not(checked)));

Page 40: Easy tests with Selenide and Easyb

All Together :)

Page 41: Easy tests with Selenide and Easyb

Preconditions to BDD

● PO knows what is Criteria of Good Requirement

● Manual QA knows how to write “Automatable” Scenarios

Team is competent :)

Page 42: Easy tests with Selenide and Easyb

Pending Easyb Story by PO

description "Products List page"

scenario "Add new product", {

given "On Products List page"

then "new product can be added"

}

Page 43: Easy tests with Selenide and Easyb

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"

}

Page 44: Easy tests with Selenide and Easyb

Implemented Easyb Storydescription "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)); }}

Page 45: Easy tests with Selenide and Easyb

Easyb Report

Page 46: Easy tests with Selenide and Easyb

FailedEasyb Report

Page 47: Easy tests with Selenide and Easyb

Alternative: TestNG testpublic 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);

}

}

Page 48: Easy tests with Selenide and Easyb

Alternative: TestNG Report

Page 49: Easy tests with Selenide and Easyb

Failed TestNG Report

Page 50: Easy tests with Selenide and Easyb

When Easyb ?

● Detailed reporting of test steps

● Ordered tests execution (as present in the file)

● “Somebody” wants Gherkin

– Automation resources are limited, and help may come from PO or Manual QA providing detailed 'steps to code'

Page 51: Easy tests with Selenide and Easyb

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.

Page 52: Easy tests with Selenide and Easyb

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

Page 53: Easy tests with Selenide and Easyb
Page 54: Easy tests with Selenide and Easyb

Q&A

Page 55: Easy tests with Selenide and Easyb

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/

Page 56: Easy tests with Selenide and Easyb

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

– https://github.com/elaides/gribletest● To Maksym Barvinskyi for application under test

– http://grible.org/● To Andrei Solntsev, creator of Selenide, for close

collaboration on Selenide Q&A, and new features implemented:)

Page 57: Easy tests with Selenide and Easyb

Contacts

[email protected]

● skype: yashaolin

● http://www.linkedin.com/in/iakivkramarenko