Wednesday, August 27, 2014

Sanjar's Blog


HOW I ORDERED AN MI3 IN LESS THAN 1 SEC ?
http://sanjar-blog.blogspot.in/

Sunday, August 17, 2014

Dynamic Suite for Junit Test cases.

Well, Today I am going to talk about a situation is which i had been (few months back) while developing a Test suite for Junit.

Test Suite: Its a program which runs list of Junit Test cases in one go.

It has got very simple piece of code.

eg.

@RunWith(Suite.class)
@SuiteClasses({Test1.class,Test2.class})
public class StaticTestSuite {

}

So, In above example we can see that we need to provide all the list of classes to be executed by the Test Suite. But, this is a static kind of Suite. Every time you have to make changes to this file to enter the Test class name.

Dynamic Situation: Suppose we have a huge list of test cases and those test cases are dynamic which keeps on added and deleted. What would we do in this case?
Yes, We would need a dynamic Suite which dynamically picks up the test classes from the classpath and include it into Suite.


Easy Solution could be Extending Suite Class. 
Let us understand this by following easy example.

1. Create 2 simple Junit Test case.

 package com.test.junit;

import org.junit.Test;


public class Test1 {
@Test
public void testIt1(){
System.out.println("Test 1 Executed.");
}
}

package com.test.junit;

import org.junit.Test;

public class Test2 {

@Test
public void testIt(){
System.out.println("Test 2 Executed.");
}
}

-----------------------------------------------------------------------------------------------------------
2. Now create the Dynamic Suite class which extends Suite.

package com.test.junit.run;

import java.io.IOException;

import org.junit.runners.Suite;
import org.junit.runners.model.InitializationError;

public class DynamicSuite extends Suite {

    public DynamicSuite(Class<?> setupClass) throws InitializationError, IOException {
       super(setupClass, DynamicTestRun.suite());
    }
}

Here we can see that, Suite class is extended, and its constructor is providing all the list of Testcases to Suite.
------------------------------------------------------------------------------------------------------------
3. Now Implement the logic of scanning all the Test cases from the class path. I have used PathMatchingResourcePatternResolver of spring framework to find the resources(class files) with given pattern.(You can implement you own scanner.)

eg.

package com.test.junit.run;

import java.io.IOException;
import java.util.LinkedList;
import java.util.List;

import org.junit.runner.RunWith;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;

@RunWith(DynamicSuite.class)
public class DynamicTestRun {
public static Class<?>[] suite() throws IOException {
List<Class<?>> classList= listMatchingClasses("classpath:/com/test/**/Test*.class");
return  (Class<?>[]) classList.toArray(new Class[classList.size()]);
}

public static List<Class<?>> listMatchingClasses(String matchPattern) throws IOException {
   List<Class<?>> classes = new LinkedList<Class<?>>();
   PathMatchingResourcePatternResolver scanner = new PathMatchingResourcePatternResolver();
   Resource[] resources = scanner.getResources(matchPattern);

   for (Resource resource : resources) {
       Class<?> clazz = getClassFromResource(resource);
       classes.add(clazz);
   }
   return classes;
}

public static Class<?> getClassFromResource(Resource resource) {
   try {
       String resourceUri = resource.getURI().toString();
       System.out.println(resourceUri);
       if(resourceUri.indexOf("com") != -1)
        resourceUri = resourceUri.substring(resourceUri.indexOf("com")).replace(".class", "").replace("/", ".");
       return Class.forName(resourceUri);
   } catch (Exception ex) {
       ex.printStackTrace();
   }
   return null;
}

}

Please do comment if you have some better solution to it and also have any question on this. I would be glad to answer it.
Thank You.
Cheers. :)

PS:  You can access the sample code from following location:
https://github.com/sanjar/Day_Today/tree/master/org.sanjar.test.junit