Saturday, 30 June 2018

Junit: categorising test cases

By using @Category annotation, you can place the test case (or) complete test class under specific categories.

Example 1: Placing complete test class under FastTest, ArithmeticCalculationsTest.

For example, I placed ArithmeticTest class under FastTest, ArithmeticCalculationsTest categories.

@Category({FastTest.class, ArithmeticCalculationsTest.class})
public class ArithmeticTest {

         .....
         .....

}


Example 2: Pacing the method 'factorial_5_120' under FastTest category.
         @Test
         @Category(FastTest.class)
         public void factorial_5_120() throws Exception {
                  Factorial factorial = new Factorial();

                  long actual = factorial.factorial(5);
                  long expected = 120;

                  assertEquals(expected, actual);
         }

You can execute the test cases under given category like below.

@RunWith(Categories.class)
@IncludeCategory({ ArithmeticCalculationsTest.class })
@ExcludeCategory(FastTest.class)
@SuiteClasses({ ArithmeticTest.class, FactorialTest.class, FibonacciTest.class })
public class ArithmeticTestSuite {

}

‘ArithmeticTestSuite’ class execute the tests in ArithmeticTest, FactorialTest classes by including ‘ArithmeticCalculationsTest’ category and excluding FastTest category.

@RunWith(Categories.class)
@IncludeCategory({ FastTest.class })
@SuiteClasses({ ArithmeticTest.class, FactorialTest.class, FibonacciTest.class })
public class FastTestSuite {

}

‘FastTestSuite’ class execute the ‘FastTest’ category tests in ArithmeticTest.class, FactorialTest.class, FibonacciTest.class.

Find the below working application.

Arithmetic.java

package com.sample.arithmetic;

public class Arithmetic {

 public int sum(int a, int b) {
  return a + b;
 }
 
}

Factorial.java

package com.sample.arithmetic;

public class Factorial {

 public long factorial(int num) throws Exception {
  if (num < 0) {
   throw new IllegalArgumentException("Factorial is not computed for negative numbers");
  }

  if(num > 10) {
   throw new Exception("Can't calculate factorial for big number");
  }
  
  long result = 1;

  for (int i = 2; i <= num; i++) {
   result *= i;
  }

  return result;
 }
}

Fibonacci.java

package com.sample.arithmetic;

public class Fibonacci {

 public int fibNumber(int n) {
  if (n < 0)
   throw new IllegalArgumentException("Can't calculate fiboaaci for negative numbers");
  return fib(n);

 }

 private int fib(int n) {
  if (n == 1 || n == 0)
   return 1;
  return fib(n - 1) + fib(n - 2);
 }

}

ArithmeticTest.java

package com.sample.arithmetic;

import static org.junit.Assert.assertEquals;

import org.junit.Test;
import org.junit.experimental.categories.Category;

import com.sample.categories.ArithmeticCalculationsTest;
import com.sample.categories.FastTest;

/**
 * Test cases follow below naming convention. methodName_input_output format.
 * 
 * @author krishna
 *
 */
@Category({FastTest.class, ArithmeticCalculationsTest.class})
public class ArithmeticTest {

 private Arithmetic arithmetic = new Arithmetic();

 @Test
 public void add_10And5_15() {

  int expected = 15;
  int actual = arithmetic.sum(10, 5);

  assertEquals(expected, actual);
 }

 @Test
 public void add_10AndMinus5_5() {

  int expected = 5;
  int actual = arithmetic.sum(10, -5);

  assertEquals(expected, actual);
 }
}


FactorialTest.java

package com.sample.arithmetic;

import static org.junit.Assert.assertEquals;

import org.junit.Test;
import org.junit.experimental.categories.Category;

import com.sample.categories.ArithmeticCalculationsTest;
import com.sample.categories.FastTest;
import com.sample.categories.SlowTest;

/**
 * Test cases follow below naming convention. methodName_input_output format.
 * 
 * @author krishna
 *
 */
@Category(ArithmeticCalculationsTest.class)
public class FactorialTest {

 @Test
 @Category(FastTest.class)
 public void factorial_5_120() throws Exception {
  Factorial factorial = new Factorial();

  long actual = factorial.factorial(5);
  long expected = 120;

  assertEquals(expected, actual);
 }

 @Test
 @Category(SlowTest.class)
 public void factorial_10_3628800() throws Exception {
  Factorial factorial = new Factorial();

  long actual = factorial.factorial(10);
  long expected = 3628800;

  assertEquals(expected, actual);
 }
}

FibonacciTest.java

package com.sample.arithmetic;

import static org.junit.Assert.assertEquals;

import org.junit.Test;
import org.junit.experimental.categories.Category;

import com.sample.categories.ArithmeticCalculationsTest;
import com.sample.categories.FastTest;
import com.sample.categories.SlowTest;

/**
 * Test cases follow below naming convention. methodName_input_output format.
 * 
 * @author krishna
 *
 */
@Category(ArithmeticCalculationsTest.class)
public class FibonacciTest {

 @Test
 @Category(SlowTest.class)
 public void fibonacci_7_21() {
  Fibonacci fib = new Fibonacci();
  int actual = fib.fibNumber(7);
  int expected = 21;

  assertEquals(expected, actual);

 }

 @Test
 @Category(FastTest.class)
 public void fibonacci_38_2971215073() {
  Fibonacci fib = new Fibonacci();
  int actual = fib.fibNumber(38);
  int expected = 63245986;

  assertEquals(expected, actual);
 }
}


Categories are defined like below.

ArithmeticCalculationsTest.java

package com.sample.categories;

public interface ArithmeticCalculationsTest {

}

FastTest.java

package com.sample.categories;

public interface FastTest {

}

SlowTest.java

package com.sample.categories;

public interface SlowTest {

}


Test suites are defined like below.

ArithmeticTestSuite.java

package com.sample.testsuites;

import org.junit.experimental.categories.Categories;
import org.junit.experimental.categories.Categories.ExcludeCategory;
import org.junit.experimental.categories.Categories.IncludeCategory;
import org.junit.runner.RunWith;
import org.junit.runners.Suite.SuiteClasses;

import com.sample.arithmetic.ArithmeticTest;
import com.sample.arithmetic.FactorialTest;
import com.sample.arithmetic.FibonacciTest;
import com.sample.categories.ArithmeticCalculationsTest;
import com.sample.categories.FastTest;

@RunWith(Categories.class)
@IncludeCategory({ ArithmeticCalculationsTest.class })
@ExcludeCategory(FastTest.class)
@SuiteClasses({ ArithmeticTest.class, FactorialTest.class, FibonacciTest.class })
public class ArithmeticTestSuite {

}

FastTestSuite.java

package com.sample.testsuites;

import org.junit.experimental.categories.Categories;
import org.junit.experimental.categories.Categories.IncludeCategory;
import org.junit.runner.RunWith;
import org.junit.runners.Suite.SuiteClasses;

import com.sample.arithmetic.ArithmeticTest;
import com.sample.arithmetic.FactorialTest;
import com.sample.arithmetic.FibonacciTest;
import com.sample.categories.FastTest;

@RunWith(Categories.class)
@IncludeCategory({ FastTest.class })
@SuiteClasses({ ArithmeticTest.class, FactorialTest.class, FibonacciTest.class })
public class FastTestSuite {

}


Project structure looks like below.


When you ran ArithmeticTestSuite, below methods will get executed.


When you ran 'FastTestSuite', below methods will get executed.




Previous                                                 Next                                                 Home

No comments:

Post a Comment