TestNG | Manage execution and data

After adding the TestNG framework to your Selenium Mobile project, let's look at how you can best manage your tests by using the testng.xml file. If you followed the instructions in TestNG | Add a TestNG framework to a Selenium Mobile project, you should now have a file called testng.xml inside your project. If you do not have it, create the file now with the following content:

Copy
<?xml version="1.0" encoding="UTF-8"?>
<suite name="Suite" parallel="false">
    <test name="Test">
        <classes>
            <class name="TestNG.PerfectoAppTest"/>
        </classes>
    </test> <!-- Test -->
</suite> <!-- Suite --> 

Let's look at the hierarchy of the xml file (after the xml header):

  • Suite: the highest level in the hierarchy, everything that happens is part of the suite.
  • Test: a test can be a logical set of flows with relations between them.
  • Class: the actual class where our methods are stored in.
  • Method (not in this xml): the methods inside the class we are calling.

While suite and test are logical entities, the class and method specified in the testng.xml file, are the ones we actually call when we run the test. If we put a class name in our xml file, then all the method inside this class will run.

Important: This document includes references to a third-party product, TestNG. The user interface and usage of third-party products are subject to change without notice. For the latest published information about TestNG, see https://testng.org/doc/documentation-main.html.

Adding parameters to the test

Saving data embedded in the code is not a good practice, is it's harder to track it and make necessary changes. Instead, we want to keep all our data in an external file (in the example it will be the xml file), then we can send our this data as parameters to the test from the testng.xml file, this way we would not have to store test data inside our test code.

In our code, we used the following data:

  1. MCM URL ("demo.perfectomobile.com").
  2. MCM username ("myPerfectoUsername").
  3. MCM password ("myPerfectoPassword").
  4. Device model ("iPhone-6").
  5. Test username ("John").
  6. Test password ("Perfecto1").
  7. Checkpoint string ("Welcome back").

We will add those parameters to our testng.xml file. Then, we will set our methods in the PerfectoAppTest.java file to use them.

To add a parameter to the test, we use:

Copy
<parameter name="parameterName value="parameterValue" /> 

After adding the parameters from the list above, our testng.xml file would look like the following:

Copy
<?xml version="1.0" encoding="UTF-8"?>
<suite name="Suite" parallel="false">
    <test name="Test">
        <parameter name="mcm"             value="demo.perfectomobile.com" />
        <parameter name="mcmUser"         value="johndoe@test.com" />
        <parameter name="mcmPassword"     value="xxxxxx" />
        <parameter name="deviceModel"     value="iPhone-6" />
        <classes>
            <parameter name="testUsername" value="John" />
            <parameter name="testPassword" value="Perfecto1" />
            <class name="TestNG.PerfectoAppTest"/>
        </classes>
    </test> <!-- Test -->
</suite> <!-- Suite -->
Tip: We use two levels of hierarchy for our parameters: We put the MCM parameters in the test level and the test parameters in the classes level. This is not mandatory, but it makes more sense to put the parameters only in their relevant scope.

Now we're going to add the parameters to the java file.

We are going to send the MCM parameters to the @BeforeMethod because that is where we need all the data to create our driver. Then we're going to pass the test data to the @Test method. We use the @Parameters notation before the method notation and then add the relevant parameters parenthesis and curly brackets. Each param is inside double quotes, and we separate them with commas, as shown in the following example:

@Parameters({"param1", "param2", "param3"...})
Copy
@Parameters({"mcm", "mcmUser", "mcmPassword", "deviceModel"})
@BeforeClass 
  public void beforeClass(String mcm, String mcmUser, String mcmPassword,
                          String deviceModel) throws UnsupportedEncodingException,                                                      MalformedURLException {
        System.out.println("Run started");
        String browserName = "mobileOS";
        DesiredCapabilities capabilities = new DesiredCapabilities(browserName, "",                                                Platform.ANY);
      String host = mcm;
      String user = URLEncoder.encode(mcmUser, "UTF-8");
      String password = URLEncoder.encode(mcmPassword, "UTF-8");
      capabilities.setCapability("model", deviceModel);

      this.driver = new RemoteWebDriver(new URL("https://" + user + ':' + password                         + '@' + host + "/nexperience/wd/hub"), capabilities);
    }

Then add the test parameters:

Copy
@Parameters({"testUseranem", "testPassword", "expectedText"})
@Test
public void f(String username, String password, String expectedText) { 
    boolean res = false; NXCBaseView view = new NXCBaseView(this.driver);
    try{
        view.init().login(username, password);
        String exp = "//*[contains(text(),'" + expectedText + "')]"        res = driver.findElement(By.xpath(exp).isDisplayed();
    }
    catch(Exception e){} 
    Assert.assertTrue(res); }

The @AfterClass method will remain the same because we do not need to send any parameters to it.

Last, we run our test by right-clicking the testng.xml file and selecting Run As > TestNG Suite.

Next, run the same test on multiple devices in parallel: TestNG | Parallel execution