Skip to main content

TestNG DataProvider–Phew!!!

It took me some time to get a hang of what the TestNG DataProvider could do…Once I got to know about how it functions believe me I created wonders with it Smile

 

What is a TestNG DataProvider?

There are loads of definitions on the web for it but if you are an average-but-wanting-to-learn software engineer then in simple words, a TestNG DataProvider is a Test Data Provider class…Simple! It is powerful enough to provide data according to the method which is initiating or rather calling it…

 

When/Why do I need a TestNG DataProvider?

Of course, most of us would agree that we provide the test data through various forms like an xml, excel, csv etc…The reason I found this feature useful when I knew the input before hand and it varied based on the test case…For example, if I am testing buying of a product on a retail website…I want to test buying of a new product, buying of a used product, buying of multiple products…I have the test data in all the three cases but then the test data differs with each test case…In this case, I can use a DataProvider…This is just one case, we can use it extensively to provide various test data…but then what I see is that we will have to hard code or give fixed input to the test each time…if we wanted to change the test data we would have to change our code…So use it as your discretion…

 

How to use a TestNG DataProvider?

Use a data provider Method in the same test class

Defining the Method

// This is how I would define a DataProvider in TestNG – With a name – Please note that this method exists in the Test Class itself!

@DataProvider(name = "getProductTestData")

// Create the method which generates the test data based on a criteria – Here the criteria is by the calling method name…which means based on the method calling the dataprovider, the test data is generated

public static Object[][] createProductTestData(Method m) {

               // Return this Product ID if the test is for a new product

                if (m.getName().equalsIgnoreCase("testNewProductBuy")) {

                        return new Object[][] { new Object[] { strNewProdID } };

                }

               // Return this Product ID if the test is for a used product

              else if (m.getName().equalsIgnoreCase("testUsedProductBuy")) {

                        return new Object[][] { new Object[] { strUsedProdID} };

                }

               // Return this Product ID if the test is for multiple products

              else if (m.getName().equalsIgnoreCase("testMultipleProductBuy")) {

                        return new Object[][] { new Object[] { listOfProductIDs} };

                } else

                        // By Default the function would return an ID which is a new Product

                        return new Object[][] { new Object[] {strNewProdID } };

        }

Calling the DataProvider

@Test(groups = { "someGroup" }, enabled = true, dataProvider = "getProductTestData")

      public void testNewProductBuy (String strAsin) throws Exception {

                   // Perform some actions

      }

To explain the @Test Annotation given here, the method “testNewProductBuy” is identified as a TestNG test method which belongs to the testng group “someGroup”. As it has its “enabled” property set to “true” it would run when we run the suite. The method is also using a dataprovider “getProductTestData”. So when we run the test it would run against the product id strNewProdID which we get from the data provider…

 

  • Use a data provider method in a separate data provider class

Defining the Class & the Method

 

public class DataProviderUtlity {

// This is how I would define a DataProvider in TestNG – With a name!

@DataProvider(name = "getProductTestData")

// Create the method which generates the test data based on a criteria – Here the criteria is by the calling method name…which means based on the method calling the dataprovider, the test data is generated

public static Object[][] createProductTestData(Method m) {

               // Return this Product ID if the test is for a new product

                if (m.getName().equalsIgnoreCase("testNewProductBuy")) {

                        return new Object[][] { new Object[] { strNewProdID } };

                }

               // Return this Product ID if the test is for a used product

              else if (m.getName().equalsIgnoreCase("testUsedProductBuy")) {

                        return new Object[][] { new Object[] { strUsedProdID} };

                }

               // Return this Product ID if the test is for multiple products

              else if (m.getName().equalsIgnoreCase("testMultipleProductBuy")) {

                        return new Object[][] { new Object[] { listOfProductIDs} };

                } else

                        // By Default the function would return an ID which is a new Product

                        return new Object[][] { new Object[] {strNewProdID } };

        }

}

Calling the DataProvider

@Test(groups = { "someGroup" }, enabled = true, dataProvider = "getProductTestData",dataProviderClass = DataProviderUtlity.class)

      public void testNewProductBuy (String strAsin) throws Exception {

                   // Perform some actions

      }

To explain the @Test Annotation given here, the method “testNewProductBuy” is identified as a TestNG test method which belongs to the testng group “someGroup”. As it has its “enabled” property set to “true” it would run when we run the suite. The method is also using a dataprovider “getProductTestData” which exists in the DataProviderUtility.java class. So when we run the test it would run against the product id strNewProdID which we get from the data provider…

 

Useful Links I followed to learn about this were:

  1. http://testng.org/doc/documentation-main.html#parameters
  2. http://stackoverflow.com/questions/666477/possible-to-pass-parameters-to-testng-dataprovider
  3. http://www.lysergicjava.com/?p=165
  4. http://www.mkyong.com/unittest/testng-tutorial-6-parameterized-test/

 

Hope this helps!!!

Comments

Popular posts from this blog

wget error–“zsh: parse error near &”

There is no doubt that I prefer wget way over any other type of downloads… Syntax: wget <DOWNLOAD_URL>   If you get this error “ zsh: parse error near & ” then its probably because your download URL has a “&” so you should try giving your DOWNLOAD_URL in double quotes wget “<DOWNLOAD_URL>”   If you are trying to download from a site which needs you to give your credentials then you can try giving it this way wget --http-user=<UserName> --http-password=<Password> “<DOWNLOAD_URL>”   Hope this helps

How to Unpack a tar file on Windows?

On Windows: You can download a simple command line tool to do this. You can download the tool from here Usage can be found on the website but pasting it here too for convenience: C:\>TarTool.exe Usage : C:\>TarTool.exe sourceFile destinationDirectory C:\>TarTool.exe D:\sample.tar.gz ./ C:\>TarTool.exe sample.tgz temp C:\>TarTool.exe -x sample.tar temp TarTool 2.0 Beta supports bzip2 decompression for files with extensions like tar.bz2 and .bz2 . TarTool -xj sample.tar.bz2 temp or TarTool -j sample.bz2 Download TarTool 2.0 Beta from here Unpack a .txz file on Windows Use the 7zip tool  to unpack a .txz file on windows On Linux: You can use the bzip2 and tar combined to do this… for ex: bzip2 –cd <tar.bz_fileName> | tar –xvf - This will unpack the contents of the tar.bz file Happy Un-Tar-ing

Apache Commons StringUtils.isEmpty() vs Java String.isEmpty()

You might want to test for if a String is empty many a times. Before we jump onto the numerous solutions available let us take a look at how we define “Empty String”   The difference in the two methods given by Apache and Java are dependent on how we define an empty string. Java String.isEmpty returns a boolean true if the string’s length is zero. If the string has null it throws NullPointerException Apache StringUtils.isEmpty returns a boolean true if the string is either null or has length is zero   Thus its purely dependent on how you are defining “empty string” in your program which will decide which function to use…BTW if you want to skip using Apache Commons funciton and would want to stick to java then you can have your own function like this:   public static boolean isEmptyOrNull(String strStringToTest) {                  return strStringToTest == null || strStringToTest.trim().isEmpty(); }