Better Bullshit Driven Development [SeleniumCamp 2017]

101
@juliaviluhina @yashaka Better Bullshit Driven Development

Transcript of Better Bullshit Driven Development [SeleniumCamp 2017]

Page 1: Better Bullshit Driven Development [SeleniumCamp 2017]

@juliaviluhina @yashaka

Better Bullshit Driven Development

Page 2: Better Bullshit Driven Development [SeleniumCamp 2017]

@juliaviluhina @yashaka

automician.com seleniumcourses.com

About

Page 3: Better Bullshit Driven Development [SeleniumCamp 2017]

@juliaviluhina @yashaka

Better Bullshit Driver DevelopmentPreface

Page 4: Better Bullshit Driven Development [SeleniumCamp 2017]

Plan

Preface: Classic BDD & xUnit examples

BDD Intro

Better BDD with xUnit + Allure

Q&A

Page 5: Better Bullshit Driven Development [SeleniumCamp 2017]

BDD?

Page 6: Better Bullshit Driven Development [SeleniumCamp 2017]

xUnit stylepublic class DiasporaTest extends BaseTest { LoginPage loginPage = new LoginPage(); NewPost newPost = new NewPost(); Stream stream = new Stream(); @Test public void shareMessage() { loginPage.open(); loginPage.signIn(Users.Selenide.username, Users.Selenide.password); newPost.start(); newPost.write("Selenide 4.2 released!"); newPost.share(); stream.shouldHavePostWithText(0, "Selenide 4.2 released!"); }}

Page 7: Better Bullshit Driven Development [SeleniumCamp 2017]

xUnit stylepublic class DiasporaTest extends BaseTest { LoginPage loginPage = new LoginPage(); NewPost newPost = new NewPost(); Stream stream = new Stream(); @Test public void shareMessage() { loginPage.open(); loginPage.signIn(Users.Selenide.username, Users.Selenide.password); newPost.start(); newPost.write("Selenide 4.2 released!"); newPost.share(); stream.shouldHavePostWithText(0, "Selenide 4.2 released!"); }}

Page 8: Better Bullshit Driven Development [SeleniumCamp 2017]

BDD style (option 1)@defaultsFeature: Diaspora Scenario: Share message Given I open login page And I do sign in with credentials: 'selenide', 'xxxxxxxx' When I start new post And write new post message: 'Selenide 4.2 is released!' And share new post Then stream should have post with index '1' of text 'Selenide 4.2 is released!'

Page 9: Better Bullshit Driven Development [SeleniumCamp 2017]

BDD style (option 1)public class DiasporaStepdefs { LoginPage loginPage = new LoginPage(); NewPost newPost = new NewPost(); Stream stream = new Stream(); @Given("^I open login page$") public void I_open_login_page(){ loginPage.open(); } @And("^I do sign in with credentials: '(.+)', '(.+)'$") public void I_do_sign_in_with_credentials_selenide_yagniyagni(String username, String password) { loginPage.signIn(username, password); } ...

Page 10: Better Bullshit Driven Development [SeleniumCamp 2017]

BDD style (option 1)

...@When("^I start new post$")public void I_start_new_post(){ newPost.start();}@And("^write new post message: '(.+)'$")public void write_new_post_message_Selenide_is_released_(String text){ newPost.write(text);} ...

Page 11: Better Bullshit Driven Development [SeleniumCamp 2017]

BDD style (option 1)

... @And("^share new post$") public void share_new_post() { newPost.share(); } @Then("^stream should have post with index '( \\d+)' of text '(.+)'$") public void stream_should_have_post_with_index_of_text_Selenide_is_released_(int index, String text) { stream.shouldHavePostWithText(index-1, text); }}

Page 12: Better Bullshit Driven Development [SeleniumCamp 2017]
Page 13: Better Bullshit Driven Development [SeleniumCamp 2017]

BDD style (option 2)

