Hifaces20 Testing package - testing, tracing and debugging web applications with Jetty

Introduction

I am one of those developers who like to see how things work from inside. That's why I spend much more time with the source code, debugger and tracer rather than with javadocs or reference documentation.

When it comes to web applications I need an infrastructure that actually allows be to trace the running code. That is, start the web application, set the breakpoint, see get it triggered, see how and what is invoked. I want to be able to debug the web application just as I'd debug a desktop or a command-line app.

The problem with web applications is that they run on the server. This makes things more complicated since you need to setup this server, deploy your application - and somehow get your debugger working.

Over the past years I've tried numerous solutions for web app debugging - from remote debugging to special IDE plugins, but I wasn't really satisfied with any of this. It was always too much dependencies on the external server instance and IDE and too few control of what's happening.

Finally I have developed an approach which is based on the embeddable usage of Jetty. Jetty is a lightweight HTTP server and servlet container, which is very easy to embed in your own applications. By "embedding" I mean that you can create, configure and run a Jetty instance programmatically. For instance, from your unit or integration test.

Hifaces20 Testing package

The hifaces20-testing package provides a non-invasive infrastructure which allows you to start and run your web application in a servlet container directly from your test.

Web application environment

Core element of this infrastructure is the web application environment modelled by the WebAppEnvironment. Web application envrionnment is basically a servlet container (Jetty) which runs a single web application (your application). Basic usage is as follows:

// Create a Jetty-based web application environment
final WebAppEnvironment webAppEnvironment = new JettyWebAppEnvironment(
	// host, port, context path, location
	"127.0.0.1", 8080, "Test", "src/main/webapp");

// Start the server
webAppEnvironment.start();

// The server is running now
// Do some testing

// Stop the server
webAppEnvironment.stop();

Injecting the web application environment into your tests

Configuring, starting and stopping the server is actually a routine task, the code is almost the same. To avoid repetitions and keep it all as less invasive as possible, hifaces20-testing implements an approach which allows you to simply get an instance of web application environment injected into your test. There's two parts of this solution: indicating that you need an instance of WebAppEnvironment in your test and making use of the testing tools that actually create an instance of the web application environment, start it, pass it to your test and shut it down afterwards.

In order to indicate that you want an instance of WebAppEnvironment to be injected into your test, you can do one of the following:

To make this annotation or interface work you need to actually employ the testing infrastructure hifaces20-testing offers. Depending on the testing framework you're using there are different ways of achieving that:

Examples:

JUnit 3.8
public class JUnit38Test extends AbstractWebAppEnvironmentJUnit38Test {

	public void testIt() {
		Assert.assertTrue(getWebAppEnvironment().isStarted());
	}

}
JUnit 4
public class JUnit4Test extends AbstractWebAppEnvironmentJUnit4Test {

	public void testIt() {
		Assert.assertTrue(getWebAppEnvironment().isStarted());
	}

}
JUnit 4 with rule
public class JUnit4WithRuleTest {

	private WebAppEnvironment webAppEnvironment;

	@PropertiesWebAppEnvironmentConfig
	public void setWebAppEnvironment(WebAppEnvironment webAppEnvironment) {
		this.webAppEnvironment = webAppEnvironment;
	}

	@Rule
	public MethodRule webAppEnvironmentRule = WebAppEnvironmentRule.INSTANCE;

	@Test
	public void checkRule() {
		assertThat(webAppEnvironment, notNullValue());
	}

}
TestNG
public class TestNGTest extends AbstractWebAppEnvironmentTestNGTest {

	@Test
	public void checkRule() {
		Assert.assertTrue(getWebAppEnvironment().isStarted());
	}

}
Spring Test
@RunWith(SpringJUnit4ClassRunner.class)
@TestExecutionListeners({WebAppEnvironmentTestExecutionListener.class,
 	DependencyInjectionTestExecutionListener.class})
@ContextConfiguration("applicationContext.xml")
public class SpringTest {

	@PropertiesWebAppEnvironmentConfig
	public WebAppEnvironment webAppEnvironment;

	@Test
	public void checkRule() {
		assertThat(webAppEnvironment, notNullValue());
	}

}

Configuring web application environment for your tests

The @PropertiesWebAppEnvironmentConfig annotation actually specifies the location of the web.properties file which provides host, desired port, context path and home directory of the web application. Here's a sample file:

web.properties
webapp.host=127.0.0.1
webapp.port=8080
webapp.contextPath=MyWebApp
webapp.home=src/main/webapp

By default this file is searched under src/test/resources/web.properties, but you can specify a different location in the @PropertiesWebAppEnvironmentConfig annotation:

public class AlternativeWebPropertiesTest {
	@PropertiesWebAppEnvironmentConfig("src/main/webapp/WEB-INF/web.properties")
	public WebAppEnvironment webAppEnvironment;

	@Rule
	public MethodRule webAppEnvironmentRule = WebAppEnvironmentRule.INSTANCE;

	@Test
	public void checkIt() {
		assertThat(webAppEnvironment, notNullValue());
	}

}
Please note that specified port is the desired port. If this port is already occupied then testing infrastructure will search for a free port.

Running your web application

Developing web applications involves a lot of live/hands-on testing. A quite frequent scenario is:

Hifaces20 Testing supports this scenario by providing the AbstractRunWebApp abstract base class. Here's a usage example:

public class RunMyApp extends AbstractRunWebApp {
	// Web application is configured in src/test/resource/web.properties
}

The RunMyApp is actually a pseudo-unit-test which can be started as such from the IDE (ex. in Eclipse: right click > Run As > JUnit Test).

Using Hifaces20 Testing in your builds

Maven usage

Non-Maven usage


Browse Space

- Pages
- News
- Labels
- Attachments
- Bookmarks
- Mail
- Advanced
- Activity

Explore Confluence

- Popular Labels
- Notation Guide

Your Account

Log In

 

Other Features

Add Content