2

I am using Selenium WebDriver with Java to develop automated regression tests for a web application. Currently, I am following the Page Object Model design pattern and using the PageFactory @FindBy annotation to declare all the web elements I interact with at the top of each page class and the TestNG @DataProvider annotation to pass data input to my test methods.

While this does not pose an issue at the moment, some of the pages I will need to work with have upwards of a hundred objects on the page (e.g. form for user info), and I am worried that my current methodology could run into performance and readability issues as the test suite grows. I am still new to both Selenium and Java, but have a few questions regarding this:

  1. Are there any performance concerns with declaring hundreds of WebElements at the beginning of each page class, rather than say, storing each element's locator info in an Excel datasheet and iterating over that? Or, more generally, what are the main differences between using POM as opposed to creating a function library?

  2. As is, my test methods are looking like:

    @Test(dataProvider="testData")
    public void test(String s1, String s2, ... )
    

Which can quickly become unreadable when passing in a lot of parameters. What alternatives are there for passing in multiple inputs to a test method?

  • How about creating an single data object like arrayList/hashmap or data object(class) depending on complexity of data and just move around as single entity. – Vishal Aggarwal Oct 20 '18 at 15:00
  • I ended up using a hashmap to store data and pass as a sole parameter. Thank you for the comment – A. K Oct 24 '18 at 18:52
3

My two cents on both of your questions:

1. Page Objects and locators

I don't see a reason why you would use an Excel for storing locator info. If you class becomes too 'long' (readability-wise), you could use a constants class as alternative - but that's only the locator strings, not the FindBy annotation, so it doesn't do much really. I've always kept all information about a single Page Object in one place (the class itself).

Note: don't forget that a single web app's page is not necessarily equal to a single Page Object! For example, a web page might have a navigation bar that's present in multiple screens: extract this into a separate Page Object. It's a basic technique to keep your classes as small as possible.

2. Passing in data to tests and Page Object methods.

What's working quite handy for us is XML. Basically, you feed a test with a single XML file that contains all data for that test.

Then you pass the different nodes to their respective Page Object methods. Your XML might look like this:

<xml>
  <login>
    <user>Test user</user>
    <password>qwerty</password>
  </login>
  <profile>
    <firstname>John</firstname>
    <lastname>Doe</lastname>
  </profile>
</xml>

Your test method might look like this (thinking in C# here).

public void ExampleTest(XElement xml)
{
    loginScreen.EnterData(xml.Element("login"));
    loginScreen.Continue();
    profileScreen.EnterData(xml.Element("profile"));
    profileScreen.Save();
}
  • Thank you very much for the response. I will have to experiment with using XML files as input, but I think this is along the lines of what I was looking to do. Also - regarding your point about keeping page classes as small as possible, does that mean if I have a page with different navigation tabs (where clicking one of the tabs does not change the URL but brings up a different form for input), should I make a separate class for each of these tabs? – A. K Oct 22 '18 at 13:12
  • Yes, I'd suggest you make a different class for each subpage. After all, the fact that you have to navigate to them tells you that it's in fact a different 'object'. – FDM Oct 22 '18 at 19:12
0
  1. You should not experience any performance problems. When you use POM approach in selenium the elements are actually initialized when you attempt to invoke some action on them. Unless you call some of the element method, they stay just declared but not take any space in memory. It is called lazy initialization. There is a number of posts about it over the Internet. For example this one.

  2. This is the best approach to handle your test data. Not to make your code unreadable you can supply your fields with meaningful names. Like:

--

@Test(dataProvider="testData")
public void test(String meaninfulTestDataPiece1, String meaninfulTestDataPiece2, ... )

So to sum up: you're doing the things right.

  • So if he needs to fill in a form with 20 fields, his test method will have 20 parameters? Wow. :) – FDM Oct 19 '18 at 19:50
  • Exactly. Nothing special. – Alexey R. Oct 19 '18 at 19:51
  • 1
    Clearly we have different opinions on what 'readable' means in this context, but I'm glad it works out for you. Good info in point 1 by the way! – FDM Oct 19 '18 at 19:52
  • Appreciate your point of view. Hoewer as it seems to me keeping 20 elements in xml and write a parser for them is not easier and more readable than just having 20 fields in a method that you can format one under another to keep the code more readable. – Alexey R. Oct 19 '18 at 19:57
  • 2
    Guys, if there is a need to pass 20 parameters into a form, it makes sense to create a data object (class) that would store those fields/properties. Initializing that object with 20 fields can be done in test data preparation and than the object (single parameter!) would be passed into the test method. Remember about the code readability and software development practices. If you are passing more than 3 parameters into a method, there is a high chance that you're doing something wrong. – 501NotImplemented Oct 20 '18 at 2:36

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.