@defaultsFeature: Diaspora Scenario: Share message Given I signed in from login page with credentials: 'selenide', 'xxxx' When I publish new post: 'Selenide 4.2 is released!' Then I should see new post 'Selenide 4.2 is released!' in the top of stream

Page 14: Better Bullshit Driven Development [SeleniumCamp 2017]

BDD style (option 2)

public class DiasporaStepdefs { LoginPage loginPage = new LoginPage(); NewPost newPost = new NewPost(); Stream stream = new Stream(); @Given("^I signed in from login page with credentials: '(.+)', '(.+)'$") public void I_signed_in_from_login_page_with_credentials_selenide_yagniyagni(String username, String password) { loginPage.open(); loginPage.signIn(username, password); } ...

Page 15: Better Bullshit Driven Development [SeleniumCamp 2017]

BDD style (option 2)...

@When("^I publish new post: '(.+)'$") public void I_publish_new_post_Selenide_is_released_(String text) { newPost.start(); newPost.write(text); newPost.share(); } @Then("^I should see new post '(.+)' in the top of stream$") public void I_should_see_new_post_Selenide_is_released_in_the_top_of_stream(String text) { stream.shouldHavePostWithText(0, text); }}

Page 16: Better Bullshit Driven Development [SeleniumCamp 2017]
Page 17: Better Bullshit Driven Development [SeleniumCamp 2017]

BDD Intro

Page 18: Better Bullshit Driven Development [SeleniumCamp 2017]

= ?BDD

Page 19: Better Bullshit Driven Development [SeleniumCamp 2017]

= ? human readable

scenarios

BDD

Page 20: Better Bullshit Driven Development [SeleniumCamp 2017]

= ? human readable

scenarios

pretty reports

BDD

Page 21: Better Bullshit Driven Development [SeleniumCamp 2017]

= ... human readable

scenarios

pretty reports

BDD

Page 22: Better Bullshit Driven Development [SeleniumCamp 2017]

= OptimisedATDD BDD

Page 23: Better Bullshit Driven Development [SeleniumCamp 2017]

=BDD OptimisedATDD

giving as a bonus: readable scenarios and

reports

Page 24: Better Bullshit Driven Development [SeleniumCamp 2017]

= OptimisedATDD

=

?

BDD

Page 25: Better Bullshit Driven Development [SeleniumCamp 2017]

= OptimisedATDD

=

Devs write tests first

BDD

Page 26: Better Bullshit Driven Development [SeleniumCamp 2017]

= OptimisedATDD

=

Devs write acceptance tests first

BDD

Page 27: Better Bullshit Driven Development [SeleniumCamp 2017]

= OptimisedATDD

=

Devs write acceptance tests first

based on scenarios already written by BA/PO

BDD

Page 28: Better Bullshit Driven Development [SeleniumCamp 2017]

= OptimisedATDD

=

Devs write acceptance tests first

based on scenarios already written by BA/PO

BDD

Page 29: Better Bullshit Driven Development [SeleniumCamp 2017]

=BDD OptimisedATDD

=

Devs write acceptance tests first

based on scenarios already written by BA/PO

unbiased thinking of end product

doing things once (reqs are 2 in 1 - are already automatable)

Page 30: Better Bullshit Driven Development [SeleniumCamp 2017]

=BDD OptimisedATDD

=

Devs write acceptance tests first

based on scenarios already written by BA/PO

unbiased thinking of end product

doing things once (reqs are 2 in 1 - are already automatable)

Page 31: Better Bullshit Driven Development [SeleniumCamp 2017]

OptimisedATDD

=

Devs write acceptance tests first

based on scenarios already written by BA/PO

unbiased thinking of end product

doing things once (reqs are 2 in 1 - are already automatable)

Behaviour Driven Development

Page 32: Better Bullshit Driven Development [SeleniumCamp 2017]

OptimisedATDD

=

Devs write acceptance tests first

based on scenarios already written by BA/PO

unbiased thinking of end product

doing things once (reqs are 2 in 1 - are already automatable)

Beh?viour Driven Development

Page 33: Better Bullshit Driven Development [SeleniumCamp 2017]

OptimisedATDD

=

Devs write acceptance tests first

based on scenarios already written by BA/PO

Automation engineers write tests after.

adding extra “readable scenarios” layer for “good

reports”

Beh?viour Driven Development

vs

vs

Page 34: Better Bullshit Driven Development [SeleniumCamp 2017]

OptimisedATDD

=

Devs write acceptance tests first

based on scenarios already written by BA/PO

Automation engineers write tests after.

adding extra “readable scenarios” layer for “good

reports”

Bullshit Driven Development

vs

vs

Page 35: Better Bullshit Driven Development [SeleniumCamp 2017]

WTF?

adding additional limited pseudo-programming layer just to make tests readable

and with good reports?

Page 36: Better Bullshit Driven Development [SeleniumCamp 2017]

WTF?

adding additional limited pseudo-programming layer just to make tests readable

and with good reports?

Page 37: Better Bullshit Driven Development [SeleniumCamp 2017]

Better “Bullshit” Driven Development

without additional limited pseudo programming layers ;)

Page 38: Better Bullshit Driven Development [SeleniumCamp 2017]

Readable xUnit

Page 39: Better Bullshit Driven Development [SeleniumCamp 2017]

pom.xml with just xUnit + Selenide<dependencies> <dependency> <groupId>com.codeborne </groupId> <artifactId>selenide </artifactId> <version>4.2 </version> <scope>test </scope> </dependency> <dependency> <groupId>junit </groupId> <artifactId>junit </artifactId> <version>4.12 </version> </dependency></dependencies>

Page 40: Better Bullshit Driven Development [SeleniumCamp 2017]

xUnit + PageObject with readable stepspublic class DiasporaTest extends BaseTest { LoginPage loginPage = new LoginPage(); NewPost newPost = new NewPost(); Stream stream = new Stream(); @Test public void shareMessage() { loginPage.open(); loginPage.signIn(Users.Selenide.username, Users.Selenide.password); newPost.start(); newPost.write("Selenide 4.2 released!"); newPost.share(); stream.shouldHavePostWithText(0, "Selenide 4.2 released!"); }}

Page 41: Better Bullshit Driven Development [SeleniumCamp 2017]

xUnit + PageObject with readable stepspublic class DiasporaTest extends BaseTest { LoginPage loginPage = new LoginPage(); NewPost newPost = new NewPost(); Stream stream = new Stream(); @Test public void shareMessage() { loginPage.open(); loginPage.signIn(Users.Selenide.username, Users.Selenide.password); newPost.start(); newPost.write("Selenide 4.2 released!"); newPost.share(); stream.shouldHavePostWithText(0, "Selenide 4.2 released!"); }}

Page 42: Better Bullshit Driven Development [SeleniumCamp 2017]

xUnit + PageObject with readable stepspublic class DiasporaTest extends BaseTest { LoginPage loginPage = new LoginPage(); NewPost newPost = new NewPost(); Stream stream = new Stream(); @Test public void shareMessage() { loginPage.open(); loginPage.signIn(Users.Selenide.username, Users.Selenide.password); newPost.start(); newPost.write("Selenide 4.2 released!"); newPost.share(); stream.shouldHavePostWithText(0, "Selenide 4.2 released!"); }}

Page 43: Better Bullshit Driven Development [SeleniumCamp 2017]

xUnit + PageObject with readable steps

public class LoginPage { public void open() { Selenide.open("/users/sign_in"); } public void signIn(String username, String password) { Form form = new Form($("#new_user")); form.set("USERNAME", username); form.set("PASSWORD", password); form.submit(); }}

Page 44: Better Bullshit Driven Development [SeleniumCamp 2017]

xUnit + PageObject with readable steps

Report :(

Page 45: Better Bullshit Driven Development [SeleniumCamp 2017]

Better xUnit reports with Allure

Page 46: Better Bullshit Driven Development [SeleniumCamp 2017]

<dependencies> ... <dependency> <groupId>ru.yandex.qatools.allure </groupId> <artifactId>allure-junit-adaptor </artifactId> <version>${allure.version} </version> </dependency></dependencies>

pom.xml with Allure configuration

Page 47: Better Bullshit Driven Development [SeleniumCamp 2017]

<build> <plugins> <plugin> <groupId>org.apache.maven.plugins </groupId> <artifactId>maven-surefire-plugin </artifactId> <version>2.19.1 </version> <configuration> <testFailureIgnore>false </testFailureIgnore> <argLine> -javaagent:"${settings.localRepository}/org/aspectj/aspectjweaver/${aspectj.version}/aspectjweaver-${aspectj.version}.jar" </argLine> <properties> <property> <name>listener </name> <value>ru.yandex.qatools.allure.junit.AllureRunListener </value> </property> </properties> </configuration> <dependencies> <dependency> <groupId>org.aspectj </groupId> <artifactId>aspectjweaver </artifactId> <version>${aspectj.version} </version> </dependency> </dependencies> </plugin> ... </plugins></build>

Page 48: Better Bullshit Driven Development [SeleniumCamp 2017]

<build> <plugins> ... <plugin> <groupId>org.mortbay.jetty </groupId> <artifactId>jetty-maven-plugin </artifactId> <configuration> <webAppSourceDirectory>${project.build.directory}/site/allure-maven-plugin </webAppSourceDirectory> <stopKey /> <stopPort /> </configuration> </plugin> </plugins></build>

Page 49: Better Bullshit Driven Development [SeleniumCamp 2017]

<reporting> <excludeDefaults>true </excludeDefaults> <plugins> <plugin> <groupId>ru.yandex.qatools.allure </groupId> <artifactId>allure-maven-plugin </artifactId> <version>2.5 </version> </plugin> </plugins></reporting>

Page 50: Better Bullshit Driven Development [SeleniumCamp 2017]

xUnit + PageObject with reportable @Steps :)

public class DiasporaTest extends BaseTest { LoginPage loginPage = new LoginPage(); NewPost newPost = new NewPost(); Stream stream = new Stream(); @Test public void shareMessage() { loginPage.open(); loginPage.signIn(Users.Selenide.username, Users.Selenide.password); newPost.start(); newPost.write("Selenide 4.2 released!"); newPost.share(); stream.shouldHavePostWithText(0, "Selenide 4.2 released!"); }}

Page 51: Better Bullshit Driven Development [SeleniumCamp 2017]

xUnit + PageObject with reportable @Steps :)public class LoginPage { @Step public void open() { Selenide.open("/users/sign_in"); } @Step public void signIn(String username, String password) { Form form = new Form($("#new_user")); form.set("USERNAME", username); form.set("PASSWORD", password); form.submit(); }}

Page 52: Better Bullshit Driven Development [SeleniumCamp 2017]

xUnit + PageObject with reportable @Steps :)

Report

Page 53: Better Bullshit Driven Development [SeleniumCamp 2017]

xUnit + PageObject with reportable @Steps :)

Report

Page 54: Better Bullshit Driven Development [SeleniumCamp 2017]

xUnit + PageObject with reportable @Steps :)

Report

qwerty1234

Page 55: Better Bullshit Driven Development [SeleniumCamp 2017]

xUnit + PageObject with reportable @Steps :)

Report

qwerty1234

qwerty1234

Page 56: Better Bullshit Driven Development [SeleniumCamp 2017]

Missed “objects info” in reports :(public class DiasporaTest extends BaseTest { LoginPage loginPage = new LoginPage(); NewPost newPost = new NewPost(); Stream stream = new Stream(); @Test public void shareMessage() { loginPage.open(); loginPage.signIn(Users.Selenide.username, Users.Selenide.password); newPost.start(); newPost.write("Selenide 4.2 released!"); newPost.share(); stream.shouldHavePostWithText(0, "Selenide 4.2 released!"); }}

Page 57: Better Bullshit Driven Development [SeleniumCamp 2017]

Report :(

Missed “objects info” in reports :(

What is opened?Where do we do signin?

What do we start?

Where?

Page 58: Better Bullshit Driven Development [SeleniumCamp 2017]

Fixing “missed objects” with One Entry Point to PageObjects :)

public class DiasporaTest extends BaseTest { Diaspora diaspora = new Diaspora(); @Test public void shareMessage() { diaspora.loginPage().open(); diaspora.loginPage() .signIn(Users.Selenide.username, Users.Selenide.password); diaspora.newPost().start(); diaspora.newPost().write("Selenide 4.2 released!"); diaspora.newPost().share(); diaspora.stream().shouldHavePostWithText(0, "Selenide 4.2 released!"); }}

Page 59: Better Bullshit Driven Development [SeleniumCamp 2017]

Fixing “missed objects” with One Entry Point to PageObjects :)public class Diaspora { @Step public LoginPage loginPage() { return new LoginPage(); } @Step public NewPost newPost() { return new NewPost(); } @Step public Stream stream() { return new Stream(); } ...}

Page 60: Better Bullshit Driven Development [SeleniumCamp 2017]

Fixing “missed objects” with One Entry Point to PageObjects :)public class Diaspora { @Step public LoginPage loginPage() { return new LoginPage(); } @Step public NewPost newPost() { return new NewPost(); } @Step public Stream stream() { return new Stream(); } ...}

The simplest impl.with

redundant objects, not actually influencing

performance much

Page 61: Better Bullshit Driven Development [SeleniumCamp 2017]

Fixing “missed objects” with One Entry Point to PageObjects :)

public class Diaspora { private final LoginPage loginPage; private final NewPost newPost; private final Stream stream; public Diaspora() { this.loginPage = new LoginPage(); this.newPost = new NewPost(); this.stream = new Stream(); } @Step public LoginPage loginPage() { return this.loginPage; } ...}

but in case you bother…

Page 62: Better Bullshit Driven Development [SeleniumCamp 2017]

Fixing “missed objects” with One Entry Point to PageObjects :)

public class Application { private final LoginPage loginPage; private final NewPost newPost; private final Stream stream; public Application() { this.loginPage = new LoginPage(); this.newPost = new NewPost(); this.stream = new Stream(); } @Step public LoginPage loginPage() { return this.loginPage; } ...}

aka Application Manager

Page 63: Better Bullshit Driven Development [SeleniumCamp 2017]

Fixing “missed objects” with One Entry Point to PageObjects :)

public class DiasporaTest extends BaseTest { Application app = new Application(); @Test public void shareMessage() { app.loginPage().open(); app.loginPage() .signIn(Users.Selenide.username, Users.Selenide.password); app.newPost().start(); app.newPost().write("Selenide 4.2 released!"); app.newPost().share(); app.stream().shouldHavePostWithText(0, "Selenide 4.2 released!"); }}

aka Application Manager

Page 64: Better Bullshit Driven Development [SeleniumCamp 2017]

Fixing “missed objects” with One Entry Point to PageObjects :)

Report

Page 65: Better Bullshit Driven Development [SeleniumCamp 2017]

Fixing “missed objects” with One Entry Point to PageObjects :)

Report

May be a bit “too long” while reading to find

“logical code sentences”…

Page 66: Better Bullshit Driven Development [SeleniumCamp 2017]

Fixing “missed objects” with One Entry Point to PageObjects :)

Report

But if considerthat “each sentence” is two lines

it becomes to make sense:)

Page 67: Better Bullshit Driven Development [SeleniumCamp 2017]

Applying Fluent PageObject for easier scenarios …

public class DiasporaTest extends BaseTest { Diaspora diaspora = new Diaspora(); @Test public void shareMessage() { diaspora.loginPage().open().signIn( Users.Selenide.username, Users.Selenide.password); diaspora.newPost().start().write("Selenide 4.2 released!").share(); diaspora.stream().post(0).shouldBe("Selenide 4.2 released!"); }}

Page 68: Better Bullshit Driven Development [SeleniumCamp 2017]

Applying Fluent PageObject for easier scenarios …

public class DiasporaTest extends BaseTest { Diaspora diaspora = new Diaspora(); @Test public void shareMessage() {

diaspora.loginPage().open().signIn( Users.Selenide.username, Users.Selenide.password);

diaspora.newPost().start().write("Selenide 4.2 released!").share(); diaspora.stream().post(0).shouldBe("Selenide 4.2 released!"); }}

Page 69: Better Bullshit Driven Development [SeleniumCamp 2017]

Applying Fluent PageObject for easier scenarios …

public class DiasporaTest extends BaseTest { Diaspora diaspora = new Diaspora(); @Test public void shareMessage() {

diaspora.loginPage().open().signIn( Users.Selenide.username, Users.Selenide.password);

diaspora.newPost().start().write("Selenide 4.2 released!").share(); diaspora.stream().post(0).shouldBe("Selenide 4.2 released!"); }}

Page 70: Better Bullshit Driven Development [SeleniumCamp 2017]

Applying Fluent PageObject for easier scenarios …public class NewPost { ... @Step public NewPost start() { this.textArea.click(); return this; } @Step public NewPost write(String text) { this.textArea.setValue(text); return this; } @Step public void share(){ this.container.find("#submit").click(); }}

Page 71: Better Bullshit Driven Development [SeleniumCamp 2017]

Applying Fluent PageObject for easier scenarios …public class NewPost { ... @Step public NewPost start() { this.textArea.click(); return this; } @Step public NewPost write(String text) { this.textArea.setValue(text); return this; } @Step public void share(){ this.container.find("#submit").click(); }}

no need to be “fluent” here, as we do not know, where user should proceed a flow

Page 72: Better Bullshit Driven Development [SeleniumCamp 2017]

… may lead to “missing flow” in reports :(

Report :(

Where does the sentence start and finish?

Page 73: Better Bullshit Driven Development [SeleniumCamp 2017]

… may lead to “missing flow” in reports :(

Report :(

Where does the sentence start and finish?

Page 74: Better Bullshit Driven Development [SeleniumCamp 2017]

Fixing “missed flow” with “gherkin” pseudo-steps…

public class DiasporaTest extends BaseTest { Diaspora diaspora = new Diaspora(); @Test public void shareMessage() { GIVEN("Logged in from login page"); diaspora.loginPage().open().signIn( Users.Selenide.username, Users.Selenide.password); WHEN("Posted new message"); diaspora.newPost().start().write("Selenide 4.2 released!").share(); THEN("Message should appear in the stream"); diaspora.stream().post(0).shouldBe("Selenide 4.2 released!"); }}

Page 75: Better Bullshit Driven Development [SeleniumCamp 2017]

Fixing “missed flow” with “gherkin” pseudo-steps…public class Gherkin { @Step public static void GIVEN(String step) {} @Step public static void AND(String step) {} @Step public static void WHEN(String step) {} @Step public static void THEN(String step) {}}

Page 76: Better Bullshit Driven Development [SeleniumCamp 2017]

Fixing “missed flow” with “gherkin” pseudo-steps…

Report :)

Page 77: Better Bullshit Driven Development [SeleniumCamp 2017]

Fixing “missed flow” with “gherkin” pseudo-steps…

Report :)

Each new “code sentence”starts with a “gherkin” keyword

Page 78: Better Bullshit Driven Development [SeleniumCamp 2017]

Fixing “missed flow” with “gherkin” pseudo-steps…

Report (more complicated example)

Page 79: Better Bullshit Driven Development [SeleniumCamp 2017]

Fixing “missed flow” with “gherkin” pseudo-steps…

Report (more complicated example)

Page 80: Better Bullshit Driven Development [SeleniumCamp 2017]

Illustration (more complicated example)

Fixing “missed flow” with “gherkin” pseudo-steps…

Page 81: Better Bullshit Driven Development [SeleniumCamp 2017]

… leads sometimes to even more to readable code

THEN("Connect first cell of this column to first row from data storage");app.testTable().row(0).cell(0).fill("1").hover();EXPECT("Connection works by showing connected data in a cell tooltip (on hover)");app.testTable().toolTip() .shouldHaveKeyRowCells("", "user", "password") .shouldHaveValueRowCells("1", "vasya", "pupkin1234");

Implementation (more complicated example)

Page 82: Better Bullshit Driven Development [SeleniumCamp 2017]

… leads sometimes to not much more readable

public class DiasporaTest extends BaseTest { Diaspora diaspora = new Diaspora(); @Test public void shareMessage() { GIVEN("Logged in from login page"); diaspora.loginPage().open().signIn( Users.Selenide.username, Users.Selenide.password); WHEN("Posted new message"); diaspora.newPost().start().write("Selenide 4.2 released!").share(); THEN("Message should appear in the stream"); diaspora.stream().post(0).shouldBe("Selenide 4.2 released!"); }}

Page 83: Better Bullshit Driven Development [SeleniumCamp 2017]

… and often redundant code :|

public class DiasporaTest extends BaseTest { Diaspora diaspora = new Diaspora(); @Test public void shareMessage() { GIVEN("Logged in from login page"); diaspora.loginPage().open().signIn( Users.Selenide.username, Users.Selenide.password); WHEN("Posted new message"); diaspora.newPost().start().write("Selenide 4.2 released!").share(); THEN("Message should appear in the stream"); diaspora.stream().post(0).shouldBe("Selenide 4.2 released!"); }}

just repeats already readable “code”

Page 84: Better Bullshit Driven Development [SeleniumCamp 2017]

Fixing everything:) with “gherkin” style of One Entry Point

public class DiasporaTest extends GherkinTest { @Test public void shareMessage() { GIVEN().loginPage().open().signIn( Users.Selenide.username, Users.Selenide.password); WHEN().newPost().start().write("Selenide 4.2 released!").share(); THEN().stream().post(0).shouldBe("Selenide 4.2 released!"); }}

Page 85: Better Bullshit Driven Development [SeleniumCamp 2017]

Fixing everything:) with “gherkin” style of One Entry Point

