Parameterization in TestNG - Working with the testng.xml file

Parameterization in TestNG – Working with the testng.xml file

Let’s start this post with the introduction of a hypothetical website that we are trying to build. This website is for those shortlisted in the Testsigma contest for their excellent test automation skills. Testsigma wishes to give them goodies as part of their goodwill gesture.

We start this website by designing the landing page, information page, and the “forms.html” up page. This page is essential because it will gather information to send the goodies to all the winners. Testsigma wants it to be perfect to avoid future delays, so they decide to make it as easy for the users as possible.

In the same line of thought, the company decides that the information related to the city, state, etc., should be filled automatically based on the pin code. Considering this scenario, as a tester, what do you think could be the best way to test this field, and what other areas would require such testing?

While you ponder this question, let me introduce you to TestNG – a test automation framework and the concept of parameterization in it. Once we understand them and the reasons for their existence, we can gradually move ahead and answer the above question along with a few lines of code.

Parameterization in TestNG

Before coming directly to parameterization, I would like to introduce you in brief about TestNG. You can skip this paragraph if you are already aware of this framework.

TestNG is a test automation framework that uses Java programming language to create tests. TestNG’s word “NG” is attributed to “Next Generation.” It was designed to overcome the anomalies possessed by the JUnit framework and support many more testing techniques than those supported by JUnit and NUnit.

Therefore, if you have worked on JUnit, you will feel closely resemble the two, such as in annotations. While the framework is extensive and profound in its work, it is impossible to showcase its power at this point. In this post, we will stick to parameterization in TestNG and its implementation. You can refer to this guide on annotations in TestNG for better understanding.

Parameterization is attributed as one of the great powers of TestNG. Parameterization in TestNG means we want to pass a parameter into the test with multiple values. Each value will run on the same test, and the output will be generated for the final analysis. For example, we encountered a pin code issue on our hypothetical website. This can be resolved by passing a parameter with pin codes. So the step-wise process would look as follows:

  • Putting the pin code list into the parameters.
  • Passing the parameter to the tests.
  • Check whether we get the correct city name by the pin code or not.
  • Generating results.

The code walkthrough with an example snippet will be shown later in the post.

Why do we need to parameterize tests in TestNG?

Parameterization allows us to pass several values to the same tests. This feature’s most significant advantage is avoiding repetitiveness in our test case construction. This is the ultimate goal of “automation” in general, whether in testing or development. The more generic environment we create, the better it is for debugging and future construction and maintenance.

When we parameterize tests in TestNG, we create a pipeline of automation testing. In this pipeline, we feed values from one end while generating results from another. However, we create this pipeline only once. For example, if I want to pass many pin codes for my tests, I can skip the efforts such as:

if (pin_code == 249403)

  {

      Do something

}

else if (pin_code == 110016)

{

Do something

}

else if (pin_code == 500012)

{

Do something

}

…….and so on.

Instead, I can reconstruct this as follows:

@parameter_value

Hit API to test pin_code

Generate result

Later, when we add or delete the pin code values, we just need to delete them from the list we were feeding into the pipeline. This process saves a lot of time, effort, and work.

How to perform parameterization in TestNG?

The final question to address here is the process of applying parameterization in TestNG. The annotation “Parameters achieve this” is a part of the TestNG library. By declaring the annotation, we pass the parameters (similar to variables in programming) along with the annotation as follows:

@Parameters ({“first_param”, “second_param”, “third param”…..})

The parameters passed work as a reference when we need to feed values to them. The “Parameters” annotation is placed after the @Test annotation. So, on our website, if we want to check if our logic of shortlisting the candidates is working correctly or not, we can do that through parameterization in TestNG.

Suppose there are two reviewers, both of whom award marks to an article out of 10. If the writer achieves an average of 4 or above, he gets shortlisted. This can be written as follows:

public class Parameterization{

 @Test

@Parameters({“Reviewer_1”, “Reviewer_2”})

    public void check_if_shortlisted(int marks_1, int marks_2)

    {

       float average = (marks_1 + marks_2)/2;

       System.out.println(“The average achieved by the writer is ” + average);

       if(average >= 4){

           /* put this writer in the shortlisted category” */

       } else {

           /* put this writer in the “not shortlisted category” */

       }

    }

}

Currently, this file won’t work as the file still does not know what to do with the line:

@Parameters({“Reviewer_1”, “Reviewer_2”})

To make it understand this line and run the TestNG test case using parameterization, we need to take help from the testng.xml file.

In the testng.xml file, we put the parameter values as they will be passed over to the tests we created above. One test parameter description looks as follows:

<suite name = “TestSigma TestNG suite”>

 <test name=”ExplicitWait”>

    <parameter name=”Reviewer_1″ value=”2″ />

    <parameter name=”Reviewer_2″ value=”3″ />

    <classes>

      <class name=”org.example.ExplicitWait” />

    </classes>

  </test>

</suite>

In this snippet, we declare a name attribute that should match the name we put in the test file. This helps in conflicts when there are multiple parameters. The value attribute defines the value to be assigned to this variable.

Run the TestNG suite, and the values will automatically be inserted at runtime.

You can repeat the above-written block for multiple values with different test names and parameter values (but the name attribute holds the same value as shown above). Just remember to keep it under the same suite.

Parameterization at the suite level

The tester can also directly define parameters at the suite level (i.e., one step above the test block). However, the parameters defined at the suite level have lower priority than those defined at the test level. Please refer to the below snippet for the same:

<suite name = “TestSigma TestNG suite”>

<parameter name=”Reviewer_1” value=”4”/>

<parameter name=”Reviewer_2” value=”2”/>

 <test name=”ExplicitWait”>

    <parameter name=”Reviewer_1″ value=”2″ />

    <parameter name=”Reviewer_2″ value=”3″ />

    <classes>

      <class name=”org.example.ExplicitWait” />

    </classes>

  </test>

</suite>

The output for the above testng.xml file would be:

The average achieved by the writer is 2.5

The average achieved by the writer is 3.0

The parameters defined above the <test> block are considered suite-level parameters.

Data-Driven Testing vs Parameterization in TestNG

One question might arise naturally with our learnings related to parameterization in TestNG. If parameterization is feeding different values to a test, aren’t we doing a similar thing with data-driven testing? After all, in DDT, we run different values on a single field and generate a summarised result. Just like we did above.

This is logical, and when looked at theoretically, parameterization and data-driven testing do look similar in their work. But subtle differences make them used at different points by the tester.

Input mechanism

The first difference is the feeding mechanism of both methods. In parallelization, we feed the input through the testng.xml file and sometimes through the data provider methods. This is more technical than data-driven testing, requiring writing and compiling code in Java programming language (referring to TestNG). In DDT, however, we feed the input through a pre-written file such as excel and CSV. 

However, this is not a matter of concern as it is just the input method. The main difference that matters in their usage is the target element on which both of them work.

Working method

The DDT method and the parameterization method work differently at the core. For example, coming back to our hypothetical website, let’s say we have an input field called name that takes the candidate’s name.

Considering a scenario where a user enters a numerical number as follows:

Name – 3420192

Address – XYZ, ABC

Pin Code – 249403

Contact Number – 8729290478

DDT and parameterization can mimic it in two different ways.

We replace the value in the input field in DDT and press submit. If validations are put correctly, this test should fail, and the first response is that numeric characters are not allowed in this field. This is plain and simple.

However, when we feed the following value (which is valid), we get an unusual error – the candidate has already entered the address, and no duplicate entries are allowed. Since the first entry was rejected due to “name” being entered as numerical values, it is complicated to diagnose this issue.

In parameterization, however, things work differently. When we test through parameterization, we are not replacing the value like DDT, but we replace the values of the variables behind it. Going through the same steps again, but now in parameterization, we pass the “name” variable with values as numerical.

But this time, since we are testing through code, we also put another check to see verify the values of other variables such as address. Since the “name” field is returning an error, we expect these fields to return a default value which could be either “or “None” or “Nil.”

Verifying these fields, we find that address is not holding the default value but the value entered in the first iteration run, i.e., XYZ, ABC. This helps us define the real cause of the problem related to database entries, which was impossible through data-driven testing.

Leveraging framework and programming capabilities

Another essential difference between data-driven testing and parameterization is that since parameterization is based on code in the IDE, it can access IDE and framework features. For example, if you wish to use parallelization, you can use that along with parameterization. You can also use IDE-specific features to increase efficiency. DDT does not offer such lucrative deals.

However, these are just the difference between DDT and parameterization. In no way do they justify the importance or preference of one over another. DDT and parameterization hold specific use cases and implementation points used to complete the application testing.

Conclusion

TestNG is a hugely popular framework in the field of test automation. Its capabilities surpass what NUnit and JUnit used to provide us. Powering itself with added annotations makes it stand apart from its peers in the competitive market we work in today.

One such annotation in TestNG is parameters which help us place different values in the same variable, avoiding repetitions and unnecessary lines of code. It is an essential feature that allows for facilitating the testing phase.

In this post, we discussed TestNG parameterization, its importance, and the process that helps us achieve it. With this, we would love to hear your experience with parameterization in TestNG and what type of additions you make to your code to make it even better. I hope this post helps you in your TestNG journey. Thank you for giving your valuable time. 


Test automation made easy

Start your smart continuous testing journey today with Testsigma.

SHARE THIS BLOG

RELATED POSTS