Saturday, 14 February 2009

jIntegrationTest Framework.

The Framework.

jIntegrationTest comes from my own experience working in many projects and trying to figure out how could I do the integration tests easier. Usually you will find two approaches: using mocking frameworks or just deploying the application and testing it.

The Mocking Approach.

One approach is using one of the many *.Mock.* frameworks out there. It's a valid one and it works (easy for POJO's, no that easy if you want to mock something more complex as HTTP request for example) but you probably will found yourself writing a lot of code and spending a lot of time just to replicate the behaviour of the application.

Mocking as you are developing and designing it's OK, as you don't have the actual code or HTML's or pages (that's the whole point of mocking). But at the end of the day, when you have the real code it feels lacking doing the integration testing through all that mocking infrastructure as you are not getting most of the real errors you would get in the real environment (application, system, configuration, environment, dependencies errors etc...). The good thing about this approach is that fits easily with automatic testing and continuous integration.

Just Deploy and test Approach.

The other approach and sadly the most common one it's just doing the deployment and see what happens. OK the deployment fails because the XML descriptors are wrong or a file it's missing or we are getting a null pointer. Fix it, compile, test and deploy again. And so on. At last the deployment works, start testing the application, now one SQL sentence is failing. You do it again.. and again :). Now everything seems to work but now one new component is added and the deployment process fails again :(.

Well it's clear how many time it's wasted following this approach and what is worst, you are never sure that you are not breaking something when you add something new having to do expensive regression tests. It's obvious this approach it's no very easy to automatize.

Why to use Embedded Servers and jIntegrationTest.

At this point it's when the idea of using embedded servers (and of course jIntegrationTest) comes handy as you won't have any of the problems of the former approaches:
  • Don't need to replicate the behaviour of the application, just test the expected real results, being a number, a HTTP response, the creation of a component...
  • Don't need to deploy the application to test it, just run the the integration test units from Eclipse, maven, ant etc.. getting an instant feedback.
  • Don't need to do regression testings as the process can be automatized.
The advantages of using jIntegrationTest are:
  • You get all the above advantages.
  • Many embedded servers out of the box: HTTP (Jetty), DB (HSQLDB), Web Services (Apache CXF), Spring (Container and MVC), JMS(ActiveMQ) and RMI.
  • Easy configuration relying on defaults and annotations (almost none).
  • Based on JUnit so it's very easy to get into.
  • Many Integration Test Units out of the box: HTTP, DB, Spring, Spring MVC, JSF, Web Services....
A quick example

You can find the complete application and tests in the folder examples/invoices of the jIntegrationTest release.

@HttpIntegrationConfigurationTest( port=9006, root="/test", src="src/main/webapp/")
public class InvoicesControllerTest extends AbstractIntegrationHttpTest {

public void testController() throws Exception {
String uri = "http://localhost:9006/test/invoice.do";
assertResponseStatusOK(uri);
}
}


In this test we are testing an actual controller of the application which is responsible of invoking a service that calculates the invoice.

As we are testing a controller we need to use a HTTP embedded server, which configuration it's very easy, just need a port, a web root and the root location of the web application in your file system.

It's just a simple test in which the framework will execute a request to the indicated URL, in this case the invocation URL of the controller, just if someone would have pressed a button to generate the invoice. If the server returns an OK (200 code) the test will pass.

Of course, if there is any problem in your web application you will get an error and you could fix it right away without having to deploy again.

2 comments:

Anonymous said...

I can not compile your whole project successfully even after downloading all source codes from google web site,which includes jservicerules,jcontenedor & jembedded,but there is something wrong with these source codes,e.g "org.jsemantic.jcontenedor.lite.ContenedorLite" still in org.jsemantic.jembedded.core.annotation.ServiceAnnotationProcessor,but we know it had been moved to "org.jsemantic.jcontenedor.core.ContenedorLite"

Admin said...

Hi,

just download the latest version, now the project is called jintegration-test (same url).