Automating NS Reisplanner App

This Testing Showcase demonstrates the automation of the NS Reisplanner App for Android.

Share This:

Automating ParkMobile App

This Testing Showcase demonstrates the automation of the ParkMobile App for Android.

Share This:

Clean(er) Test Automation Code

This blog post tries to explain why it is important to really care about your test (automation) code and write clean (automation) code. I’m mainly involved in test automation, so some of the examples given are related to that, but most are related to programming in general. Often test automation code is less exposed to a formal review process. Keep in mind; test automation is code and should threated like that.

I hope this blog post will bring you one step closer to clean(er) code.

Test Class Naming
Defining a classname for unit testing is rather easy; it’s the same name as the implementation class. In terms of functional or integration testing, the classname should reflect the feature or functionality you are testing.

For example:

public class LoginTest { }

public class RegistrationTest { }

public class OrderTest { }

Test Method Naming
I have been on many projects, some Greenfield* others continuing development on an existing codebase. Every project has its own naming convention* or not ☺. The following can happen in projects without naming convention:

@Test
public void test1() { }

@Test
public void test2() { }

// or:

@Test
public void testLogin() { }

Do you get the point? It’s all very descriptive, isn’t it?

Imagine you have to share this with a colleague or you have to present the results to non-tech colleagues, they have no clue what’s going on.

