Blog‎ > ‎

JUnit and its Magic

posted Oct 10, 2011, 8:42 PM by Isaac Lopez   [ updated Dec 15, 2011, 12:48 PM by Victor Reina ]
By Jose Ignacio Gonzalez De La Fuente & Luis Alfredo Rivera Acuña
JUnit is a framework for unit testing in java, this framework has been ported to PHP (PHPUnit) , .NET (NUnit), and many other languages; it has a set of classes to control the various tests that you are going to do to your system; has assertion methods, which are used to verify whether the expected result is the same as the method is returning; JUnit uses annotations to handle different types of methods.

The following is a simple example of a test:
import junit.framework.Assert;
import org.junit.Test;

public class testPlayer {

@Test

public void testGetUserName() {
Person p = new Person();
Assert.assertNull("the name not its null",p.getUserName());
}
}

In this simple test, we are only ensuring that when declaring a class Person, the user name is equal to null.
As you can see before testGetUserName method is the @ Test annotation, this tells JUnit that will handle that method as a test.
(For more information about JUnit annotations see # Getting http://junit.sourceforge.net/)

Compiling Junit
This is easiest part to do, because we only have to download the source code from GitHub and enter the folder from a terminal / shell, you run the command "ant build" and the command is responsible for creating the libraries. jar of JUnit.

Recommendations

Its very recommended to compile and review the JUnit code, using the Eclipse IDE, because the project is created in this IDE.

To do it, you just have to download the plugin for eclipse Egit, then import the project from the GIT repository.
https://github.com/KentBeck/junit.git (It will ask you for a GitHub account which you can create for free)

This way you can review the code easier, exploiting the advantages of eclipse

Learning from JUnit

To run a test you can call several classes, in this case we’ll use the default class:

This is the RunJUnit.class
import org.junit.runner.JUnitCore;
import org.junit.runner.Result;
public class RunJUnit {
public static void main(String[] args) {
Result a= new JUnitCore().run(testPlayer.class);
System.out.print((a.getFailureCount()>0)?a.getFailures().get(0):"no errors");
}
}

As you can see we are using JunitCore class that is dedicated to test all tests using the Run method, this method returns an object of type Result, by which you can get the Junit report.

Obviously the easier way is to use the IDE to do this like intelliJ for example, as soon as it detects an @Test annotation you can run that class as a Test.

The first thing JUnit does is check for test methods and make a test suite with all those tests, then checks for errors and passes each test method to a Runner, a Runner notifies of significant events happening in a test, then it makes a small description of the suite and test cases and runs all the methods marked with the @Test individually (it creates an instance of the class for each test) after all the tests are run it displays the results.


As we can see in the example, the run method in the JUnitCore class doesn’t receives an instance of the class testPlayer as a parameter, it receives the class (in java a .class is called an object of type class that has methods and properties of the class that is referenced "testPlayer")

JUnit, having the class type object of your class, detects the methods that have annotations and what not, as well as which annotations it has, but how?

It’s easy!, here is a small example of how to make and get an annotation:

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.Method;

@Retention(RetentionPolicy.RUNTIME)
@interface MyAnno {
 String str();

 int val();
}

public class MainClass {

 @MyAnno(str = "Annotation Example", val = 100)
 public static void myMeth() {
   MainClass ob = new MainClass();

   try {
     Class c = ob.getClass();
     Method m = c.getMethod("myMeth");
     MyAnno anno = m.getAnnotation(MyAnno.class);//here’s how you check for annotations
     System.out.println(anno.str() + " " + anno.val());
   } catch (NoSuchMethodException exc) {
     System.out.println("Method Not Found.");
   }
 }
 public static void main(String args[]) {
   myMeth();
 }
}


As you can see the annotation are called with getAnnotation, in this case the entry "MyAnno" is called, this is an @interface annotation we can see it is declared at the beginning, the ideal situation would be create a separate file and call it as it does with JUnit in the line:

import org.junit.Test;

JUnit is responsible not only for looking methods with annotations, is also responsible for executing and storing each result, as well as storing your data (exceptions, if there’s a simple bug or a fault etc.) and returns it as a Result object for easier handling.

Community

Right now David Saff in charge of JUnit and lot of new features are coming out. With a new version released a few days ago (4.9) it seems to be going in the right direction asking for user feedback to improve.

If you pay attention JUnit’s main webpage it has a lot of useful stuff like news, articles, tools, etc. It also has a mailing list in a yahoo group and if you join it you get a pretty FAQ.txt that has many things like an overview on JUnit, how to get started, writing, organizing and running tests, best practices and other miscellanious; you can find pretty much everything you want there.

Here’s the jGuru discussion forum dedicated to JUnit.

There are 3 mailing lists:

  * JUnit announcements  

  * JUnit user list
    
  * JUnit developer list



I have to say i’m pretty surprised because what looked like a forgotten community turned out to be pretty alive.

Conclusion

JUnit is an innovative project that has enhanced and facilitated unit testing, as well as learning to develop for the simplicity of many of their classes, is very well commented and explained.

Its community looked like it had little movement compared to others since the initial developers Erich Gamma and Kent Beck interact almost nothing and Kent is currently working in JUnit Max but there’s a spark now that David Saff works in JUnit.

Based on my experience, I can say that it is a good project to get started and I’ve learn too many important things that I usually do not learn in school, such as annotations or manipulation of the object class, besides it's very understandable.

Comments