Thursday, December 11, 2014

TestNg @Factory class Example



TestNG factory class 
TestNG factory is used to create instances of test classes dynamically. This is useful if you want to run the test class any number of times. For example, if you have a test to login into a site and you want to run this test multiple times, then it’s easy to use TestNG factory where you create multiple instances of test class and run the tests. Whereas, dataprovider is used to provide parameters to a test. If you provide dataprovider to a test, the test will be run taking different sets of value each time. This is useful for a scenario like where you want to login into a site with different sets of username and password each time.

@Factory  Marks a method as a factory that returns objects that will be used by TestNG as Test classes. The method must return Object[].This is useful if you want to run the test class any number of time.


public class FactoryTest {
      @Factory
      public Object[] createTest() {
            Object[] res = new Object[5];
            res[0] = new FactoryImplTestAdd(2,3,5);
            res[1] = new FactoryImplTestAdd(2,3,5);
            res[2] = new FactoryImplTestAdd(2,3,5);
            res[3] = new FactoryImplTestSubtract(4,2,2);
            res[4] = new FactoryImplTestSubtract(4,2,2);
            return res;
      }
}


TestNG will pick you your @Factory method, invoke it, retrieve all the objects you returned and consider each of them as a separate TestNG test class.


public class FactoryImplTestAdd{
      int op1;
      int op2;
      int expResult;

      public FactoryImplTestAdd(int op1, int op2, int expResult) {
            this.op1=op1;
            this.op2=op2;
            this.expResult=expResult;
      }

      @Test
      public final void testAdd() {
            Calculator cal = new Calculator();
            Assert.assertEquals(cal.add(op1,op2),expResult);
      }
}


public class FactoryImplTestSubtract{
      int op1;
      int op2;
      int expResult;

      public FactoryImplTestSubtract(int op1, int op2, int expResult) {
            this.op1=op1;
            this.op2=op2;
            this.expResult=expResult;
      }

      @Test
      public final void testAdd() {
            Calculator cal = new Calculator();
            Assert.assertEquals(cal.subtract(op1,op2),expResult);
      }
}


You only have to execute the Class named “FactoryTest”. TestNG will find the Factory method inside it and will execute it. To do that your testng.xml only needs to reference the “FactoryTest” class that contains factory methods.
<class name="FactoryTest" />


If testing.xml created dynamically
classes.add(new XmlClass("FactoryTest"));

public class WebTestFactory {     
  //createInstances method will create 10 objects of WebTest class
  @Factory    
  public Object[] createInstances() {     
   Object[] result = new Object[10];      
   for (int i = 0; i < 10; i++) {     
      result[i] = new WebTest(i);     
    }     
    return result;    
  } 
and the test class is now:
public class WebTest {    
  private int m_numberOfTimes;    
  public WebTest(int numberOfTimes) {     
    m_numberOfTimes = numberOfTimes;      
  }   

  @Test   
  public void testServer() {      
   //Code to test the application  
  }   
}   
Your testng.xml only needs to reference the class that contains the factory method, since the test instances themselves will be created at runtime:
<class name="WebTestFactory" /> 
The factory method can receive parameters just like @Test and @Before/After and it must return Object[]. The objects returned can be of any class (not necessarily the same class as the factory class).
Whereas, dataprovider is used to provide parameters to a test. If you provide dataprovider to a test, the test will be run taking different sets of value each time. This is useful for a scenario like where you want to login into a site with different sets of username and password each time.
public class DataProviderTest {

    @Test(dataProvider= "data")
    public void TestUltimatixFromExcelData(String userName,String password) {
        WebDriver driver;
        driver=new FirefoxDriver();
        //Test to login into a site
    }

    @DataProvider(name="data")
    public static Object[][] dataProviderTest() throws Exception{

        Object[][] returnArray={new Object[]{"username1","password1"},new Object[]{"username2","password2"},new Object[]{"username3","password3"}
        };
        return returnArray;
    }

}

No comments:

Post a Comment

TestNG - Can i use the 2 different data providers to same @test methods in TestNG?

public Object [][] dp1 () { return new Object [][] { new Object [] { "a" , "b" }, new Obje...