A detailed look at the Coffee machine project with Selenium

In the tutorial CI in 5 minutes flat, we have seen how to easily integrate a Hiptest project with Travis-CI and get the results of the CI pushed back to Hiptest.

Now we’ll have a deeper look to one particular project: hps-java-junit-selenium. This projet has several particularities making it worth having a deeper look at than the other hps-* projects:

  • it uses Selenium to run the tests
  • it uses different languages for the test running and the implementation of the system under test
  • it can be integrated with SauceLabs and CrossBrowserTesting

So let’s have a look deeper in the project and see what are the differences between this project and the other ones.

Actionwords implementation

When taking a close look at the action words implementation, for example when comparing to the one we can found in the simple Java/Junit Coffee machine implementation, we can see that the implementation is in fact pretty close.

The only difference is the way we interact with the SUT (as this could be expected). For example, when stopping the coffee machine, the main difference is that in one case we call the methods directly on the system under test and in the other case we ask the driver (the object responsible for acting on the browser) to click on a button:

// Implementation calling functions on the system under test
public void iShutdownTheCoffeeMachine() {
   sut.stop();
}

//Implementation using the driver
public void iShutdownTheCoffeeMachine() {
driver.findElement(By.id(“onOff”)).click();
}

As the system under test is pretty simple (there are no Ajax calls made to a server for example), the implementation with Selenium stays pretty simple.
That said, when testing a more complex system, the only difference would be in the adding of some “wait” methods to ensure the element we want to click on is already available on the page.

Ensuring a browser is available and closed after each test

For this part, we will require to modify a bit the way Hiptest-publisher generates the code for the tests. Indeed, if we have a look at the way the folder “Serve coffee” is generated by default, it looks like this:

package com.coffeemachine;

import junit.framework.TestCase;

public class ServeCoffeeTest extends TestCase {
// Tags: sprint:1
public Actionwords actionwords = new Actionwords();
// Well, sometimes, you just get a coffee.
// Tags: priority:0

public void testSimpleUse() {
// Given the coffee machine is started
actionwords.theCoffeeMachineIsStarted();
// When I take a coffee
actionwords.iTakeACoffee();
// Then coffee should be served
actionwords.coffeeShouldBeServed();
}
}

This type of tests work fine in many cases (when directly calling the system under test or when testing via APIs for example). When it comes to testing with a browser (or a mobile phone simulator), we need a setup and a teardown.
The first one will ensure a browser is created before each test, the second one will ensure the broswer is closed after.

If you are familiar with Hiptest publication process, you know you should not manually modify the test scripts (only the action words library) to ensure your test suite will be able to scale.
What we will do instead is modify the way hiptest-publisher generates the test scripts so the setup and tear down will be available.
To do so, we created a folder named “templates” at the root of the project and copied the file “folder.hbs” (which can be found in the hiptest-publisher GitHub project) in it.
Then, we added the following line to the hiptest-publisher config file so it knows where to find the custom templates:

overriden_templates = templates

After some editions, the folder.hbs file now looks like this:

package {{{ context.package }}}{{{ relative_package }}};

import junit.framework.TestCase;
import org.openqa.selenium.WebDriver;

{{#if needs_to_import_actionwords? }}import {{{ context.package }}}.Actionwords;
import {{{ context.package }}}.SeleniumDriverGetter;
{{/if}}
public class {{{ clear_extension context.filename }}} extends TestCase {{#curly}}
{{#indent}}{{#if has_tags?}}{{#comment ‘//’}}Tags: {{join rendered_children.tags ‘ ‘}}
{{/comment}}{{/if}}
public Actionwords {{{ context.call_prefix }}};
public WebDriver driver;

protected void setUp() throws Exception {{#curly}}{{#indent}}
super.setUp();

driver = new SeleniumDriverGetter().getDriver();
{{{ context.call_prefix }}} = new Actionwords(driver);
{{/indent}}
{{> body}}
{{/curly}}

protected void tearDown() throws Exception {{#curly}}{{#indent}}
driver.quit();{{/indent}}
{{/curly}}

{{#each rendered_children.scenarios}}{{{this}}}
{{/each}}
{{/indent}}
{{/curly}}

As we can see, the template now include a setup and a teardown methods. In the setup, we use the SeleniumDriverGetter object to create a new driver and pass it as an argument to the Actionwords object so it is now able to interact with the browser. It is a good practice not to include the code to generate a new driver directly in the action words but leave it to an external object. Doing so, your actionwords will only contain code to interact with the application.
The teardown implementation is pretty straightfoward, ensuring the browser is closed at the end of the tests (this way you do not end up with a dozen of browser still open after your tests have been ran).

Now if we look at the code generated by hiptest-publisher for the “Serve coffee” folder, it matches our needs:

package com.coffeemachine;

import junit.framework.TestCase;
import org.openqa.selenium.WebDriver;

public class ServeCoffeeTest extends TestCase {
// Tags: sprint:1
public Actionwords actionwords;
public WebDriver driver;

protected void setUp() throws Exception {
super.setUp();

driver = new SeleniumDriverGetter().getDriver();
actionwords = new Actionwords(driver);

}

protected void tearDown() throws Exception {
driver.quit();
}

// Well, sometimes, you just get a coffee.
// Tags: priority:0
public void testSimpleUse() {
// Given the coffee machine is started
actionwords.theCoffeeMachineIsStarted();
// When I take a coffee
actionwords.iTakeACoffee();
// Then coffee should be served
actionwords.coffeeShouldBeServed();
}
}

If you want to learn more about how to customize the output of hiptest-publisher, you can have a look at those two blog posts:

 

Wrap up

As you can see, automating with Selenium (or any tool allowing you to drive an application with a browser or a mobile phone simulator) is not that different to automating tests in a more classical ways.

The first objective to complete is to ensure that your action words will be able to interact with the browser, which will generally need some customising of the publication templates.

After that, you will have to use the browser driver when needed and you are done.

Download the ebook

This field is required

This field is required

Please enter a valid email address

Thank you, the ebook has been sent to your mailbox

Hiptest is FREE for open source projects

We actually utilize a number of open source components, which is why Hiptest service is free for any open source project. We are giving back to the community!

Your open source project must meet the following criteria to be approved:

  • Your project is licensed under a license approved by the Open Source Initiative
  • Your project source code is available for download
  • Your project has a publicly accessible website

By continuing to use the site, you agree to the use of cookies. more information

The cookie settings on this website are set to "allow cookies" to give you the best browsing experience possible. If you continue to use this website without changing your cookie settings or you click "Accept" below then you are consenting to this.

Close