Tapestry part V - Testing a page

Introduction

In this blog we will demonstrate how to test a webpage within the Tapestry framework. The framework comes with a few handy testing options. Here we will consider the PageTester object, which can be used to replicate interactions between user and application. It deals with all input and output on the pages. As such it is great for User Acceptance Testing and Unit Testing. To show how to use the PageTester we will add some tests to the Hello Tapestry example of the first blog in the series.

Prerequisites

Setup

Create a new test class by adding IndexTest to the "src/test/java" folder.

package nl.uglyduckling.hello.pages;

import static org.junit.Assert.*;

import org.apache.tapestry5.dom.Document;
import org.apache.tapestry5.test.PageTester;
import org.junit.Test;

public class IndexTest {
	private final String PAGE_NAME = "Index";
	
	private PageTester tester;

	public IndexTest() {
		String appPackage = "nl.uglyduckling.hello";
		String appName = "app";
		String context = "src/main/webapp";
		tester = new PageTester(appPackage, appName, context);
	}
	
	@Test
	public void confirmIndexIsLoaded() {
		Document document = tester.renderPage(PAGE_NAME);

		String markup = document.toString();
		String expectedWelcome = "Name :";
		assertTrue(markup.contains(expectedWelcome));
	}
}

In the constructor we setup the PageTester for our target application. By doing that, the Jetty server only needs to be started once for all the tests we are going to run for index page. The second method confirms that the page is loaded correctly.

index

Recall that the index page looks like this on first load. We can check if the page is loaded as expected by validating if the elements we expect are actual rendered. We do this by checking the DOM that is returned by the renderPage method.

To run the test you will need to add JUnit to your Build Path. (I most case Eclipse will suggest you to do this if you haven't already done so.)

Using the same approach we can also check if the footer of the page has been rendered correctly. This is tested by the following test method

@Test
public void checkFooter() {
   Document document = tester.renderPage(PAGE_NAME);   
   String markup = document.toString();
   String expectedWelcome = "© Ugly Duckling 2016";
   assertTrue(markup.contains(expectedWelcome));
}

Testing Form input

Of course we can't leave the main functionality of our web application untested. Let's add a test for input Fred. We expect a page with "Hello ...." and "Fred" as a response. To test this using PageTester we must:

  1. Get the form element from page
  2. Submit the form and it's values
  3. Validate that the resulting DOM of the HTML page is as expected.

This can be done as follows

@Test
public void helloFred() {
   String name = "Fred";
   String nameOfInputFieldInForm = "nameOfUser";

   Document document = tester.renderPage(PAGE_NAME);
   Element form = document.getElementById(FORM_NAME);
   Map<String, String> formValues = new HashMap<String, String>();
   formValues.put(nameOfInputFieldInForm, name);
	
   Document documentWithFormData = tester.submitForm(form, formValues);
						
   String markup = documentWithFormData.toString();
   String expectedHello = "Hello ....";
   assertTrue(markup.contains(expectedHello));
   assertTrue(markup.contains(name));
}

Running Tests using Maven

For most of this series we have been using Maven to build and run the project. So we would like to be able to run the tests also with Maven. To do this we set up a run configuration for running the tests. From the menu in Eclipse select Run -> Run Configuration and create a new Maven configuration like this

test run configuration mvn

Frustratingly the test will not get detected if you try to use the Maven run configuration we just setup. The default POM will try to use testng, which will not pick up the JUnit tests. To change this we need to instruct Surefire to use the correct dependencies. We can do so be adding this snippet the to the Surefire section of the POM

<dependencies>
   <dependency>
      <groupId>org.apache.maven.surefire</groupId>
      <artifactId>surefire-junit47</artifactId>
      <version>2.18.1</version>
   </dependency>
</dependencies>

The complete Surefire setup should look something like this

 <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.7.2</version>
    <dependencies>
       <dependency>
          <groupId>org.apache.maven.surefire</groupId>
          <artifactId>surefire-junit47</artifactId>
	  <version>2.18.1</version>
        </dependency>
     </dependencies>
     <configuration>
        <systemPropertyVariables>
           <tapestry.execution-mode>Qa</tapestry.execution-mode>
        </systemPropertyVariables>
     </configuration>
</plugin>

Now if you run Maven test you getmaven test results

Code

Code is available here : helo_tapestry_pagetest

Complete Listing IndexTest

package nl.uglyduckling.hello.pages;

import static org.junit.Assert.*;

import java.util.HashMap;
import java.util.Map;

import org.apache.tapestry5.dom.Document;
import org.apache.tapestry5.dom.Element;
import org.apache.tapestry5.test.PageTester;
import org.junit.Test;

public class IndexTest {
	private final String PAGE_NAME = "Index";
	private final String FORM_NAME = "inputform";
	
	private PageTester tester;

	public IndexTest() {
		String appPackage = "nl.uglyduckling.hello";
		String appName = "app";
		String context = "src/main/webapp";
		tester = new PageTester(appPackage, appName, context);
	}
	
	@Test
	public void confirmIndexIsLoaded() {
		Document document = tester.renderPage(PAGE_NAME);

		String markup = document.toString();
		String expectedWelcome = "Name :";
		assertTrue(markup.contains(expectedWelcome));
	}
	
	@Test
	public void checkFooter() {
		Document document = tester.renderPage(PAGE_NAME);

		String markup = document.toString();
		String expectedWelcome = "© Ugly Duckling 2016";
		assertTrue(markup.contains(expectedWelcome));
	}
	
	@Test
	public void helloFred() {
		String name = "Fred";
		String nameOfInputFieldInForm = "nameOfUser";
		
		Document document = tester.renderPage(PAGE_NAME);
		Element form = document.getElementById(FORM_NAME);
		Map<String, String> formValues = new HashMap<String, String>();
		formValues.put(nameOfInputFieldInForm, name);
		
		Document documentWithFormData = tester.submitForm(form, formValues);
						
		String markup = documentWithFormData.toString();
		String expectedHello = "Hello ....";
		assertTrue(markup.contains(expectedHello));
		assertTrue(markup.contains(name));
	}
}

Leave a Reply

Your email address will not be published. Required fields are marked *