sebaslogen / CleanGUITestArchitecture

Sample project of Android GUI test automation using Espresso, Cucumber and the Page Object Pattern
MIT License
137 stars 31 forks source link

Nice Work!! But "i_login_with_username_and_password" has an issue... (Maybe) #8

Closed HowardSchmaeu closed 7 years ago

HowardSchmaeu commented 7 years ago

First of all thank you for this Project ... it's nice and clear ... and very Helpful !!

But :-) in the Function [i_login_with_username_and_password] the using with the PageObject Pattern is i bit to much coupled i think.

For Example: if i would write a Test called "User can't login without a valid password" (of course i have to change your [UserLoginTask] a bit) i'm not able to use the same [StepDefinitions.java] with a new Function like this:

@Then("^I still see the login screen$") public void something() { mCurrentPage.is(LoginPage.class); }

because the Constructor called in [WelcomePage] just check the ViewID. May all this can be right and did not understand the context ... but for my perspective should be the constructor Code :

onView(withId(R.id.welcome_activity)).check(matches(isDisplayed()));

somewhere in the StepDefinitions. Or?

sebaslogen commented 7 years ago

In cases were you want to test negative scenarios that don't lead to the Welcome screen/activity/page, you should create a new step like "^I login with incorrect user name \"(.+)\" and password \"(.+)\"$" which calls a new method in LoginPage.java like doInvalidLogin(...) and this method should return the ErrorPage you expect to show to the user in this scenario.

This simple example project does accept any login data so it does not show errors when credentials are wrong like in a real world app, but the takeaway is that scenarios that lead to different places should be called from different methods (doLogin/doInvalidLogin/doLoginWithNetworkProblem...) and have different PageObjects returned that reflect one to one the screens of you real application.

HowardSchmaeu commented 7 years ago

okay i see... u said it's better to write an additional Function in LoginPage instead of using something like this:

@ScenarioId("FUNCTIONAL.AUTH.SCN.004") @UserStory("MyApp-135") @login-scenarios Scenario: User can't login without a valid password Given I see the login page When I login with user name "ThirdUser" and password "passion1" Then I still see the login screen

Where you just need another Step in the StepDefinitions.java

sebaslogen commented 7 years ago

Exactly. Also, the implementation of @Then("^I still see the login screen$") is equivalent to @Given("^I see the login page$") so you can reuse the code inside:

@When("^I still see the login screen$")
public void i_still_see_the_login_page() {
    i_see_the_login_page();
}

I would even reuse the first step because the full scenario still makes sense for me (but this is a personal preference):

@ScenarioId("FUNCTIONAL.AUTH.SCN.004") @UserStory("MyApp-135") @login-scenarios
Scenario: User can't login without a valid password
Given I see the login page
When I login with invalid user name "ThirdUser" and password "passion1"
Then I see the login page

Anyway, the real world scenario would not end in login page but probably end in some error page or the login page with some error dialog on top, real apps always give feedback when a login attempt is invalid or fails.

HowardSchmaeu commented 7 years ago

okay thx for clarifying these things...

sebaslogen commented 7 years ago

You're welcome 👍