0
votes

I am using TestNG and annotations- "dependsonMethods"

Code sample:

@Test(dependsOnMethods = { "test2" })
public void Test1() throws IOException { }

Now, programmatically need to get the name of the the Test method (Test1) which has triggered the other Test method (Test2).

******************updated the context & code samples**************************

I am running the TestNg,java, extent reports 4.0.9, selenium tests in Maven project.

CURRENT: Test [addAndPopulateTest] which calls [addTest] using TestNg-"dependsonMethods". After the run, Extent Report shows the results of [addAndPopulateTest] & [addTest] separately as 2 individual tests. This is the link to the current situation : https://imgur.com/ZnBNqzo

EXPECTED: Extent HTML report should show- Single test i.e.[addAndPopulateTest] with 2 child tests i.e. [addTest] & [addAndPopulateTest]. This is the link to the ToBe situation : https://imgur.com/NKMxoIB

*****Code Samples

///TC_addAndPopulateTest

 package com.tra.testCases;  
 import org.testng.annotations.Test;
 import com.tram.pageObjects.BaseClass;

 public class TC_addAndPopulateTest extends TC_addTest {

@Test(dependsOnMethods = { "addTest" })
public void addAndPopulateTest() throws IOException, InterruptedException {
    System.out.println("Currently executing Test-> addAndPopulateTest");
}
}

///TC_addTest

  package com.tram.testCases;

 import java.io.IOException;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 import com.tram.pageObjects.BaseClass;

 public class TC_addTest extends BaseClass {

   @Test()
   public void addTest() throws IOException, InterruptedException {
    System.out.println("Currently executing Test->'addTest'");
}
}

///Reporting Class

  import org.testng.ITestContext;
  import org.testng.ITestListener;
  import org.testng.ITestResult;
  import com.aventstack.extentreports.ExtentReports;
  import com.aventstack.extentreports.ExtentTest;
  import com.tram.pageObjects.BaseClass;

 public class Reporting extends BaseClass implements ITestListener {
 private static ExtentReports extent = 
              ExtentManager.createInstance("Extent-Report.html");
private static ThreadLocal parentTest = new ThreadLocal();
private static ThreadLocal test = new ThreadLocal();

@Override
public synchronized void onStart(ITestContext context) {        

}

@Override
public synchronized void onFinish(ITestContext context) {
    extent.flush();
}

@Override
public synchronized void onTestStart(ITestResult result) {


**//Currently, [addTest] is ready to be executed, So, need to the find 
  that this test method [addTest] has triggered directly by [TC_addTest] 
 class or by other test method. 

 A] If directly by the test class, set 
   PARENT=result.getMethod().getMethodName()
 B] if indirectly by the other test method, set PARENT= Name of the test 
   method [addAndPopulateTest] which has triggered the [addTest] //**

   ExtentTest parent = 
         Extent.createTest(result.getMethod().getMethodName());
          parentTest.set(parent);          
      }

@Override
public synchronized void onTestSuccess(ITestResult result) {
    ExtentTest child = ((ExtentTest) 
   parentTest.get()).createNode(result.getMethod().getMethodName());
    test.set(child);
    ((ExtentTest) test.get()).pass("Test passed");
}

@Override
public synchronized void onTestFailure(ITestResult result) {
    ((ExtentTest) test.get()).fail(result.getThrowable());
}

@Override
public synchronized void onTestSkipped(ITestResult result) {
    ((ExtentTest) test.get()).skip(result.getThrowable());
}

@Override
public synchronized void onTestFailedButWithinSuccessPercentage(ITestResult 
    result) { 

     }
   }

//Extent Manager

 package com.tram.utilities;

 import com.aventstack.extentreports.ExtentReports;
 import com.aventstack.extentreports.reporter.ExtentHtmlReporter;
 import com.aventstack.extentreports.reporter.configuration.Theme;

 public class ExtentManager {

   private static ExtentReports extent;

 public static ExtentReports getInstance() {
    if (extent == null)
        createInstance("test-output/extent.html");      
    return extent;
}

public static ExtentReports createInstance(String fileName) {
    ExtentHtmlReporter htmlReporter = new ExtentHtmlReporter(fileName);
    htmlReporter.config().setTheme(Theme.STANDARD);
    htmlReporter.config().setDocumentTitle(fileName);
    htmlReporter.config().setReportName(fileName);        
    extent = new ExtentReports();
    extent.attachReporter(htmlReporter);        
    return extent;
}

}

2
If you want only name of the Method, You can get it through stackoverflow.com/questions/41502326/…Ishita Shah
@IshitaShah: I don't the method name simply. I want the calling method's name - Test1 when I am in the called method- Test2. Please note that I was executing Test1 and execution comes to Test2 after it finds dependsOnMethods = { "test2" } above Test1.Atul Kumar Sharma
Using ITestResult you can get array of methods . arg0.getMethod().getMethodsDependedUpon(); And Test1 is not calling Test2Rahul L
@RahulL: I think you are asking me a Ques here..And Test1 is not calling Test2?? My ans to this is NO. When Test2 is executed & arg0.getMethod().getMethodsDependedUpon() is empty array.Atul Kumar Sharma

2 Answers

0
votes

A simple way to detect the method name of a running test would be to inject java.lang.reflect.Method as an argument on method-level configuration (@BeforeMethod or @AfterMethod).

As part of the Dependency Injection features in TestNG, an instance of Method that is injected into @BeforeMethod or @AfterMethod "will receive the test method that will be called once this @BeforeMethod finishes (or after the method as run for @AfterMethod)". (see Native Dependency Injection)

This will allow us to retrieve the name of any method being executed, even a dependent test method, which can subsequently be passed to reports.

As a brief example with your use case in mind, consider the following class:

public class MethodNameDemo {

    String methodName;

    @BeforeMethod
    public void setup(Method method) {
        methodName = method.getName();
    }

    @Test
    public void test2() {
        System.out.println("Running " + methodName);
    }

    @Test (dependsOnMethods = "test2")
    public void test1() {
        System.out.println("Running " + methodName);
    }
}

When we run the test1() method directly, the dependsOnMethods will force test2 to execute first. The @BeforeMethod will run before each of the test methods, assigning the class field methodName to the value of the test method that is about to be executed.

Upon execution of test1(), we will get the following output:

Running test2
Running test1

Once you have these values, you can then perform whichever needed operations to pass to Extent.

-1
votes

Finally, sorted my issue using comparing the instance name vs methodname by implementing "ITestListener".

A) If instance name = methodname, create test with methodname.

B) If instance name =! methodname, create test with instancename.

public static ArrayList<String> mylist = new ArrayList<String>();

@Override
public void onTestStart(ITestResult result) {

    String instance = result.getInstanceName().toString();
    String methodname = result.getMethod().toString();

    if ((chkAndAddArray(finalInstance))) {
        return;
    }

    if (finalmethodname.equalsIgnoreCase(finalInstance.toString())) {
        logger = extent.createTest(finalmethodname);
    } else {
        logger = extent.createTest(finalInstance);
    }
}


boolean chkAndAddArray(String instance) {

    if (mylist.contains(instance)) {
        System.out.println(instance + " value is already present");
        return true;
    } else
        mylist.add(instance);
    System.out.println(instance + " value is not present & now, added");
    return false;
}