Page objects my two cents

In this post I would like to make you aware of the pitfalls of the classic page object approach and give insights in how to improve your page objects setup.

Classic approach

The Page Object pattern is very popular among automated testers. Its essence is that all the selectors by which the elements are searched for on the web page of the application under test are moved … exactly, into constants:

public class OrderPage {
  @FindBy(name = "firstName")
  public WebElement firstName;
  @FindBy(name = "lastName")
  public WebElement lastName;
  @FindBy(name = "deliveryDate")
  public WebElement deliveryDate;
}

Nice, huh? The good thing about such pagination objects is that you don’t have to duplicate the same locator in hundreds of different tests. When the locator changes, it only needs to be changed in one place.

And tests do not need to be changed often because they use a page object:

@Test
  public void userCanOrder() {
    OrderPage page = new OrderPage(webdriver);
    firstName.sendKeys("Neil");
    lastName.sendKeys("Jones");
    deliveryDate.sendKeys("19-03-1986");
  }

This approach became especially popular via Martin Fowler, who stated the ground rule for test automation:

The test should not contain any locator. Locators should be hidden in the page objects. If the locator is visible in the test, it is an invalid test.

What’s the catch?

We forget that it’s not just locators that change. The logic of working with elements is changing. Let’s say you have a hundred tests that contain this line:

deliveryDate.sendKeys("19-03-1986");

Yes, it’s kind of good if the locator changes – a hundred tests will remain intact.

But what if this element <input> suddenly turns into a calendar type control? You know, in which you first need to click the calendar icon, then select the year, then the month, and only then the day.

How to handle?

I tend to follow this rule:

You need to take out not constants, but logic

The page object should not have a field deliveryDate, but a method.

public class OrderPage {
  public void enterDeliveryDate(String deliveryDate) {
  
    Selector(By.name("deliveryDate")).sendKeys(deliveryDate);
  
    // you can implement the new calendar type here on one place!
  }
}

Now, if the logic of working with the deliveryDate element (including the locator) changes, not a single test will change – only the page object. Of course, in this case, the fields of the page object must be private so that no one can use them directly, but only through the methods of the page object.

Happy testing!

Quickly identify and inspect chrome problems on mobile devices

I post this as a giveaway to help testers and developers quickly identify (possible) problems on websites when using mobile devices. I noticed there is no general awareness how to quickly check and verify console errors in mobile devices on IOS or Android when using a chrome browser.

Open a new tab on your mobile device in chrome and type in address bar:

chrome://inspect

You will now see the following screen:

Now you can open a new tab with your web application or website you want to verify. Notice all javascript logging is displayed on the chrome inspect tab.

This way you can verify quickly if there are any console errors or identify possible problems with your web application on mobile devices.

Happy testing!

3 Questions you should ask yourself before automating a functional test scenario

The list of functional test automation frameworks is endless nowadays. A pitfall off this ease of automation is that testers get overenthusiastic in automating all functional test scenarios. As a result you can be busy whole day maintaining your automated regression testset. If you have a large project, the number of tests to maintain can grow exponentially during the years. The time to create test scenarios and manual/exploratory testing time decreases, because all time will be spent on refactoring your automated tests. In my experience manual and exploratory testing is still an essential part of the software testing process. Automated tests are robotic and don’t necessarily act as a real user would. Protractor for example is manipulating the browser DOM by injection some javascript to be able to wait for synchronisation. Manual testing, on the other hand, allows the tester, a real user, to be in control of the tests. Nevertheless automation is  necessary to cope with the current rapid software release cycles.

To determine which logical tests scenarios are eligible to be automated you can ask yourself the following questions.

1. Is this or part of the scenario already covered by a system integration or unit test?

The mindset of developers regarding testing is changed radically the last couple of years. More and more developers understand the importance of writing unit tests and integration tests to improve code quality. This has resulted in a lot of javascript end-to-end testing frameworks, most of them based on the Selenium WebDriver API. With those frameworks a lot of user input element functionality can be checked before the functional system test phase. For example the behaviour of a custom dropdown element can completely be tested with a end-to-end javascript testing framework like Nightwatch.js. As a tester, when starting in a new or existing project, it is always wise to check the unit test and system integration test code to determine functionality that is already covered. Also ask a developer about their vision on testing, this can lead to new insight for you and the developer. Also reviewing/skimming the quality of the tests written by developers can be of great help to improve software quality.

2. Can the functionality be tested with a more ‘low-maintainable’ test?

If I have a functional test scenario I try to put it as low as possible in the testing pyramid. If the level is not suitable for the scenario I go one level up. Think about a situation here were you want to automate the following scenario. A user enters an account number into a web application form. The server can reply with a valid or invalid response. The invalid response can result in 20 different error messages. Given this situation a tester can write functional scenarios for all error messages. This can result in possibly 20 functional testscripts. My solution for this situation would be to verify the server frontend mechanism with one functional automated test and verify if all the messages are returned correctly with one or more backend  integration testcases.

3. Is this critical system functionality?

This question is especially for starting projects, when you start writing some script, take baby steps. Think, “what is the minimalistic thing I want right away!”. Keep building on top of it whenever tasks get complicated. Functional testing scenarios often have a lot of overlap in test steps to be able to prepare certain scenarios. It will save you a lot of time in the future when generic functions are created which can be reused in the test scripts. I see the generic functions as lego bricks which can be used for automated testcase construction.

Test automation is becoming more and more important due to faster development iterations and agile methodologies. Overthinking were and how certain functionality of your application will be tested can take effort to accomplish but it saves you a lot of valuable work time in the future.

TestCafe and why you should try it!

Every test automation engineer is known with the popular automation frameworks like protractor, webdriver.io or nightwatch.js. They all have in common that they are based on the selenium/webdriver framework. To communicate with the browsers the frameworks are depending on plugins. ChromeDriver is needed to communicate with Chrome, IEDriverServer to communicate with Internet Explorer etc. If you are testing in a multi browser environment it is very hard to write stable tests that are non flaky for all the browsers and driver plugins.

Unlike the majority of other end-to-end (e2e) testing tools, TestCafe is not dependent on Selenium or WebDriver. Instead, it injects scripts into the browser to communicate directly with the DOM and handle events. It works on any modern browser that supports HTML5 without any plugins. Further, it supports all major operating systems and can run simultaneously on multiple browsers and machines. TestCafe started as a paid product but became open-source late 2016. The popularity is increasing rapidly, in the last couple of months the GitHub project is starred from hundreds to over 4000!

I used the basic example (Node.js based). After installing the dependencies I ran npm test. Without any additional configuration it started my installed browsers ( Chrome/Safari/Firefox ) and the example tests were executed WOW.. no installation of drivers needed run out of the box :-).

Syntax is really awesome you can use es6 async await to handle promise chain. Also other cool es6 features like imports and classes. I am going to explore this tool a little bit more for sure during the next couple of weeks.