Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TestReport customisation: How to get java method names at runtime for adding them in reports instead of TestNames #579

Open
p00j4 opened this issue Dec 17, 2014 · 15 comments

Comments

@p00j4
Copy link

p00j4 commented Dec 17, 2014

Hi Cedric,
Thanks for writing this awesome piece.
I have a query....
At run time, how can I get the java method names called under a testMethod
ex. ITestContext/ITestResult exposes the testMethods mentioned in testNg.xml file [ but I want to get java methods which are not annotated and being called from any test annotated method].
Need:

@test(dataProvider="itenary")
public void testBooking(StringArray data){
homePage(data);
searchPage(data);
bookingPage(data);
}
Now if a test fails in bookingPage() flow then I want to show the method name bookingPage() in test report but not testBooking() [so that my report becomes more narrowed to understand which function caused the fail in entire booking flow testing]
similarly for all other methods
[but as per my current understanding I can just show the test method name]
What I tried: thought to have different tests for all above 3 methods but since I need same data from dataprovider to be passed in all, so It can't be possible.
Can you please suggest, any alternative or a object which exposes methods at run time , so that I can make my reports more relevant.

@p00j4
Copy link
Author

p00j4 commented Jan 7, 2015

@cedricrefresh : Kindly please suggest a way

@p00j4
Copy link
Author

p00j4 commented Jan 10, 2015

@VladRassokhin
Copy link
Contributor

To store data between methods you could use @Factory on class constructor and fields.
So could would look like:

class TestClass {
final Object[] args;
@Factory(dataProvider="itenary")
TestClass(Object[] args) {this.args = args}

@Test
void homePage() ...;
@Test(dependsOn="homePage")
searchPage(data) ...;
@Test(dependsOn="searchPage")
bookingPage(data) ... ;
}

But there exists another approaches, e.g. change method name in ITestResult, etc.

@p00j4
Copy link
Author

p00j4 commented Jan 11, 2015

@VladRassokhin : thanks for replying , i'm trying this and will update on the same.
however, can you just forward any link which can give little more details on "e.g. change method name in ITestResult,"

@p00j4
Copy link
Author

p00j4 commented Jan 11, 2015

@VladRassokhin : I tried using Factory but it doesn't serve my purpose, here is my code

public class TestClass {
    final int args;
    @Factory(dataProvider="itenary")
    public TestClass(int args) 
    {
        this.args = args;
    }

    @DataProvider
    static public Object[][] itenary() {
      return new Object[][] {
        new Object[] { 41 },
        new Object[] { 42 },
      };
    }
    @Test(description="homePage /././.",dataProvider="itenary")
    public void homePage(int data){
        System.out.println("in searchPage, data="+data);
    }


    @Test(dependsOnMethods="homePage",dataProvider="itenary")
    public void searchPage(int data){
        System.out.println("in searchPage, data="+data);
    }

    @Test(dependsOnMethods="searchPage",dataProvider="itenary")
    public void bookingPage(int data){
        System.out.println("in bookingPage, data="+data);
    }
}

and the output is-

in homePage, data=41
in homePage, data=42
in homePage, data=41
in homePage, data=42
in searchPage, data=41
in searchPage, data=42
in searchPage, data=41
in searchPage, data=42
in bookingPage, data=41
in bookingPage, data=42
in bookingPage, data=41
in bookingPage, data=42
PASSED: homePage(41)
        homePage /././.
PASSED: homePage(42)
        homePage /././.
PASSED: homePage(41)
        homePage /././.
PASSED: homePage(42)
        homePage /././.
PASSED: searchPage(41)
PASSED: searchPage(42)
PASSED: searchPage(41)
PASSED: searchPage(42)
PASSED: bookingPage(41)
PASSED: bookingPage(42)
PASSED: bookingPage(41)
PASSED: bookingPage(42)

===============================================
    Default test
    Tests run: 12, Failures: 0, Skips: 0
===============================================

rather my desired output is [Since I want all the tests should run for the same data in one cycle]-

in homePage, data=41
in searchPage, data=41
in bookingPage, data=41
in homePage, data=42
in searchPage, data=42
in bookingPage, data=42

Please correct me if I have used Factory in wrong manor, also as per definition, factory is generally used for load testing to load same test multiple times, so I'm wondering how does it can fit my requirement !
image

@p00j4
Copy link
Author

p00j4 commented Jan 11, 2015

My requirement is , when a test fails, so related enclosing method name should be displayed in test report
Ex.
when failure occurs in in bookingPage() flow then bookingPage() should be shown in test report but not testBooking()
[so that my report becomes more narrowed/specialized to understand which function caused the fail in entire "testBooking" testNg test]

@p00j4
Copy link
Author

p00j4 commented Jan 21, 2015

@nullin @VladRassokhin @lukasj : anyone felt need of this and tried !

@p00j4
Copy link
Author

p00j4 commented Feb 6, 2015

@cbeust : i'm naive at this, a little idea will help me achieve the custom requirement and if this feature is straight forward added in lib will definitely make it more usable .

@p00j4 p00j4 changed the title How to get java methods at runtime for adding them in reports TestReport customisation: How to get java method names at runtime for adding them in reports instead of TestNames Feb 6, 2015
@p00j4
Copy link
Author

p00j4 commented Apr 27, 2015

Using "ITestResult" also returns "testName" declared in testng xml file but not the java method called from the testMethod where the code had failed.

public void onTestFailure(ITestResult tr) {
    tr.getMethod().getMethodName().toString(); //returns testMethod name but not the method name from where onTestFailure is actuated
    tr.getMethod().getClass().getCanonicalName(); //returns class name
}

@juherr
Copy link
Member

juherr commented Apr 27, 2015

You can try: tr.getMethod().getConstructorOrMethod().getName()

@p00j4
Copy link
Author

p00j4 commented Apr 27, 2015

@juherr : this too returns "testBooking" the name of annoted method rather I'm looking for name like "homePage" or "searchPage" etc from wherever the call is transfered to the respective listener method (onTestFailure / onTestSuccess / onTestSkipped)
and I'm wondering if its possible with TestNg, since on debugging I have found that "ITestResult" doesn't have the java method name throughout its life cycle [checked in Invoker.java->runTestListeners] [all the names which sound like methodName are actually pointing to @test method names]

@juherr
Copy link
Member

juherr commented Apr 27, 2015

@p00j4 Could you create a little and runnable project? That will be easier to understand.

@p00j4
Copy link
Author

p00j4 commented Apr 27, 2015

@juherr : thanks for taking time out, here is the code- https://github.com/p00j4/customReoprt

test class
listener implementation

@juherr
Copy link
Member

juherr commented Apr 28, 2015

Ok, I understand now.
Maybe you could try something with result.getThrowable() but not sure if it is possible.

I never have to use it, but maybe FluentLenium could help you too.

@sanjayselectorshub
Copy link

@p00j4
you can use this code inside any method-
int size = Thread.currentThread().getStackTrace().length;
System.out.println("size -"+size);
String methodName = Thread.currentThread().getStackTrace()[size-29].getMethodName().toLowerCase(); //there are other 28 methods call so ignore them

This piece of code will always give you the method name which is running currently inside @test method, like - homePage.

And to get the current method name where exactly test case got failed you can use below code-
Thread.currentThread().getStackTrace()[1].getMethodName().toLowerCase();

@krmahadevan krmahadevan added this to the 7.6.0 milestone Jan 7, 2022
@krmahadevan krmahadevan modified the milestones: 7.6.0, 7.7.0 May 18, 2022
@krmahadevan krmahadevan removed this from the 7.7.0 milestone Dec 6, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants