2

I have a login page in my application which I am trying to automate. Should that be automated with a POM class which has a different function for each action, like this:

public class LearningPOM {

    WebDriver driver;

    @FindBy(id="loginId")
    WebElement loginTB;

    @FindBy(id="password")
    WebElement passwordTB;


    @FindBy(id="QTP_LoginButton")
    WebElement loginButton;

    public LearningPOM(WebDriver driver) {
        this.driver = driver;
        PageFactory.initElements(driver, this);  // Initializes all elements described above 
    }

    public void fillLoginTB(String name){
        loginTB.sendKeys(name);
    }

    public void fillPasswordTB(String password){
        passwordTB.sendKeys(password);
    }

    public void clickLoginButton(){
        loginButton.click();
    }
}

Or can I just use one function to login instead of three, like this:

public void login(String name,String password){
        loginTB.sendKeys(name);
        passwordTB.sendKeys(password);
        loginButton.click();
}
5

If you think about what a method actually is (a procedure specific to that class to achieve a certain result or get a value) then I would use a single Login method. Having a one-on-one relation between methods and individual elements is not doable for larger pages, and it will make your test methods very long.

My PageObjects usually have at least these same (similar) methods:

  • EnterData (input all values per the test data)
  • Save (or Next, or Finish...)

Why separate these two? For some tests, you might want to click Cancel/Previous instead of Save, for example. This makes the flow clear in your test method.

  • +1 Keep your test methods as short as possible and readable. Just don't separate unless you need them for your tests. :) – Niels van Reijmersdal May 18 '17 at 10:57
2

Only program the actions (class methods) you really need. Apply the YAGNI principle. Don't write code you think you might need in the future, this will only add maintenance as you write more code than needed.

Make sure the tests are readable and describe the user behaviour. So in the example case you give, the user behavioural action is to login. So one Login action in your PageObject would suffice, no need to split it up in three separate methods.

Once you have a need for the separate methods in one of your tests split the action up in multiple actions.

If your actions become large functions (5-10+ lines) try to split them up for readability. Apply Clean Code practises just like you would with production code.

Data Objects

In your login example you pass the username and password to the login action. Here I would pass a userObject instead. It is a test-data class containing the username and password. In your tests you use something like

page.login(new User('Admin'));

In your login method:

public void login(user){
   loginTB.sendKeys(user.name);
   passwordTB.sendKeys(user.password);
   loginButton.click();
}
1

If controls are used only together (it does not make sense to fill/click one but not the other), handle them in a single method. If they can be used separately, handle them in separate methods. Possibly provide reasonable defaults.

PageObjects provide services for tests. Design them in a way so writing tests is easier. Encapsulate all the info about the page and hide from test parts which are not relevant - so if you need to change how the page behaves, changes to tests should be minimal.

If two widgets which always have to be filled together are filled using two separate methods calls, you may forget to call one of them in test, and you have problem.

In your example, having 3 separate methods gives you no gain, just headache, and possibility of forgetting one of them.

In is just common sense design, no magic.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.