Saturday, October 24, 2015

JUnit and Test NG for software testing

  

How To Use.


JUnit is a unit testing framework which is very handy and useful to perform unit testing of java codes.

To setup Junit on a maven project include this dependency on pom.xml
<dependency>
  <groupId>junit</groupId>
  <artifactId>junit-dep</artifactId>
  <version>4.10</version>
  <scope>test</scope>
</dependency>         
<dependency>
  <groupId>org.hamcrest</groupId>
  <artifactId>hamcrest-library</artifactId>
  <version>1.3</version>
  <scope>test</scope>
</dependency>

Annotations used in Junit test
@BeforeClass -- This runs only once before all @Test
@AfterClass  -- This runs only once after all @Test
@Before -- This runs before every @Test
@After-- This runs after every @Test
@Test  -- This is the actual test
@Rule  -- To introduce a Rule like ErrorCollector rule
@Test( expected = IllegalStateException.class )
@RunWith -- for any other test runner class except the default Junit runner
@SuiteClasses -- for running all tests in suite



 package com.sudas.newJunit;  
 import static org.junit.Assert.*;  
 import java.io.PrintWriter;  
 import org.hamcrest.Matchers;  
 import org.junit.After;  
 import org.junit.AfterClass;  
 import org.junit.Before;  
 import org.junit.BeforeClass;  
 import org.junit.Test;  
 public class JunitAnnotations {  
      Calculators calc1;  
      Calculators calc2;  
      Calculators calc3;  
      @BeforeClass  
      public static void setUpBeforeClass() throws Exception {  
      }  
      @AfterClass  
      public static void tearDownAfterClass() throws Exception {  
      }  
      @Before  
      public void setUp() throws Exception {  
           calc1 = new Calculators("10", "10");  
           calc2 = new Calculators("10.1", "10.1", "10.1");  
           calc3 = new Calculators("10.1", "10.1", "10.1", "10.1");  
      }  
      @After  
      public void tearDown() throws Exception {  
      }  
      @Test  
      public void AdditionTwoNumbers() {  
 //          assertEquals(20.21, calc1.twoDigitAddition(), 0);  
           assertThat(calc1.twoDigitAddition(), new Matchers().equalTo(20.21));  
      }  
      @Test  
      public void AdditionThreeNumbers() {  
           assertEquals(60.3, calc2.threeDigitAddition(), 0);  
      }  
      @Test  
      public void AdditionFourNumbers() {  
           assertEquals(80.4, calc3.FourDigitAddition(), 0);  
      }  
 }  


@After annotation is used where we need to close db connection. close buffer stream etc.

@BeforeClass - Unlike @Before which runs before every test, @BeforeClass run only once in the test class. @BeforeClass is use to create database connection object webdriver object etc.


@Rule
 @Rule  
      public ErrorCollector collector = new ErrorCollector();  
      @Test  
      public void testSeven() {  
           int num1[] = { 10, 20, 30, 40, 50 };  
           int num2[] = { 10, 20, 0, 40, 50 };  
           // Assert.assertArrayEquals("All elements in array are equal", num1,  
           // num2);  
           // Assert.assertThat(num1, Matchers.equalTo(num2));  
           collector.checkThat("Element mismatch", num2, Matchers.equalTo(num1));  
      }  


JUnit Test Runner
      @RunWith(Suite.class)  
 //     @Suite.SuiteClasses({   
 //       calc.class,ArrayTest.class  
 //     })  
      @SuiteClasses  
      ({ArrayTest01.class,ArrayTest02.class})  
      public class JunitTestSuite {  
      }  


A broader JUnit example

 package com.sudas.junit;  
 import org.hamcrest.Matchers;  
 import org.hamcrest.*;  
 import org.junit.Assert;  
 import org.junit.Ignore;  
 import org.junit.Rule;  
 import org.junit.Test;  
 import org.junit.rules.ErrorCollector;  
 public class JunitExample {  
      public static void main(String[] args) {  
      }  
      @Test  
      public void testOne() {  
           // Test for actual and expected result  
           String actual = "Apple";  
           String expected = "apple";  
           // use of assert  
           Assert.assertEquals(expected.toLowerCase(), actual.toLowerCase());  
      }  
      // if condition is true test case fail  
      @Test  
      public void tesTwo() {  
           String actual = "Apple";  
           String expected = "apple";  
           Assert.assertFalse("This condition is Flase", actual.length() == expected.length());  
      }  
      @Test  
   // if condition is true test case pass
public void testThree() { String actual = "Apple"; String expected = "apple"; Assert.assertTrue("This condition is True", actual.length() == expected.length()); } @Test  
// Hamcrest matcher example
      public void testFour() {  
           String actual = "Apple";  
           String expected = "apple";  
           Assert.assertThat(actual, Matchers.equalToIgnoringCase(expected));  
      }  
      @Test  
      public void testFive() {  
// Hamcrest matcher ignore case example
String actual = "Apple"; String expected = "apple"; Assert.assertThat(actual, Matchers.equalToIgnoringCase(expected)); } @Test  
// Array Test
      public void testSix() {  
           int num1[] = { 10, 20, 30, 40, 50 };  
           int num2[] = { 10, 20, 0, 40, 50 };  
           Assert.assertArrayEquals("All elements in array are equal", num1, num2);  
      }  
      @Rule  
      public ErrorCollector collector = new ErrorCollector();  
      @Test  
// Use of Error collector rule
      public void testSeven() {  
           int num1[] = { 10, 20, 30, 40, 50 };  
           int num2[] = { 10, 20, 0, 40, 50 };  
           // Assert.assertArrayEquals("All elements in array are equal", num1,  
           // num2);  
           // Assert.assertThat(num1, Matchers.equalTo(num2));  
           collector.checkThat("Element mismatch", num2, Matchers.equalTo(num1));  
      }  
      @Test  
      public void testEight() {  
           String num1 = "10.1";  
           String num2 = "10.1";  
           double number1 = Double.parseDouble(num1);  
           double number2 = Double.parseDouble(num2);  
           double total = number1 + number2;  
           Assert.assertTrue(total == 20.2);  
      }  
      @Ignore("do not test")  
      @Test  
      public void testNine() {  
      }  
 }  
Test Results For Failed Tests

JunitExample
com.sudas.junit.JunitExample
tesTwo(com.sudas.junit.JunitExample)

java.lang.AssertionError: This condition is Flase
eTestRunner.main(RemoteTestRunner.java:192)

testSix(com.sudas.junit.JunitExample)
All elements in array are equal: arrays first differed at element [2]; expected:<30> but was:<0>

testSeven(com.sudas.junit.JunitExample)
java.lang.AssertionError: Element mismatch
Expected: [<10>, <20>, <30>, <40>, <50>]
     got: [<10>, <20>, <0>, <40>, <50>]



@Parameterized test using JUnit



CLASS UNDER TEST

 package sudas.junit;  
 public class Addition {  
      public int addition(int num1, int num2) {  
           int total = num1 + num2;  
           return total;  
      }  
 }  

 package sudas.junit;  
 import static org.junit.Assert.*;  
 import java.util.Arrays;  
 import java.util.Collection;  
 import java.util.Collections;  
 import java.util.List;  
 import org.junit.After;  
 import org.junit.AfterClass;  
 import org.junit.Before;  
 import org.junit.BeforeClass;  
 import org.junit.Test;  
 import org.junit.runner.RunWith;  
 import org.junit.runners.Parameterized;  
 import org.junit.runners.Parameterized.Parameters;  
 @RunWith(Parameterized.class)  
 public class JunitParameterTest {  
      static Addition addition;  
      int expected;  
      int number1;  
      int number2;  
      public JunitParameterTest(int expected, int number1, int number2) {  
           // TODO Auto-generated constructor stub  
           this.expected = expected;  
           this.number1 = number1;  
           this.number2 = number2;  
      }  
      @BeforeClass  
      public static void setUpBeforeClass() throws Exception {  
           addition = new Addition();  
      }  
      @AfterClass  
      public static void tearDownAfterClass() throws Exception {  
      }  
      @Before  
      public void setUp() throws Exception {  
      }  
      @After  
      public void tearDown() throws Exception {  
      }  
      @Parameterized.Parameters  
      public static Collection<Object[]> addedNumbers() {  
           return Arrays.asList(new Object[][] { { 3, 1, 2 }, { 5, 2, 3 }, { 7, 3, 4 }, { 9, 4, 5 }, });  
      }  
      @Test  
      public void test() {  
           int t = addition.addition(number1, number2);  
           System.out.println(number1);  
           assertEquals(expected, t);  
      }  
 }  

OUTPUT





 import static org.junit.Assert.*;  
 import org.junit.After;  
 import org.junit.AfterClass;  
 import org.junit.Before;  
 import org.junit.BeforeClass;  
 import org.junit.Test;  
 public class ExecutionOrder {  
      @BeforeClass  
      public static void setUpBeforeClass() throws Exception {  
           System.out.println("@BeforeClass");  
      }  
      @AfterClass  
      public static void tearDownAfterClass() throws Exception {  
           System.out.println();  
      }  
      @Before  
      public void setUp() throws Exception {  
           System.out.println("@AfterClass");  
      }  
      @After  
      public void tearDown() throws Exception {  
           System.out.println("@After");  
      }  
      @Test  
      public void test01() {  
           System.out.println("test01");  
      }  
      @Test  
      public void test02() {  
           System.out.println("test02");  
      }  
      @Test  
      public void test03() {  
           System.out.println("test03");  
      }  
 }  
EXECUTION ORDER 
@BeforeClass
@Before
test01
@After
@Before
test02
@After
@Before
test03
@After
@AfterClass
 

Common Test NG Annotations

@BeforeSuite - 

@AfterSuite
@BeforeTest
@AfterTest
@BeforeGroups
@AfterGroups
@BeforeClass
@AfterClass
@BeforeMethod
@AfterMethod


 package TestNG;  
 import org.testng.annotations.Test;  
 import org.testng.annotations.BeforeMethod;  
 import org.testng.annotations.AfterMethod;  
 import org.testng.annotations.BeforeClass;  
 import org.testng.annotations.AfterClass;  
 import org.testng.annotations.BeforeTest;  
 import org.testng.annotations.AfterTest;  
 import org.testng.annotations.BeforeSuite;  
 import org.testng.annotations.AfterSuite;  
 public class AnnotationsOrder {  
      @Test  
      public void Test01() {  
           System.out.println("@Test 01");  
      }  
      @Test  
      public void Test02() {  
           System.out.println("@Test 02");  
      }  
      @Test  
      public void Test03() {  
           System.out.println("@Test 03");  
      }  
      @Test  
      public void Test04() {  
           System.out.println("@Test 04");  
      }  
      @Test  
      public void Test05() {  
           System.out.println("@Test 0");  
      }  
      @BeforeMethod  
      public void beforeMethod() {  
           System.out.println(" @BeforeMethod");  
      }  
      @AfterMethod  
      public void afterMethod() {  
           System.out.println(" @AfterMethod");  
      }  
      @BeforeClass  
      public void beforeClass() {  
           System.out.println("@BeforeClass");  
      }  
      @AfterClass  
      public void afterClass() {  
           System.out.println(" @AfterClass");  
      }  
      @BeforeTest  
      public void beforeTest() {  
           System.out.println(" @BeforeTest");  
      }  
      @AfterTest  
      public void afterTest() {  
           System.out.println(" @AfterTest");  
      }  
      @BeforeSuite  
      public void beforeSuite() {  
           System.out.println(" @BeforeSuite");  
      }  
      @AfterSuite  
      public void afterSuite() {  
           System.out.println("@AfterSuite");  
      }  
 }  
 EXECUTION ORDER
[TestNG] Running:  
  C:\Users\sudas\AppData\Local\Temp\testng-eclipse--451353207\testng-customsuite.xml  
  @BeforeSuite  
  @BeforeTest  
 @BeforeClass  
  @BeforeMethod  
 @Test 01  
  @AfterMethod  
  @BeforeMethod  
 @Test 02  
  @AfterMethod  
  @AfterClass  
  @AfterTest  
 PASSED: Test01  
 PASSED: Test02  
 ===============================================  
   Default test  
   Tests run: 2, Failures: 0, Skips: 0  
 ===============================================  
 @AfterSuite  
 ===============================================  
 Default suite  
 Total tests run: 2, Failures: 0, Skips: 0  
 ===============================================  
 [TestNG] Time taken by org.testng.reporters.JUnitReportReporter@3419866c: 15 ms  
 [TestNG] Time taken by org.testng.reporters.jq.Main@4f47d241: 71 ms  
 [TestNG] Time taken by [FailedReporter passed=0 failed=0 skipped=0]: 1 ms  
 [TestNG] Time taken by org.testng.reporters.EmailableReporter2@198e2867: 6 ms  
 [TestNG] Time taken by org.testng.reporters.XMLReporter@6d1e7682: 16 ms  
 [TestNG] Time taken by org.testng.reporters.SuiteHTMLReporter@2f410acf: 37 ms  


< Implementation of TestNG >

This example will illustrate the use of Listener in TestNG and will illustrate use of overriding methods from TestListenerAdapter  like onTestFailure, onTestSuccess.
onTestFailure - Gets executed on Test Failure 
onTestSuccess - Gets executed on Test Success.

Use of ITestResult Interface on @AfterMethod




package com.TestNG;

import org.testng.annotations.Test;
import org.testng.annotations.Parameters;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeClass;
import org.testng.Assert;
import org.testng.ITestResult;
import org.testng.TestListenerAdapter;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Optional;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeSuite;
import org.testng.annotations.AfterSuite;

public class NewTest extends TestListenerAdapter {
 // This test takes parameter from testNG XML file
 @Parameters({ "parameter_name1", "parameter_name2" })

 // Test Case One
 @Test(testName = "TestOne", groups = { "g1", "g5" }, enabled = true)
 // if no argument are supplied
 public void t1(@Optional("p1") String par1, @Optional("p2") String par2) {
  Assert.assertEquals(par1, par2);
 }

 // Test Case Two
 @Test(testName = "TestTwo", groups = { "g1" }, enabled = true)
 public void t2() {
  Assert.assertTrue(true);

 }

 // Test Case Three
 @Test(testName = "TestThree", groups = { "g1" }, enabled = false)
 public void t3() {
 }

 // Test Case Four
 @Test(testName = "TestFour", groups = { "g1", "g5" }, enabled = false)
 public void t4() {
 }

 // Test Case Five
 @Test(testName = "TestFive", groups = { "g1", "g5" }, enabled = false)
 public void t5() {
 }

 @BeforeMethod
 public void beforeMethod() {
 }

 @AfterMethod
 public void afterMethod(ITestResult result) {
  if (result.getStatus() == ITestResult.SUCCESS) {
   System.out.println("Test method Name " + result.getName());

   System.out.println("do something in after method");
  }
 }

 @BeforeClass
 public void beforeClass() {
 }

 @AfterClass
 public void afterClass() {
 }

 @BeforeTest
 public void beforeTest() {
 }

 @AfterTest
 public void afterTest() {
 }

 @BeforeSuite
 public void beforeSuite() {
 }

 @AfterSuite
 public void afterSuite() {
 }

 @Override
 public void onTestFailure(ITestResult tr) {
  // TODO Auto-generated method stub
  System.out.println("because failed");
  System.out.println(tr.getName());
  super.onTestFailure(tr);
 }

 @Override
 public void onTestSuccess(ITestResult tr) {
  // TODO Auto-generated method stub
  System.out.println("because passed");
  super.onTestSuccess(tr);
 }
}

Test NG XML to run the above tests
<?xml version="1.0" encoding="UTF-8"?>
<suite name="check for failed tests">
 <listeners>
  <listener class-name="com.TestNG.NewTest" />
 </listeners>
 <test name="TestOne">
 <classes>
  <class name="com.TestNG.NewTest" />
 </classes>
</test>
</suite>

No comments:

Post a Comment