Monday, January 10, 2011

JUnit Annotation Type - RunWith

7. Annotation Type RunWith:  

When a class is annotated with @RunWith to extends a class annotated with @RunWith, JUnit will invoke the class it references to run the tests in the class instead of the runner built into JUnit. For example, suites in the JUnit 4 are built using RunWith, and a custom runner names Suite:

@RunWith(Suite.class)
@SuiteClasses(ATest.class, BTest.class, CTest.class)
public class ABCSuite{
}

Class Parametrized:

The custom runner Parameterized implements parameterized tests. When running a parameterized test class, instances are created for the class-product of the test methods and test data elements.

Junit Parameterized Test is new feature invoked in JUnit4, it means vary parameter value for unit test. In fact some method have many difference parameters value to input, if you write a testcase for per parameter value, this could be quite large numbers of test case you need to code in Junit, which has supported class Parameterized as for Parameterized Test function, use @RunWith annotate Parameterized as this test class runner, use @Parameters annotate method data() and it have to return List[], the parameter will pass into class constructor as argument.

Example:

Write the following JUnitTest in Eclipse.

import java.util.Arrays;
import java.unit.Collection;
import junit.framework.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;

 @RunWith(value = Parameterized.class)
public class JUnitTest extends Assert{

            String name;
            int age;

            public JUnit4Test(String name, int age){
                      this.name = name;
                      this.age = age;
            }

           @Parameters
           public static Collection<Object[]> data(){
                    object[][] data = new Object[]{{"Parameterized test1",       10},{"Parameterized test2", 20}};
                    return Arrays.asList(data);
           }

          @Test
          public void testOut(){
                   System.out.println(name + " " + age);
          }

Output:
Parameterized test1 10
Parameterized test2 20

JUnit Annotation Type - AfterClass

6. Annotation Type AfterClass:

If you allocate expensive external resources in a BeforeClass method you need to release them after all the tests in the class have run. Annotating a public static void method with @AfterClass causes that method to be run after all the tests in the class have been run. All @AfterClass methods are guaranteed to run even if a BeforeClass method throws exception. The @AfterClass method declared in superclasses will be run after those of the current class

Here is a simple example:
public class Example{
        DatabaseConnection database;
        @BeforeClass
         public static void login(){
                database = ...;
     
         @Test
         public void something(){
                ...
         }

        @Test
         public void somethingElse(){
               ...
         }

         @AfterClass
         public static void logout(){
                  database.logout();
         }
}

Example in Eclipse:

import java.util.Date;

public class Person2{

         private Date birthday;
         private String name;

         public Person2(String name, Date birthday){
                 this.name = name;
                 this.birthday = birthday;
          }

          public Person2(String name){
                 this.name = name;
           }

           public Date getBirthday(){
                  return birthday;
           }

           public void setBirthday(Date birthday){
                   this.birthday =  birthday;
           }

           public String getName(){
                    return name;
           }

           public void setName(String name){
                    this.name = name;
            }

           public int getAge(){
                   if(this.birthday == null return 0;
                   Date now = new Date();
                   return now.getYear() - this.birthday.getYear() + 1;
            }
}

Here is the test code which is used to test class Person2.

import org.junit.*;
import java.util.Date;
import java.text.SimpleDateFormat;

public class Person2Test extends Assert{
         public static SimpleDateFormat df;
         private Person2 person2;

         @BeforeClass
         public static void BeforeClass(){
                  df = new SimpleDateFormat("yyyy-mm-dd");
                  System.out.println("BeforeClass");
         }

         @Before
         public static void setUp() throws Exception{
                  Date date = df.parse("2010-10-14");
                  Person2 = new Person2("Jimmy", date);
                  System.out.println("setUp");
        }

        @Test
         public void getAge(){
                  assertEquals(person2.getAge(), 6);

                  System.out.println("Test getAge");
        }

       @Test
         public void getName(){
                  assertEquals(person2.getName(), "Jimmy");


                  System.out.println("Test getName");
        }

        @After
         public void tearDown() throws Exception{
                  person2 = null;

                  System.out.println("tearDown");
        }



        @AfterClass
         public static void BeforeClass(){
                  df = null;
                  System.out.println("AfterClass");
         }
}

JUnit Annotation Type - BeforeClass

5. Annotation Type BeforeClass:  

Sometimes several tests need to share computationally expensive setup (like logging into a database), While this can compromise the independence of tests, sometimes it is a necessary optimization. Annotating a public static void no-arg method with @Before causes it to be run once before any of the test methods in the class. The @BeforeClass methods of superclasses will be run before those the current class.

For example:

public class Example{
         @BeforeClass public static void onlyOnce(){
            ...
          }

          @Test public void one(){
            ...
          }
     
          @Test public void two(){
            ...
          }
}

JUnit Annotation Type - After

4. Annotation Type After:

If you allocate external resources in a Before method you need to release them after the test runs. Annotating a public void method with @After causes that method to be run after the Test method. All @After methods are guaranteed to run even if a Before or Test method throws an exception. The @After methods declared in superclasses will be run after those of the current class.

Here is a simple example:

public class Example{
         File output;
         @Before public void createOutputFile(){
                     output = new File(...);
          }

         @Test public void something(){
                   ...
          }

         @After public void deleteOutputFile(){
                 output.delete();
          }
}

Example in Eclipse:

Create the class called Person in eclipse.

package test;

public class Person
{
       private String name;
    
       public Person(String name)
       {
             this.name = name;
       }

      public String getName()
      {
           return name;
      }
}

Here is the test cose which is used to test Person class.

package test;

import static org.junit.Assert.*;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class PersonTest
{
        private Person person;

       @Before
       public void setUp() throws Exception{
               person = new Person("Jimmy");
               System.out.println("setUp");
       }

      @Test
       public void getName(){
                assertEquals(person.getName(), "Jimmy");
                System.out.println("Test getName");
       }

      @After
      public void tearDown() throws Exception{
               person = null;
               System.out.println("tearDown");
     }
}

Output:
setUp
Test getName
tearDown

JUnit Annotation Type - Before

3. Annotation Type Before: 

When writing tests, it is common to find that several tests need similar object created before they can run. Annotating a public void method with @Before causes that method to be run before the Test method. The @Before methods of superclasses will be run before those of the current class.

Here is a simple example:



public class Example{
       List empty;
       @Before
        public void initialize(){
               empty = new ArrayList();
         }
         @Test public void size(){
             ...
         }
          @Test public void remove(){
             ...
        }
}

JUnit Annotation Type - Ignore

2. Annotation Type Ignore:

Sometimes you want to temporarily disable a test or a group of tests. Methods annotated with Test that are also annotated with @Ignore will not be executed as tests. Also you can annotate a class containing test methods with @Ignore and none of the containing tests will be executed. Native JUnit 4 test runners should report the number of ignored tests along with the number of tests that ran and number of tests that failed.

For example:

@Ignore @Test public void something(){ ...

@Ignore takes an optional default parameter if you want to record why a test is being ignored.

@Ignore("not ready yet") @Test public void something() { ...

@Ignore can also be applied to the test class.
                 @Ignore public class IgnoreMe{
                             @Test public void test1(){....}
                             @Test public void test2(){....}
                  }

Example: Create a following class in Eclipse and name it as JUnitTest4

import org.junit.Ignore;
import org.junit.Test;

public class JUnitTest4
{
       @Test
       public void test1()
       {
              System.out.println("test1");
       }

       @Ignore("not ready yet")
       @Test
       public void test2()
       {
              System.out.println("test2");
       }

       @Test
       public void test3()
       {
              System.out.println("test3");
       }
}

Right click within the test method area and choose "Run As - JUnit Test"

Figure: Example for JUnit @Ignore annotation

JUnit Annotation Type - Test

1. Annotation Type Test

The Test annotation tells JUnit that the public void methos to which it is attached can be run as a test case. To run the method, JUnit first constructs a fresh instance of the class then invokes the annotated method. Any exceptions thrown by the test will be reported by JUnit as failure. If no expectations are thrown, the test is assumed to have succeeded.

A simple test looks like this:

public class Example{
        @Test
         public void method(){
                org.junit.Assert.assertTrue(new ArrayList().isEmpty());
          }
}

Example in Eclipse IDE:

1. Open your Eclipse IDE.
2. Add a new class to the test project
3. If needed please import the Junit library to your currect project decency libraries.
4. Write a class named SimpleTest and extend junit.framework.TestCase (actually if you Junit4, you don't need extend junit.framework.TestCase)
5. Write a test method and asserting desired result. You can use annotation "@Test" to declare this method is test method.

Figure: Example for JUnit @Test annotation






Right click within the test method area and choose "Run As - JUnit Test"

Test annotation with optional parameters:

The Test annotation supports two optional parameters:

a. expected
b. timeout

1.1 Test annotation with 'expected' optional parameter:

The first, expected, declared that a test method should throws an exception. If it doesn't throw an exception or it it throws a different exception that the one declared, the test fails. For example, the following test succeeds.

Example:

@Test(expected=IndexOutOFBoundsException.class)
public void outOfBounds(){
        new ArrayList<Object>().get(1);
}

Example in Eclipse:

Crate a following class in Eclipse IDE.

import org.junit.*;

public class JunitTest2
{
         @Test(expected = ArithmeticException.class)
          public void divisionWithException(){
          int i = 1/0;
          }
}

Right click within the test method area and choose "Run As - Junit Test"

Figure: Test annotation with expected parameter.
In the above example, the divisionWithException() method will throw an ArithmeticException exception, since this is an expected excpetion, so the unit test will pass.

1.2 Test annotation with 'timeout' optional parameter:

The second optional parameter, timeout, causes a test to fail if it takes longer than a specified amount of clock time (measured in milliseconds). The following test fails.

Example:

Create a following class in Eclipse IDE and name it as JUnitTest3

import org.junit.Test;

public class JUnitTest3
{
       @Test(timeout=1000)
       public void infinity()
       {
               while(true)
       }
}

Right click within the test method area and choose "Run As - JUnit Test"

Figure: Test annotation with timeout parameter
In the above example, the infinity() method will throw an time out exception, and the test will fail.