I very much like the naming convention introduced by Roy Osherove (http://osherove.com/blog/2005/4/3/naming-standards-for-unit-tests.html). The basic idea to describe the tested method, expected input or state and the expected behaviour as the name of the test method.

public void nonExistingCredentialsGiven_ShouldThrowException() {

}

We can adopt this principle for feature testing as well.

public void nonExistingCredentialsGiven_ShouldShowErrorMessage() {

}

By following this naming convention we can make sure that the intent of the test is clear to everyone. (Off course the implementation should reflect the method name) Method names are a bit longer, but self-explanatory.

Naming of fields and local variables

Another thing that strikes me is the use of non-explicit fields or variable name. Like:

i for loops
page when applying the Page Object Model (everything is a page lol)
And so on..

We need to be more explicit if we want to create readable code.

Magic numbers
Magic numbers indicates the direct usage of a number in your code. By doing this, your code becomes less readable and harder to maintain.

Example implementing magic numbers:

public class Username {

	private String setUsername;

	public void setUsername(final String username) {
		if (username.length() > 10) {
			throw new IllegalArgumentException("username");
		}
		this.setUsername = username;
	}

}

After refactoring

public class Username {

	private static final int MAX_USERNAME_SIZE = 10;
	private String setUsername;

	public void setUsername(final String username) {
		if (username.length() > MAX_USERNAME_SIZE) {
			throw new IllegalArgumentException("username");
		}
		this.setUsername = username;
	}

}

The refactored example allows you to easily update the maximum size of a username, even if its used in different methods.

A general rule of thumb might be when applying any naming convention is to be very explicit.

Greenfield: setup a project from scratch.
Naming convention: set of rules

Other Test Naming Conventions: https://dzone.com/articles/7-popular-unit-test-naming

Share This:

Disposable Selenium Grid

Over time your Selenium Grid might become unstable due to browsers not being closed properly, browser error popups and so on. This blogpost will cover the creation of a disposable Selenium Grid. Since the introduction of Docker the creation of containers (a kind of virtual machine) became a lot easier. With Docker-compose you can even describe your multi-container setup in a recipe-style providing step-by-step procedures.

  1. Install Docker (https://docs.docker.com/compose/install/)
  2. Put the file below somewhere
  3. Run the following command: docker-compose up

Getting the Selenium Grid Address
Use the following command to get retrieve the IP-address of your Docker container: docker-machine ip
In your script you can use http://[IP]:4444/wd/hub in order to connect to your Selenium Grid.

Scaling you Selenium Grid
With the following command you can easily scale up/down your Selenium Grid
docker-compose scale chromenode=15 firefoxnode=15

Filename: docker-compose.yml

seleniumhub:
  image: selenium/hub
  ports:
    - 4444:4444
  environment:
    - GRID_MAX_SESSION=50

firefoxdebug:
  image: selenium/node-firefox-debug
  environment:
    SCREEN_WIDTH: 2880
    SCREEN_HEIGHT: 1800
  ports:
    - 5900
  links:
    - seleniumhub:hub
firefoxnode:
  image: selenium/node-firefox
  environment:
    SCREEN_WIDTH: 2880
    SCREEN_HEIGHT: 1800
  ports:
    - 5900
  links:
    - seleniumhub:hub
chromenode:
  image: selenium/node-chrome
  environment:
    SCREEN_WIDTH: 2880
    SCREEN_HEIGHT: 1800
  ports:
    - 5900
  links:
    - seleniumhub:hub

Share This:

Automatically update drivers

Getting tired of downloading the latest driver into your project? You might want to take a look at gradle-download-task. This plugin allows you to download files (over HTTP and HTTPS) to a specific destination directory.

Herewith a simple example:

/**
 * Include the gradle-download-task plugin
 */
plugins {
    id 'de.undercouch.download' version '3.1.0'
}
 
apply plugin: 'java'
apply plugin: 'eclipse'
 
/**
 * Import the Download task. This line is optional.
 * You can of course also always use the full qualified name
 * when you specify a task of type 'Download'.
 */
import de.undercouch.gradle.tasks.download.Download
 
/**
 * The following two tasks download a ZIP file and extract its
 * contents to the build directory
 */
task downloadZipFile(type: Download) {
    src([
        'http://chromedriver.storage.googleapis.com/2.22/chromedriver_mac32.zip',
        'https://github.com/mozilla/geckodriver/releases/download/v0.9.0/geckodriver-v0.9.0-mac.tar.gz'
    ])
    dest buildDir
    acceptAnyCertificate true
    overwrite true
}
 
task downloadAndUnzipFile(dependsOn: downloadZipFile, type: Copy) {
    from zipTree('build/chromedriver_mac32.zip')
    into 'src/main/resources'
     
    from tarTree('build/geckodriver-v0.9.0-mac.tar.gz')
    into 'src/main/resources'
}
 
defaultTasks 'downloadAndUnzipFile'

You only need to update the version numbers (from time to time) and the files will be downloaded and extracted. (eventually in src/main/resources)

Share This:

Firefox Marionette Driver

As announced some time ago, FirefoxDriver will nolonger work after Firefox 47 has been released. There are 2 options;

  1. Downgrade Firefox (version < 47)
  2. Implement Marionette Driver. (Marionette WebDriver)

This blogpost will cover the implementation of Marionette Driver. Luckily it’s not too hard to switch to MarionetteDriver. Following these steps:

  1. Download Marionette Driver
  2. Extract the file
  3. Set the webdriver.gecko.driver property to the location path of Marionette driver
  4. Adjust the code, to something like this:
    	@BeforeClass
    	public void startFirefox() {
    		System.setProperty("webdriver.gecko.driver", "path/to/geckodriver");
    		final WebDriver driver = new MarionetteDriver();
    		driver.get("http://www.google.com");
    	}
    

Alternatively we can implement a method to find the file on path:

	private static String findFileOnPath(final String fileName) {
		return MarionetteDriverTest.class.getClassLoader().getResource(fileName).getPath();
	}

MarionetteDriverTest is the classname.

And use it like this:

	@BeforeClass
	public void startFirefox() {
		System.setProperty("webdriver.gecko.driver", findFileOnPath("geckodriver")); //assuming the file is located in the resources folder
		final WebDriver driver = new MarionetteDriver();
		driver.get("http://www.google.com");
	}

Share This:

Genereer Leanpub book

While writing a book (Leanpub) it might be useful to quickly replace a lot of variables in one go. Therefore I created this tool. GenerateBook-all-1.0.jar

The tool expects to following directory structure:

|-orig/ (folder containing the original files)
|-manuscript/ (if this folder does not exist it will be created)
|prop.properties (file containing all variables you want to replace)

Example prop.properties file content:
authors=Author1 and Author2
demo.url=http://example.com
software.version=12.3

Usage:
To use this tool: java -jar GenerateBook-all-1.0.jar

Example output:
Copied: orig/chapter1.md to manuscript/chapter1.md

I hope this tool is useful for you and additional features can be requested via comments.

Share This:

Generate Leanpub Book

While writing a book (Leanpub) it might be useful to quickly replace a lot of variables in one go. Therefore I created this tool. GenerateBook-all-1.0.jar

The tool expects to following directory structure:

|-orig/ (folder containing the original files)
|-manuscript/ (if this folder does not exist it will be created)
|prop.properties (file containing all variables you want to replace)

Example prop.properties file content:
authors=Author1 and Author2
demo.url=http://example.com
software.version=12.3

Usage:
To use this tool: java -jar GenerateBook-all-1.0.jar

Example output:
Copied: orig/chapter1.md to manuscript/chapter1.md

 

I hope this tool is useful for you and additional features can be requested via comments.

Share This:

2015 Retrospective: a year’s reflection

My first year as a independent software testing professional. This year I worked as a Technical Test Specialist/Coach in the energy branch. My main task was/is to setup a testautomation framework and support 10+ scrum teams with creating automated testscripts.

I experienced/applied some new techniques, like: docker, vagrant, gatling, wiremock.

I initiated a interest group for technical testers. We periodically organize sessions to share knowledge about technical testing (tools / methedologies / practices).

I also achieved the following certificates:

  • Professional Scrum Master (PSM 1)
  • Professional Scrum Developer (PSD 1)
  • Professional Scrum Product Owner (PSPO 1)

Next year I will continue my current assignment.

Share This:

Testing AngularJS applications in plain Java

You might think that protractor is the way to go when testing AngularJS applications… The thing with AngularJS is that you can decide to remove all class and id‘s from the rendered html. (which is good for page rendering times, but bad for testability). In the template files there are some identifiers, but those are not visible in the rendered html, all the webelements with a template identifier have a class with the value ng-binding (or something very similar).

We have a very large broad IT-landscape with a big variety of applications. (JSF (JavaServer Faces) websites, AngularJS websites, JMX services, web services (REST and WSDL), mail server integration, PDF reader, FTP, Ora cle DB and perhaps mobile in the future).

In this case I decided to write a Java-based test automation solution. Protractor is built on top of WebDriverJS. So, I thought the same actions can be done in Java. I found https://github.com/paul-hammant/ngWebDriver which suits our needs. Don’t forget to set the setScriptTimeout(), otherwise it might not work.

Share This: