Testing web applications

I've recently been assigned to develop automated tests for our main web application. The idea is basically to speed up the process of accepting new releases and avoid allowing new features to break old ones.


Our first step was to build a minimum viable product, that is, a full working test that assumed the user would always take a straightforward path inputting only valid values.

We built it using Node.js and Puppeteer. It took us about a week and we learned quite a few lessons that we were able to use when building our testing tool.

Lessons from the MVP:

I really enjoyed working with Puppeteer. In several opportunities it was necessary to send javascript to be executed within the browser. The fact that the whole test was written in Javascript was quite helpful. Some other advantages were: I was already familiar with node and javascript, I could easily use command line tools that I am familiar with and the Vim text editor.

The downside was that the company we hired to develop the tests wouldn't work with Puppeteer. The contract was in their side on this. If we wanted to share our test code with them, we would need to adopt their technology, that is Java and Selenium.

Recreating the MVP with Java

I actually enjoyed the fact that I now had to work with Java. It is a language I had never had much interest in ― not even when my brother and I decided to build Android apps (we chose Python with Kivy back than). Now that my main job was requiring me to work with Java I had the perfect opportunity and incentive to learn a new language.

For me the worst part of Java until now is that I still cannot work with Vim. I'm aware there are Java developers that use Vim, but it is quite hard to find references that would help you on this. I had never used an IDE before. I worked with Python, PHP, JavaScript, Go, Shell Script and even QlikView Script and yet I've always could easily use vim.

Now I had a different situation. I had a deadline, a different language with a community that seems to be completely dependent on their IDEs of choice. I ended up installing several of them, enabling their Vim plugins. When I thought I was familiar enough I tried turning back to vim, but it turns out I wasn't familiar enough.

It took me a whole other week to rebuild the MVP with Java and I am pretty sure it is a much worse code.

Building the testing suite

Abstracting Selenium

Our first step to improve our test code was to create our own abstraction layer for Selenium.

We created simplified versions of the actions we commonly used and avoided invoking Selenium directly from the tests.

The idea was that we could use something like this in our code:

      Browser b = new Browser();
      Page p = new Page();
      b.click(page.calendar.day(3, 5));

Separating the script from the page description

It seemed reasonable from the start to separate the procedural section of the code from the page description section. The page description ought to be reused in several tests. At first we thought we would have some classes holding a bunch of CSS selectors that would be consumed by the tests. We called these page description classes Pages. The fact is that many selectors would be used a single time and moving them to the Page classes seemed to be a waste of time. So we tried to create these Pages a little smarter: they would be collection of components.

The components were basically collections of selectors and selector templates that could be reused within several tests in the same Page.

Let's consider a quick example: a calendar. A calendar would have a main selector, a selector for the next month and previous month, and a selector builder that would return the selector for a day.

The idea is that the test may invoke a method that would look like something like this:

      Page p = new Page();