简体   繁体   中英

Is it possible to pass parameter value as a function name in testNG

I have an "clientId" stored in my s3bucket. This value keeps updating everyday from an external device farm run. I Want to pass this ClientID as a parameter in my testsuite. Because, the s3 content keeps updating everyday, I've written a function ReadFromS3() in my code. I want to give this function as value to the testNG parameter.

Instead of calling,

 <sysproperty key="clientId" value="abc"/>

I want to call something like below

<sysproperty key="clientId" value=ReadFromS3()/>

Is this achievable with testNG? If so, kindly provide pointers.

Yes you can do it, but it is going to be a bit of convoluted approach.

Here's how you do it.

  • In your suite xml file, you would need to pass in the fully qualified method name of the method which can be invoked to get the actual value.
  • Once you have the method name in your @Test method via the parameters, you use reflection to load the class, find the method and invoke it.

Here's a sample

import java.lang.reflect.Method;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;

public class SampleTestClass {

  @Parameters({"clientId"})
  @Test
  public void testMethod(String methodName) throws Exception {
    System.err.println("Value for clientId :" + invokeMethod(methodName));
  }

  private String invokeMethod(String methodName) throws Exception {
    String[] parts = methodName.split("#");
    String className = this.getClass().getName();
    String method = parts[0];
    if (parts.length == 2) {
      className = parts[0];
      method = parts[1];
    }
    Class<?> clazz = Class.forName(className);
    Object object = clazz.newInstance();
    Method m = clazz.getDeclaredMethod(method);
    m.setAccessible(true);
    return m.invoke(object).toString();
  }

  private String readFromS3() {
    return "s3Bucket";
  }
}

Suite file

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="57006917_Suite" verbose="2">
  <test name="57006917_Test">
    <parameter name="clientId"
      value="com.rationaleemotions.stackoverflow.qn57006917.SampleTestClass#readFromS3"/>
    <classes>
      <class name="com.rationaleemotions.stackoverflow.qn57006917.SampleTestClass"/>
    </classes>
  </test>
</suite>

Output:

...
... TestNG 7.0.0-beta7 by Cédric Beust (cedric@beust.com)
...
Value for clientId :s3Bucket
PASSED: testMethod("com.rationaleemotions.stackoverflow.qn57006917.SampleTestClass#readFromS3")

===============================================
    57006917_Test
    Tests run: 1, Failures: 0, Skips: 0
===============================================

===============================================
57006917_Suite
Total tests run: 1, Passes: 1, Failures: 0, Skips: 0
===============================================

If the "clientId" stored in my s3bucket keeps updating everyday, better to read client id once in before suite and store it into context or system property. You can implement suite listener or create method with BeforeSuite for that.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM