When to replace Unit Tests with Integration Test

Its been a while I was thinking about integration vs unit testing. Lots of googling, questions in stack overflow and looking in many books. In this post I would like share with you the information I have found and what decision I arrive at this.

I think if you put this question to any Java developer, you will get an anwser supporting the unit test instantaneously. They will tell you that if you can not do unit testing, the unit of code you hava written is large and you have to bring it down to multiple testable unit. I have found these questions in Stack Overflow 1, 2, 3 and 4 useful in getting a good understanding of both terminologies.

Unit testing is widly followed in Java domain with most of the projects now also enforcing the code coverage and unit testing. Integration testing is relativly new and misunderstood concept. Even through it is practiced much less than, unit testing there can be varios uses of it. Lets take a simple user story and revisit both.

Lets consider it with a user story

User will give an INPUT in a UI form and when the submit button is clicked, the PROCESSED output should be shown in the next page. Since the results should be editable, both INPUT and OUTPUT should be saved in the database.

Technical Design

Lets assume that our application will grow rapidly in the future and we will design it now keeping that in mind. 

As shown in the above image it is a standard 4-tier design with view, service, dao. It has a application layer which contains the logic of how to convert the input into output. To implement the story we wrote 5 methods(1 in service, 2 dao to save input and output, 1 contains the business and 1 method in view layer to prepare the input.)

Writing some Unit test cases

If we were to unit test the story, we need to write 5 tests. As the different layers are dependent, we might need to use mock objects for testing. But apart from one method in application layer that does the original process, is there any need to unit test the other part? For example the method,

 public void saveInput(Input input){  
           Session session = sessionFactory.getCurrentSession();  

When you unit test this, you will typically use a mock object of sessionFactory and the code willl always work. Hence I don't see much point in wiring a unit test here. If you observe carefully, apart from the application layer, all the other methods will be similar to what we have discussed.

What can we acheive with integration test?

Read here as a heads up for the integration test. As we have seen most of the unit tests for this story were not effective. But we can't skip testing as we want to find out the code coverage and make our code self testing. According to Martin flower in his article about Continuous Integration you should write the code that can test the other code. I fell the good integration tests can do this for you.

Lets write a simple itegration test for this situation,

 @Configurable(autowire = Autowire.BY_NAME)   
 @ContextConfiguration(locations = {"classpath:applicationContext.xml"})  
 public class SampleIntTest {  
      private SamService samService;  
      public void testAppProcessing(){  
      Input input = new Input();  
      //prepare input for the testing.  
      Output output = samService.processInputs(input);  
      //validate outpt gainst the given input.  
           Assert.fail("Validation failed!");  

I have skipped the view layer here as it not so relevent. We are expecting the INPUT from the UI in a bean Input and thats that we willl have in the service layer. Here, With this few line of coding, you can acheive the full functionality of the application from the service layer.

It is prefered to use a in-memory database like H2 for integration tests. If the table structure is complicated it may not be possible in that case,you can use a test instance of DB and prepare a script to delete all the data and run it as part of the test so that the DB state is restored back. This is important because in the next run the same data will be saved again.

Another advantage of integration tets is that if you are changing the implementation the test need not be changed because it ic concerned with the input and output.This is useful in refactoring the code without change in the test code. Also, you can schedule these tets to measure the stability of the appication and any regression issues can be caught early.

As we have seen, integration test are easy to write and are useful, but we need to make sure it does not replace the unit testing completely. When ever there is a rule base system(like the LogicalProcesser in our case) it should be mandatory because you can't cover all the scenarios with the integration test.

So as always JEE is about making choice asnd sticking to it. For the last few months we were practicing it in our teams and it is really going well. Currently we made integration test mandatory and unit tests and optional. Always review the code coverage and make sure you get good coverage in the core of the system(the LogicalProcesser in our case).

Developing Java Web Applications with Tapestry 5

In this post I would like to share my experience with  developing Java Web Applications with Tapestry 5.

Tapestry is a component oriented framework for creating dynamic, robust, highly scalable web applications in Java. Tapestry is been is here for a while now, not really taken off as a web framework for Java. In the past, it is been critisized for non compatability of its versions. After the release of version 5 in 2008 it has been more consistant and popular with developers.

I have been using Tapestry for the last 15 months and used both version 5.0.18 and 5.2.6. One of the main issues with tapestry was the learning curve and that is been some what improved now, with the exelent documentation available at the project home page here. You don't see  a lot of tapestry resources online. If you search for the tapestry resources in internet you might end up getting t3 or t4 versions which will not be usefull with the new t5 version.

Having worked in tapestry for more than one year, I must say that I have mixed opinion about tapestry. Its POJO based approach is really nice and it also scores as a component based framework. The components are easily plug-gable in all the pages. There has been a lot of improvements in the ability of unit testing the pages. Even if you don't want to depend on tapestry's test classes you can create your own integration test cases as the pages are simple java classes. It has really good integration with spring that opens your window to all other frameworks and technologies.

The biggest pain is been when you are stuck with problems, the alternatives were really difficult. For example there is a grid component in tapestry which by default provides sorting for all the columns in the grid. If you need to disable sorting, there should be hell lot of things you have to do as told here. In another example, you might need to have 3 classes construct a simple drop down in tapestry as told here. In today world of IDE tapestry don't have much of IDE support and that can be a pain while you develop a page in tapestry.

Its been really difficult to find good resouces about tapestry and I thought of sharing some links that I found useful during my learning of tapestry. As I told already the getting started page is reaaly improved and now you can really get started with tapestry in that page. The wiki page contains lots of tips and tricks on how to use tapestry features.

The Tapestry Jump Start page is great place with lots of examples that will help you get into tapestry. Howard M. Lewis Ship the creator of Tapestry writes about tapestry in his personal blog is also a good read.  Recently I have found another site with lots of exapmle in tapestry.  Even the Tapestry360 is a fresh and new concept.I  really liked Mark Shead blog post is a good collection of usefull references about tapestry5.

When you are thinking about java web framework I think tapestry should be one of the choices. If You compare tapestry with other web framework there will be lots of diffidence have a look at Matt Raible presentation about comparing jvm web frameworks also the matrix comparing the web frameworks in Java. Also there is a post from Joshua about why you should consider tapestry5.