public class GherkinTest { ... Diaspora diaspora = new Diaspora(); @Step public Diaspora GIVEN(String ... comments) { return this.diaspora; } @Step public Diaspora AND(String ... comments) { return this.diaspora; } @Step public Diaspora WHEN(String ... comments) { return this.diaspora; } @Step public Diaspora THEN(String ... comments) { return this.diaspora; }}

Page 86: Better Bullshit Driven Development [SeleniumCamp 2017]

Fixing everything:) with “gherkin” style of One Entry Point

Report :D

Each new “code sentence”starts with a “gherkin” keyword

Page 87: Better Bullshit Driven Development [SeleniumCamp 2017]

Fixing everything:) with “gherkin” style of One Entry Point

THEN("Connect first cell of this column to first row from data storage") .testTable().row(0).cell(0).fill("1").hover();EXPECT("Connection works by showing connected data in a cell tooltip (on hover)") .testTable().toolTip() .shouldHaveKeyRowCells("", "user", "password") .shouldHaveValueRowCells("1", "vasya", "pupkin1234");

Implementation (more complicated example)

with additional step comments when needed

Page 88: Better Bullshit Driven Development [SeleniumCamp 2017]

Fixing everything:) with “gherkin” style of One Entry Point

Report (more complicated example)

Page 89: Better Bullshit Driven Development [SeleniumCamp 2017]

SummaryGIVEN

no BA writing Gherkin

AND automation engineers writing tests after

WHEN

xUnit

AND Fluent PageObjects with Allure readable @Steps

AND Gherkin style of One Entry Point (aka Application Manager)

THEN

Bullshit Driven Development is Better

Page 90: Better Bullshit Driven Development [SeleniumCamp 2017]

Better Bullshit Driven Development withxUnit, Fluent PageObjects, Allure @Steps, “Gherkined" One Entry Point

• all-powerful programming language over textual-pseudo-language

• full IDE support (autocompletion, auto-generate, etc.)

• 1 abstraction layer less => simpler and faster in implementation

• still fully readable and with pretty good reports

• newcomers friendly

• Just One Entry Point to all Application Model

• structured with granular Fluent PageObjects => easier to learn&use via autocompletion

Page 91: Better Bullshit Driven Development [SeleniumCamp 2017]

Better Bullshit Driven Development withxUnit, Fluent PageObjects, Allure @Steps, “Gherkined" One Entry Point

• all-powerful programming language over textual-pseudo-language

• full IDE support (autocompletion, auto-generate, etc.)

• 1 abstraction layer less => simpler and faster in implementation

• still fully readable and with pretty good reports

• newcomers friendly

• Just One Entry Point to all Application Model

• structured with granular Fluent PageObjects => easier to learn&use via autocompletion

Page 92: Better Bullshit Driven Development [SeleniumCamp 2017]

Better Bullshit Driven Development withxUnit, Fluent PageObjects, Allure @Steps, “Gherkined" One Entry Point

• all-powerful programming language over textual-pseudo-language

• full IDE support (autocompletion, auto-generate, etc.)

• 1 abstraction layer less => simpler and faster in implementation

• still fully readable and with pretty good reports

• newcomers friendly

• Just One Entry Point to all Application Model

• structured with granular Fluent PageObjects => easier to learn&use via autocompletion

Page 93: Better Bullshit Driven Development [SeleniumCamp 2017]

Better Bullshit Driven Development withxUnit, Fluent PageObjects, Allure @Steps, “Gherkined" One Entry Point

• all-powerful programming language over textual-pseudo-language

• full IDE support (autocompletion, auto-generate, etc.)

• 1 abstraction layer less => simpler and faster in implementation

• still fully readable and with pretty good reports

• newcomers friendly

• Just One Entry Point to all Application Model

• structured with granular Fluent PageObjects => easier to learn&use via autocompletion

Page 94: Better Bullshit Driven Development [SeleniumCamp 2017]

Better Bullshit Driven Development withxUnit, Fluent PageObjects, Allure @Steps, “Gherkined" One Entry Point

• all-powerful programming language over textual-pseudo-language

• full IDE support (autocompletion, auto-generate, etc.)

• 1 abstraction layer less => simpler and faster in implementation

• still fully readable and with pretty good reports

• newcomers friendly

• Just One Entry Point to all Application Model

• structured with granular Fluent PageObjects => easier to learn&use via autocompletion

Page 95: Better Bullshit Driven Development [SeleniumCamp 2017]

Better Bullshit Driven Development ;)public class DiasporaTest extends GherkinTest { @Test public void shareMessage() { GIVEN().loginPage().open().signIn( Users.Selenide.username, Users.Selenide.password); WHEN().newPost().start().write("Selenide 4.2 released!").share(); THEN().stream().post(0).shouldBe("Selenide 4.2 released!"); }}

Page 96: Better Bullshit Driven Development [SeleniumCamp 2017]

Better Bullshit Driven Development ;)

Page 97: Better Bullshit Driven Development [SeleniumCamp 2017]

More ideas• tune Allure to report objects (via calling their toString() method)

• already possible?

• contribute?

• new Allure Feature: log object classes

• contribute?

Page 98: Better Bullshit Driven Development [SeleniumCamp 2017]

AfterwordsThere are good practices in context,

but there are no best practices.

(c) Cem Kaner, James Bach

Page 99: Better Bullshit Driven Development [SeleniumCamp 2017]

Q&A

Page 100: Better Bullshit Driven Development [SeleniumCamp 2017]

Thank you!

github.com/automician automician.com

seleniumcourses.com

juliaviluhina @

@juliaviluhina @yashaka

Page 101: Better Bullshit Driven Development [SeleniumCamp 2017]

You are welcome;)Selene in Python

NSelene in C#

Selenide snippets in Java

Yashaka talks src code

Selenide User Guide

@juliaviluhina @yashaka