Is this how IInvokedMethodListener supposed to work?

classic Classic list List threaded Threaded
15 messages Options
Reply | Threaded
Open this post in threaded view
|

Is this how IInvokedMethodListener supposed to work?

praveen133t
I have a test class as below

@Listeners(com.testng.test.TestListener.class)

public class TestClass {


    @Test

    public void testMethod() {

        ReportImpl report = new ReportImpl();

        report.populateMap();

    }

}


Then I have a `ReportImpl` class as below


public class ReportImpl {


    Map<String, String> reportMap = new HashMap<String, String>();


    public void populateMap() {

        reportMap.put("google", "alphabet");

        reportMap.put("bing", "Microsoft");

        reportMap.put("iOS", "apple");

    }


    public void getDataFromMap() {

        String google = reportMap.get("google");

        String ms = reportMap.get("bing");

        System.out.println(google + ms);

    }

}



Now I have a listener called `TestListener` which is implements `IInvokedMethodListener` as below


public class TestListener implements IInvokedMethodListener {


    @Override

    public void beforeInvocation(IInvokedMethod method, ITestResult testResult) {

        ReportImpl report = new ReportImpl();

        Reporter.getCurrentTestResult()

                .setAttribute("REPORT_DATA", report);


    }


    @Override

    public void afterInvocation(IInvokedMethod method, ITestResult testResult) {

        ReportImpl report = (ReportImpl) Reporter.getCurrentTestResult()

                                                 .getAttribute("REPORT_DATA");

        report.getDataFromMap();


    }

}


Now the question is in the `afterInvocation` I'm doing `report.getDataFromMap()` which in turn get's data from `ReportImp` class. Unfortunately `reportMap` is null because for some reasons the key/value that was put into this `reportMap` has been lost when the control was passed to `afterInvocation`. 


But when I make the `reportMap` to static it perfectly works fine. Is this how it's supposed to work? What would be the side effect for having `static` map when tests are run in parallel?

--
You received this message because you are subscribed to the Google Groups "testng-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/testng-users.
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Is this how IInvokedMethodListener supposed to work?

SUBRAMANYESWARA RAO BHAVIRISETTY
If you declare it as static, the value will be retained across the invocations.  I guess static hashmaps are not thread safe. Please take a look at this link:
http://www.asjava.com/core-java/thread-safe-hash-map-in-java-and-their-performance-benchmark/

Just wanted to know why you wanted to share the same data structure across multiple tests.




On Mon, Dec 18, 2017 at 4:40 PM, prvn <[hidden email]> wrote:
I have a test class as below

@Listeners(com.testng.test.TestListener.class)

public class TestClass {


    @Test

    public void testMethod() {

        ReportImpl report = new ReportImpl();

        report.populateMap();

    }

}


Then I have a `ReportImpl` class as below


public class ReportImpl {


    Map<String, String> reportMap = new HashMap<String, String>();


    public void populateMap() {

        reportMap.put("google", "alphabet");

        reportMap.put("bing", "Microsoft");

        reportMap.put("iOS", "apple");

    }


    public void getDataFromMap() {

        String google = reportMap.get("google");

        String ms = reportMap.get("bing");

        System.out.println(google + ms);

    }

}



Now I have a listener called `TestListener` which is implements `IInvokedMethodListener` as below


public class TestListener implements IInvokedMethodListener {


    @Override

    public void beforeInvocation(IInvokedMethod method, ITestResult testResult) {

        ReportImpl report = new ReportImpl();

        Reporter.getCurrentTestResult()

                .setAttribute("REPORT_DATA", report);


    }


    @Override

    public void afterInvocation(IInvokedMethod method, ITestResult testResult) {

        ReportImpl report = (ReportImpl) Reporter.getCurrentTestResult()

                                                 .getAttribute("REPORT_DATA");

        report.getDataFromMap();


    }

}


Now the question is in the `afterInvocation` I'm doing `report.getDataFromMap()` which in turn get's data from `ReportImp` class. Unfortunately `reportMap` is null because for some reasons the key/value that was put into this `reportMap` has been lost when the control was passed to `afterInvocation`. 


But when I make the `reportMap` to static it perfectly works fine. Is this how it's supposed to work? What would be the side effect for having `static` map when tests are run in parallel?

--
You received this message because you are subscribed to the Google Groups "testng-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/testng-users.
For more options, visit https://groups.google.com/d/optout.



--
Subramanyam

--
You received this message because you are subscribed to the Google Groups "testng-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/testng-users.
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Is this how IInvokedMethodListener supposed to work?

praveen133t
@Subramanyaeswara: I don't want to share same data across multiple tests. This is just an example. But imagine the "ReportImpl" class carries some information about the test itself. So it's unique data.

On Monday, December 18, 2017 at 8:58:32 PM UTC-5, SUBRAMANYESWARA RAO BHAVIRISETTY wrote:
If you declare it as static, the value will be retained across the invocations.  I guess static hashmaps are not thread safe. Please take a look at this link:
<a href="http://www.asjava.com/core-java/thread-safe-hash-map-in-java-and-their-performance-benchmark/" target="_blank" rel="nofollow" onmousedown="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fwww.asjava.com%2Fcore-java%2Fthread-safe-hash-map-in-java-and-their-performance-benchmark%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHpdpg0CKDZQXeAgQGSkjLrvbFrLg&#39;;return true;" onclick="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fwww.asjava.com%2Fcore-java%2Fthread-safe-hash-map-in-java-and-their-performance-benchmark%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHpdpg0CKDZQXeAgQGSkjLrvbFrLg&#39;;return true;">http://www.asjava.com/core-java/thread-safe-hash-map-in-java-and-their-performance-benchmark/

Just wanted to know why you wanted to share the same data structure across multiple tests.




On Mon, Dec 18, 2017 at 4:40 PM, prvn <<a href="javascript:" target="_blank" gdf-obfuscated-mailto="KOCQjj9ODAAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">neevar...@...> wrote:
I have a test class as below

@Listeners(com.testng.test.TestListener.class)

public class TestClass {


    @Test

    public void testMethod() {

        ReportImpl report = new ReportImpl();

        report.populateMap();

    }

}


Then I have a `ReportImpl` class as below


public class ReportImpl {


    Map<String, String> reportMap = new HashMap<String, String>();


    public void populateMap() {

        reportMap.put("google", "alphabet");

        reportMap.put("bing", "Microsoft");

        reportMap.put("iOS", "apple");

    }


    public void getDataFromMap() {

        String google = reportMap.get("google");

        String ms = reportMap.get("bing");

        System.out.println(google + ms);

    }

}



Now I have a listener called `TestListener` which is implements `IInvokedMethodListener` as below


public class TestListener implements IInvokedMethodListener {


    @Override

    public void beforeInvocation(IInvokedMethod method, ITestResult testResult) {

        ReportImpl report = new ReportImpl();

        Reporter.getCurrentTestResult()

                .setAttribute("REPORT_DATA", report);


    }


    @Override

    public void afterInvocation(IInvokedMethod method, ITestResult testResult) {

        ReportImpl report = (ReportImpl) Reporter.getCurrentTestResult()

                                                 .getAttribute("REPORT_DATA");

        report.getDataFromMap();


    }

}


Now the question is in the `afterInvocation` I'm doing `report.getDataFromMap()` which in turn get's data from `ReportImp` class. Unfortunately `reportMap` is null because for some reasons the key/value that was put into this `reportMap` has been lost when the control was passed to `afterInvocation`. 


But when I make the `reportMap` to static it perfectly works fine. Is this how it's supposed to work? What would be the side effect for having `static` map when tests are run in parallel?

--
You received this message because you are subscribed to the Google Groups "testng-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to <a href="javascript:" target="_blank" gdf-obfuscated-mailto="KOCQjj9ODAAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">testng-users...@googlegroups.com.
To post to this group, send email to <a href="javascript:" target="_blank" gdf-obfuscated-mailto="KOCQjj9ODAAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">testng...@....
Visit this group at <a href="https://groups.google.com/group/testng-users" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://groups.google.com/group/testng-users&#39;;return true;" onclick="this.href=&#39;https://groups.google.com/group/testng-users&#39;;return true;">https://groups.google.com/group/testng-users.
For more options, visit <a href="https://groups.google.com/d/optout" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://groups.google.com/d/optout&#39;;return true;" onclick="this.href=&#39;https://groups.google.com/d/optout&#39;;return true;">https://groups.google.com/d/optout.



--
Subramanyam

--
You received this message because you are subscribed to the Google Groups "testng-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/testng-users.
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Is this how IInvokedMethodListener supposed to work?

SUBRAMANYESWARA RAO BHAVIRISETTY
I generally use reportng for the test reporting by configuring it as a listener in pom.

http://www.seleniumeasy.com/testng-tutorials/configuring-reportng-with-testng-to-generate-html-reports

Anything you want to log can be done in Reporter.log and it would get logged on the screen . https://jitpack.io/com/github/cbeust/testng/master-6.13.1-gf634d0a-4/javadoc/org/testng/Reporter.html has more details. Reporter class is definitely threadsafe.

Jenkins takes care of archiving the html reports.

Subramanyam



On Mon, Dec 18, 2017 at 6:01 PM, prvn <[hidden email]> wrote:
@Subramanyaeswara: I don't want to share same data across multiple tests. This is just an example. But imagine the "ReportImpl" class carries some information about the test itself. So it's unique data.

On Monday, December 18, 2017 at 8:58:32 PM UTC-5, SUBRAMANYESWARA RAO BHAVIRISETTY wrote:
If you declare it as static, the value will be retained across the invocations.  I guess static hashmaps are not thread safe. Please take a look at this link:
http://www.asjava.com/core-java/thread-safe-hash-map-in-java-and-their-performance-benchmark/

Just wanted to know why you wanted to share the same data structure across multiple tests.




On Mon, Dec 18, 2017 at 4:40 PM, prvn <[hidden email]> wrote:
I have a test class as below

@Listeners(com.testng.test.TestListener.class)

public class TestClass {


    @Test

    public void testMethod() {

        ReportImpl report = new ReportImpl();

        report.populateMap();

    }

}


Then I have a `ReportImpl` class as below


public class ReportImpl {


    Map<String, String> reportMap = new HashMap<String, String>();


    public void populateMap() {

        reportMap.put("google", "alphabet");

        reportMap.put("bing", "Microsoft");

        reportMap.put("iOS", "apple");

    }


    public void getDataFromMap() {

        String google = reportMap.get("google");

        String ms = reportMap.get("bing");

        System.out.println(google + ms);

    }

}



Now I have a listener called `TestListener` which is implements `IInvokedMethodListener` as below


public class TestListener implements IInvokedMethodListener {


    @Override

    public void beforeInvocation(IInvokedMethod method, ITestResult testResult) {

        ReportImpl report = new ReportImpl();

        Reporter.getCurrentTestResult()

                .setAttribute("REPORT_DATA", report);


    }


    @Override

    public void afterInvocation(IInvokedMethod method, ITestResult testResult) {

        ReportImpl report = (ReportImpl) Reporter.getCurrentTestResult()

                                                 .getAttribute("REPORT_DATA");

        report.getDataFromMap();


    }

}


Now the question is in the `afterInvocation` I'm doing `report.getDataFromMap()` which in turn get's data from `ReportImp` class. Unfortunately `reportMap` is null because for some reasons the key/value that was put into this `reportMap` has been lost when the control was passed to `afterInvocation`. 


But when I make the `reportMap` to static it perfectly works fine. Is this how it's supposed to work? What would be the side effect for having `static` map when tests are run in parallel?

--
You received this message because you are subscribed to the Google Groups "testng-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to testng-users...@googlegroups.com.
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/testng-users.
For more options, visit https://groups.google.com/d/optout.



--
Subramanyam

--
You received this message because you are subscribed to the Google Groups "testng-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/testng-users.
For more options, visit https://groups.google.com/d/optout.



--
Subramanyam

--
You received this message because you are subscribed to the Google Groups "testng-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/testng-users.
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Is this how IInvokedMethodListener supposed to work?

praveen133t
Sorry.. This is no where close to reporting. 

On Monday, December 18, 2017 at 9:09:58 PM UTC-5, SUBRAMANYESWARA RAO BHAVIRISETTY wrote:
I generally use reportng for the test reporting by configuring it as a listener in pom.

<a href="http://www.seleniumeasy.com/testng-tutorials/configuring-reportng-with-testng-to-generate-html-reports" target="_blank" rel="nofollow" onmousedown="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fwww.seleniumeasy.com%2Ftestng-tutorials%2Fconfiguring-reportng-with-testng-to-generate-html-reports\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHublL5CNnNyKWloEeDfjQhIubeGw&#39;;return true;" onclick="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fwww.seleniumeasy.com%2Ftestng-tutorials%2Fconfiguring-reportng-with-testng-to-generate-html-reports\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHublL5CNnNyKWloEeDfjQhIubeGw&#39;;return true;">http://www.seleniumeasy.com/testng-tutorials/configuring-reportng-with-testng-to-generate-html-reports

Anything you want to log can be done in Reporter.log and it would get logged on the screen . <a href="https://jitpack.io/com/github/cbeust/testng/master-6.13.1-gf634d0a-4/javadoc/org/testng/Reporter.html" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fjitpack.io%2Fcom%2Fgithub%2Fcbeust%2Ftestng%2Fmaster-6.13.1-gf634d0a-4%2Fjavadoc%2Forg%2Ftestng%2FReporter.html\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFZeFz_Es2DOkPSK4Nw09wYBYWnGw&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fjitpack.io%2Fcom%2Fgithub%2Fcbeust%2Ftestng%2Fmaster-6.13.1-gf634d0a-4%2Fjavadoc%2Forg%2Ftestng%2FReporter.html\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFZeFz_Es2DOkPSK4Nw09wYBYWnGw&#39;;return true;">https://jitpack.io/com/github/cbeust/testng/master-6.13.1-gf634d0a-4/javadoc/org/testng/Reporter.html has more details. Reporter class is definitely threadsafe.

Jenkins takes care of archiving the html reports.

Subramanyam



On Mon, Dec 18, 2017 at 6:01 PM, prvn <<a href="javascript:" target="_blank" gdf-obfuscated-mailto="HKuZJ99ODAAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">neevar...@...> wrote:
@Subramanyaeswara: I don't want to share same data across multiple tests. This is just an example. But imagine the "ReportImpl" class carries some information about the test itself. So it's unique data.

On Monday, December 18, 2017 at 8:58:32 PM UTC-5, SUBRAMANYESWARA RAO BHAVIRISETTY wrote:
If you declare it as static, the value will be retained across the invocations.  I guess static hashmaps are not thread safe. Please take a look at this link:
<a href="http://www.asjava.com/core-java/thread-safe-hash-map-in-java-and-their-performance-benchmark/" rel="nofollow" target="_blank" onmousedown="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fwww.asjava.com%2Fcore-java%2Fthread-safe-hash-map-in-java-and-their-performance-benchmark%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHpdpg0CKDZQXeAgQGSkjLrvbFrLg&#39;;return true;" onclick="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fwww.asjava.com%2Fcore-java%2Fthread-safe-hash-map-in-java-and-their-performance-benchmark%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHpdpg0CKDZQXeAgQGSkjLrvbFrLg&#39;;return true;">http://www.asjava.com/core-java/thread-safe-hash-map-in-java-and-their-performance-benchmark/

Just wanted to know why you wanted to share the same data structure across multiple tests.




On Mon, Dec 18, 2017 at 4:40 PM, prvn <[hidden email]> wrote:
I have a test class as below

@Listeners(com.testng.test.TestListener.class)

public class TestClass {


    @Test

    public void testMethod() {

        ReportImpl report = new ReportImpl();

        report.populateMap();

    }

}


Then I have a `ReportImpl` class as below


public class ReportImpl {


    Map<String, String> reportMap = new HashMap<String, String>();


    public void populateMap() {

        reportMap.put("google", "alphabet");

        reportMap.put("bing", "Microsoft");

        reportMap.put("iOS", "apple");

    }


    public void getDataFromMap() {

        String google = reportMap.get("google");

        String ms = reportMap.get("bing");

        System.out.println(google + ms);

    }

}



Now I have a listener called `TestListener` which is implements `IInvokedMethodListener` as below


public class TestListener implements IInvokedMethodListener {


    @Override

    public void beforeInvocation(IInvokedMethod method, ITestResult testResult) {

        ReportImpl report = new ReportImpl();

        Reporter.getCurrentTestResult()

                .setAttribute("REPORT_DATA", report);


    }


    @Override

    public void afterInvocation(IInvokedMethod method, ITestResult testResult) {

        ReportImpl report = (ReportImpl) Reporter.getCurrentTestResult()

                                                 .getAttribute("REPORT_DATA");

        report.getDataFromMap();


    }

}


Now the question is in the `afterInvocation` I'm doing `report.getDataFromMap()` which in turn get's data from `ReportImp` class. Unfortunately `reportMap` is null because for some reasons the key/value that was put into this `reportMap` has been lost when the control was passed to `afterInvocation`. 


But when I make the `reportMap` to static it perfectly works fine. Is this how it's supposed to work? What would be the side effect for having `static` map when tests are run in parallel?

--
You received this message because you are subscribed to the Google Groups "testng-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to testng-users...@googlegroups.com.
To post to this group, send email to [hidden email].
Visit this group at <a href="https://groups.google.com/group/testng-users" rel="nofollow" target="_blank" onmousedown="this.href=&#39;https://groups.google.com/group/testng-users&#39;;return true;" onclick="this.href=&#39;https://groups.google.com/group/testng-users&#39;;return true;">https://groups.google.com/group/testng-users.
For more options, visit <a href="https://groups.google.com/d/optout" rel="nofollow" target="_blank" onmousedown="this.href=&#39;https://groups.google.com/d/optout&#39;;return true;" onclick="this.href=&#39;https://groups.google.com/d/optout&#39;;return true;">https://groups.google.com/d/optout.



--
Subramanyam

--
You received this message because you are subscribed to the Google Groups "testng-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to <a href="javascript:" target="_blank" gdf-obfuscated-mailto="HKuZJ99ODAAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">testng-users...@googlegroups.com.
To post to this group, send email to <a href="javascript:" target="_blank" gdf-obfuscated-mailto="HKuZJ99ODAAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">testng...@....
Visit this group at <a href="https://groups.google.com/group/testng-users" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://groups.google.com/group/testng-users&#39;;return true;" onclick="this.href=&#39;https://groups.google.com/group/testng-users&#39;;return true;">https://groups.google.com/group/testng-users.
For more options, visit <a href="https://groups.google.com/d/optout" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://groups.google.com/d/optout&#39;;return true;" onclick="this.href=&#39;https://groups.google.com/d/optout&#39;;return true;">https://groups.google.com/d/optout.



--
Subramanyam

--
You received this message because you are subscribed to the Google Groups "testng-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/testng-users.
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Is this how IInvokedMethodListener supposed to work?

Krishnan Mahadevan
In reply to this post by praveen133t

Praveen,

 

>>>> Now the question is in the `afterInvocation` I'm doing `report.getDataFromMap()` which in turn get's data from `ReportImp` class. Unfortunately `reportMap` is null because for some reasons the key/value that was put into this `reportMap` has been lost when the control was passed to `afterInvocation`. 

 

This is because, from within beforeInvocation() you are invoking Reporter.getCurrentTestResult() which is going to fetch the ITestResult object associated with “beforeInvocation()” now when you enter the @Test method, the ITestResult object of the current test method is what gets popped out when you do a Reporter.getCurrentTestResult(). And when you are entering your afterInvocation(), since its still on the same thread [ only beforeInvocation() > @Test > afterInvocation()  are guaranteed to run on the same thread ] you get the ITestResult object which doesn’t have what was persisted via the setAttribute() method.

 

I am guessing that perhaps the following changed code is what you need.

 

import org.testng.Reporter;
import org.testng.annotations.Listeners;
import org.testng.annotations.Test;

@Listeners(TestListener.class)
public class TestClass {

   
@Test
   
public void testMethod() {
        ReportImpl report =
new ReportImpl();
        report.populateMap();
        Reporter.getCurrentTestResult().setAttribute(
"REPORT_DATA", report);
    }
}

 

import java.util.HashMap;
import java.util.Map;

public class ReportImpl {

    Map<String, String>
reportMap = new HashMap<String, String>();

   
public void populateMap() {
       
reportMap.put("google", "alphabet");
       
reportMap.put("bing", "Microsoft");
       
reportMap.put("iOS", "apple");
    }

   
public void getDataFromMap() {
        String google =
reportMap.get("google");
        String ms =
reportMap.get("bing");
        System.
err.println(google + ms);
    }
}

 

import org.testng.IInvokedMethod;
import org.testng.IInvokedMethodListener;
import org.testng.ITestResult;

public class TestListener implements IInvokedMethodListener {

   
@Override
   
public void beforeInvocation(IInvokedMethod method, ITestResult testResult) {
        ReportImpl report =
new ReportImpl();
        testResult.setAttribute(
"REPORT_DATA", report);

    }

   
@Override
   
public void afterInvocation(IInvokedMethod method, ITestResult testResult) {
        ReportImpl report = (ReportImpl) testResult.getAttribute(
"REPORT_DATA");
        report.getDataFromMap();

    }
}

 

Output:

 

alphabetMicrosoft

 

===============================================

Default Suite

Total tests run: 1, Failures: 0, Skips: 0

===============================================

 

 

Process finished with exit code 0

 

 

 

 

Thanks & Regards

Krishnan Mahadevan

 

"All the desirable things in life are either illegal, expensive, fattening or in love with someone else!"

My Scribblings @ http://wakened-cognition.blogspot.com/

My Technical Scribbings @ http://rationaleemotions.wordpress.com/

 

From: <[hidden email]> on behalf of prvn <[hidden email]>
Reply-To: <[hidden email]>
Date: Tuesday, December 19, 2017 at 6:10 AM
To: testng-users <[hidden email]>
Subject: [testng-users] Is this how IInvokedMethodListener supposed to work?

 

I have a test class as below

 

@Listeners(com.testng.test.TestListener.class)

public class TestClass {

 

    @Test

    public void testMethod() {

        ReportImpl report = new ReportImpl();

        report.populateMap();

    }

}

 

Then I have a `ReportImpl` class as below

 

public class ReportImpl {

 

    Map<String, String> reportMap = new HashMap<String, String>();

 

    public void populateMap() {

        reportMap.put("google", "alphabet");

        reportMap.put("bing", "Microsoft");

        reportMap.put("iOS", "apple");

    }

 

    public void getDataFromMap() {

        String google = reportMap.get("google");

        String ms = reportMap.get("bing");

        System.out.println(google + ms);

    }

}

 

 

Now I have a listener called `TestListener` which is implements `IInvokedMethodListener` as below

 

public class TestListener implements IInvokedMethodListener {

 

    @Override

    public void beforeInvocation(IInvokedMethod method, ITestResult testResult) {

        ReportImpl report = new ReportImpl();

        Reporter.getCurrentTestResult()

                .setAttribute("REPORT_DATA", report);

 

    }

 

    @Override

    public void afterInvocation(IInvokedMethod method, ITestResult testResult) {

        ReportImpl report = (ReportImpl) Reporter.getCurrentTestResult()

                                                 .getAttribute("REPORT_DATA");

        report.getDataFromMap();

 

    }

}

 

Now the question is in the `afterInvocation` I'm doing `report.getDataFromMap()` which in turn get's data from `ReportImp` class. Unfortunately `reportMap` is null because for some reasons the key/value that was put into this `reportMap` has been lost when the control was passed to `afterInvocation`. 

 

But when I make the `reportMap` to static it perfectly works fine. Is this how it's supposed to work? What would be the side effect for having `static` map when tests are run in parallel?

--
You received this message because you are subscribed to the Google Groups "testng-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/testng-users.
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "testng-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/testng-users.
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Is this how IInvokedMethodListener supposed to work?

Krishnan Mahadevan

Including the correct TestClass version

 

@Listeners(TestListener.class)
public class TestClass {

   
@Test
   
public void testMethod() {
        ReportImpl report = (ReportImpl) Reporter.getCurrentTestResult().getAttribute(
"REPORT_DATA");
        report.populateMap();
        Reporter.getCurrentTestResult().setAttribute(
"REPORT_DATA", report);
    }
}

 

 

Thanks & Regards

Krishnan Mahadevan

 

"All the desirable things in life are either illegal, expensive, fattening or in love with someone else!"

My Scribblings @ http://wakened-cognition.blogspot.com/

My Technical Scribbings @ http://rationaleemotions.wordpress.com/

 

From: Krishnan Mahadevan <[hidden email]>
Date: Tuesday, December 19, 2017 at 7:48 AM
To: <[hidden email]>
Subject: Re: [testng-users] Is this how IInvokedMethodListener supposed to work?

 

Praveen,

 

>>>> Now the question is in the `afterInvocation` I'm doing `report.getDataFromMap()` which in turn get's data from `ReportImp` class. Unfortunately `reportMap` is null because for some reasons the key/value that was put into this `reportMap` has been lost when the control was passed to `afterInvocation`. 

 

This is because, from within beforeInvocation() you are invoking Reporter.getCurrentTestResult() which is going to fetch the ITestResult object associated with “beforeInvocation()” now when you enter the @Test method, the ITestResult object of the current test method is what gets popped out when you do a Reporter.getCurrentTestResult(). And when you are entering your afterInvocation(), since its still on the same thread [ only beforeInvocation() > @Test > afterInvocation()  are guaranteed to run on the same thread ] you get the ITestResult object which doesn’t have what was persisted via the setAttribute() method.

 

I am guessing that perhaps the following changed code is what you need.

 

import org.testng.Reporter;
import org.testng.annotations.Listeners;
import org.testng.annotations.Test;

@Listeners(TestListener.class)
public class TestClass {

   
@Test
   
public void testMethod() {
        ReportImpl report =
new ReportImpl();
        report.populateMap();
        Reporter.getCurrentTestResult().setAttribute(
"REPORT_DATA", report);
    }
}

 

import java.util.HashMap;
import java.util.Map;

public class ReportImpl {

    Map<String, String>
reportMap = new HashMap<String, String>();

   
public void populateMap() {
       
reportMap.put("google", "alphabet");
       
reportMap.put("bing", "Microsoft");
       
reportMap.put("iOS", "apple");
    }

   
public void getDataFromMap() {
        String google =
reportMap.get("google");
        String ms =
reportMap.get("bing");
        System.
err.println(google + ms);
    }
}

 

import org.testng.IInvokedMethod;
import org.testng.IInvokedMethodListener;
import org.testng.ITestResult;

public class TestListener implements IInvokedMethodListener {

   
@Override
   
public void beforeInvocation(IInvokedMethod method, ITestResult testResult) {
        ReportImpl report =
new ReportImpl();
        testResult.setAttribute(
"REPORT_DATA", report);

    }

   
@Override
   
public void afterInvocation(IInvokedMethod method, ITestResult testResult) {
        ReportImpl report = (ReportImpl) testResult.getAttribute(
"REPORT_DATA");
        report.getDataFromMap();

    }
}

 

Output:

 

alphabetMicrosoft

 

===============================================

Default Suite

Total tests run: 1, Failures: 0, Skips: 0

===============================================

 

 

Process finished with exit code 0

 

 

 

 

Thanks & Regards

Krishnan Mahadevan

 

"All the desirable things in life are either illegal, expensive, fattening or in love with someone else!"

My Scribblings @ http://wakened-cognition.blogspot.com/

My Technical Scribbings @ http://rationaleemotions.wordpress.com/

 

From: <[hidden email]> on behalf of prvn <[hidden email]>
Reply-To: <[hidden email]>
Date: Tuesday, December 19, 2017 at 6:10 AM
To: testng-users <[hidden email]>
Subject: [testng-users] Is this how IInvokedMethodListener supposed to work?

 

I have a test class as below

 

@Listeners(com.testng.test.TestListener.class)

public class TestClass {

 

    @Test

    public void testMethod() {

        ReportImpl report = new ReportImpl();

        report.populateMap();

    }

}

 

Then I have a `ReportImpl` class as below

 

public class ReportImpl {

 

    Map<String, String> reportMap = new HashMap<String, String>();

 

    public void populateMap() {

        reportMap.put("google", "alphabet");

        reportMap.put("bing", "Microsoft");

        reportMap.put("iOS", "apple");

    }

 

    public void getDataFromMap() {

        String google = reportMap.get("google");

        String ms = reportMap.get("bing");

        System.out.println(google + ms);

    }

}

 

 

Now I have a listener called `TestListener` which is implements `IInvokedMethodListener` as below

 

public class TestListener implements IInvokedMethodListener {

 

    @Override

    public void beforeInvocation(IInvokedMethod method, ITestResult testResult) {

        ReportImpl report = new ReportImpl();

        Reporter.getCurrentTestResult()

                .setAttribute("REPORT_DATA", report);

 

    }

 

    @Override

    public void afterInvocation(IInvokedMethod method, ITestResult testResult) {

        ReportImpl report = (ReportImpl) Reporter.getCurrentTestResult()

                                                 .getAttribute("REPORT_DATA");

        report.getDataFromMap();

 

    }

}

 

Now the question is in the `afterInvocation` I'm doing `report.getDataFromMap()` which in turn get's data from `ReportImp` class. Unfortunately `reportMap` is null because for some reasons the key/value that was put into this `reportMap` has been lost when the control was passed to `afterInvocation`. 

 

But when I make the `reportMap` to static it perfectly works fine. Is this how it's supposed to work? What would be the side effect for having `static` map when tests are run in parallel?

--
You received this message because you are subscribed to the Google Groups "testng-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/testng-users.
For more options, visit https://groups.google.com/d/optout.


--
You received this message because you are subscribed to the Google Groups "testng-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/testng-users.
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Is this how IInvokedMethodListener supposed to work?

praveen133t
Thanks Krishnan. I tried that and it worked for me. But two questions

1. Is static field (In ReportImpl class) going to have a side effect when tests are executed in parallel?
2. I really cannot have Reporter.getCurrentTestResult().setAttribute("REPORT_DATA", report); in my test case. Is there any other way to persist the object through afterInvocation?


On Monday, December 18, 2017 at 9:21:35 PM UTC-5, Krishnan Mahadevan wrote:

Including the correct TestClass version

 

@Listeners(TestListener.class)
public class TestClass {

   
@Test
   
public void testMethod() {
        ReportImpl report = (ReportImpl) Reporter.getCurrentTestResult().getAttribute(
"REPORT_DATA");
        report.populateMap();
        Reporter.getCurrentTestResult().setAttribute(
"REPORT_DATA", report);
    }
}

 

 

Thanks & Regards

Krishnan Mahadevan

 

"All the desirable things in life are either illegal, expensive, fattening or in love with someone else!"

My Scribblings @ <a href="http://wakened-cognition.blogspot.com/" target="_blank" rel="nofollow" onmousedown="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fwakened-cognition.blogspot.com%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHzOdYJCASIDF_28vQtkp9gnKAYSQ&#39;;return true;" onclick="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fwakened-cognition.blogspot.com%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHzOdYJCASIDF_28vQtkp9gnKAYSQ&#39;;return true;">http://wakened-cognition.blogspot.com/

My Technical Scribbings @ <a href="http://rationaleemotions.wordpress.com/" target="_blank" rel="nofollow" onmousedown="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Frationaleemotions.wordpress.com%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNEcBOKyRn0lpL8LDbBuyAlKdwgXwQ&#39;;return true;" onclick="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Frationaleemotions.wordpress.com%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNEcBOKyRn0lpL8LDbBuyAlKdwgXwQ&#39;;return true;">http://rationaleemotions.wordpress.com/

 

From: Krishnan Mahadevan <<a href="javascript:" target="_blank" gdf-obfuscated-mailto="JQxQiYFPDAAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">krishnan.ma...@gmail.com>
Date: Tuesday, December 19, 2017 at 7:48 AM
To: <<a href="javascript:" target="_blank" gdf-obfuscated-mailto="JQxQiYFPDAAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">testng...@...>
Subject: Re: [testng-users] Is this how IInvokedMethodListener supposed to work?

 

Praveen,

 

>>>> Now the question is in the `afterInvocation` I'm doing `report.getDataFromMap()` which in turn get's data from `ReportImp` class. Unfortunately `reportMap` is null because for some reasons the key/value that was put into this `reportMap` has been lost when the control was passed to `afterInvocation`. 

 

This is because, from within beforeInvocation() you are invoking Reporter.getCurrentTestResult() which is going to fetch the ITestResult object associated with “beforeInvocation()” now when you enter the @Test method, the ITestResult object of the current test method is what gets popped out when you do a Reporter.getCurrentTestResult(). And when you are entering your afterInvocation(), since its still on the same thread [ only beforeInvocation() > @Test > afterInvocation()  are guaranteed to run on the same thread ] you get the ITestResult object which doesn’t have what was persisted via the setAttribute() method.

 

I am guessing that perhaps the following changed code is what you need.

 

import org.testng.Reporter;
import org.testng.annotations.Listeners;
import org.testng.annotations.Test;

@Listeners(TestListener.class)
public class TestClass {

   
@Test
   
public void testMethod() {
        ReportImpl report =
new ReportImpl();
        report.populateMap();
        Reporter.getCurrentTestResult().setAttribute(
"REPORT_DATA", report);
    }
}

 

import java.util.HashMap;
import java.util.Map;

public class ReportImpl {

    Map<String, String>
reportMap = new HashMap<String, String>();

   
public void populateMap() {
       
reportMap.put("google", "alphabet");
       
reportMap.put("bing", "Microsoft");
       
reportMap.put("iOS", "apple");
    }

   
public void getDataFromMap() {
        String google =
reportMap.get("google");
        String ms =
reportMap.get("bing");
        System.
err.println(google + ms);
    }
}

 

import org.testng.IInvokedMethod;
import org.testng.IInvokedMethodListener;
import org.testng.ITestResult;

public class TestListener implements IInvokedMethodListener {

   
@Override
   
public void beforeInvocation(IInvokedMethod method, ITestResult testResult) {
        ReportImpl report =
new ReportImpl();
        testResult.setAttribute(
"REPORT_DATA", report);

    }

   
@Override
   
public void afterInvocation(IInvokedMethod method, ITestResult testResult) {
        ReportImpl report = (ReportImpl) testResult.getAttribute(
"REPORT_DATA");
        report.getDataFromMap();

    }
}

 

Output:

 

alphabetMicrosoft

 

===============================================

Default Suite

Total tests run: 1, Failures: 0, Skips: 0

===============================================

 

 

Process finished with exit code 0

 

 

 

 

Thanks & Regards

Krishnan Mahadevan

 

"All the desirable things in life are either illegal, expensive, fattening or in love with someone else!"

My Scribblings @ <a href="http://wakened-cognition.blogspot.com/" target="_blank" rel="nofollow" onmousedown="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fwakened-cognition.blogspot.com%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHzOdYJCASIDF_28vQtkp9gnKAYSQ&#39;;return true;" onclick="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fwakened-cognition.blogspot.com%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHzOdYJCASIDF_28vQtkp9gnKAYSQ&#39;;return true;">http://wakened-cognition.blogspot.com/

My Technical Scribbings @ <a href="http://rationaleemotions.wordpress.com/" target="_blank" rel="nofollow" onmousedown="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Frationaleemotions.wordpress.com%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNEcBOKyRn0lpL8LDbBuyAlKdwgXwQ&#39;;return true;" onclick="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Frationaleemotions.wordpress.com%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNEcBOKyRn0lpL8LDbBuyAlKdwgXwQ&#39;;return true;">http://rationaleemotions.wordpress.com/

 

From: <<a href="javascript:" target="_blank" gdf-obfuscated-mailto="JQxQiYFPDAAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">testng...@...> on behalf of prvn <<a href="javascript:" target="_blank" gdf-obfuscated-mailto="JQxQiYFPDAAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">neevar...@...>
Reply-To: <<a href="javascript:" target="_blank" gdf-obfuscated-mailto="JQxQiYFPDAAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">testng...@...>
Date: Tuesday, December 19, 2017 at 6:10 AM
To: testng-users <<a href="javascript:" target="_blank" gdf-obfuscated-mailto="JQxQiYFPDAAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">testng...@...>
Subject: [testng-users] Is this how IInvokedMethodListener supposed to work?

 

I have a test class as below

 

@Listeners(com.testng.test.TestListener.class)

public class TestClass {

 

    @Test

    public void testMethod() {

        ReportImpl report = new ReportImpl();

        report.populateMap();

    }

}

 

Then I have a `ReportImpl` class as below

 

public class ReportImpl {

 

    Map<String, String> reportMap = new HashMap<String, String>();

 

    public void populateMap() {

        reportMap.put("google", "alphabet");

        reportMap.put("bing", "Microsoft");

        reportMap.put("iOS", "apple");

    }

 

    public void getDataFromMap() {

        String google = reportMap.get("google");

        String ms = reportMap.get("bing");

        System.out.println(google + ms);

    }

}

 

 

Now I have a listener called `TestListener` which is implements `IInvokedMethodListener` as below

 

public class TestListener implements IInvokedMethodListener {

 

    @Override

    public void beforeInvocation(IInvokedMethod method, ITestResult testResult) {

        ReportImpl report = new ReportImpl();

        Reporter.getCurrentTestResult()

                .setAttribute("REPORT_DATA", report);

 

    }

 

    @Override

    public void afterInvocation(IInvokedMethod method, ITestResult testResult) {

        ReportImpl report = (ReportImpl) Reporter.getCurrentTestResult()

                                                 .getAttribute("REPORT_DATA");

        report.getDataFromMap();

 

    }

}

 

Now the question is in the `afterInvocation` I'm doing `report.getDataFromMap()` which in turn get's data from `ReportImp` class. Unfortunately `reportMap` is null because for some reasons the key/value that was put into this `reportMap` has been lost when the control was passed to `afterInvocation`. 

 

But when I make the `reportMap` to static it perfectly works fine. Is this how it's supposed to work? What would be the side effect for having `static` map when tests are run in parallel?

--
You received this message because you are subscribed to the Google Groups "testng-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to <a href="javascript:" target="_blank" gdf-obfuscated-mailto="JQxQiYFPDAAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">testng-users...@googlegroups.com.
To post to this group, send email to <a href="javascript:" target="_blank" gdf-obfuscated-mailto="JQxQiYFPDAAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">testng...@....
Visit this group at <a href="https://groups.google.com/group/testng-users" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://groups.google.com/group/testng-users&#39;;return true;" onclick="this.href=&#39;https://groups.google.com/group/testng-users&#39;;return true;">https://groups.google.com/group/testng-users.
For more options, visit <a href="https://groups.google.com/d/optout" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://groups.google.com/d/optout&#39;;return true;" onclick="this.href=&#39;https://groups.google.com/d/optout&#39;;return true;">https://groups.google.com/d/optout.


--
You received this message because you are subscribed to the Google Groups "testng-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/testng-users.
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Is this how IInvokedMethodListener supposed to work?

Krishnan Mahadevan

Comments inline.

 

All said and done, what are you trying to solve? Can you please elaborate?

 

Thanks & Regards

Krishnan Mahadevan

 

"All the desirable things in life are either illegal, expensive, fattening or in love with someone else!"

My Scribblings @ http://wakened-cognition.blogspot.com/

My Technical Scribbings @ http://rationaleemotions.wordpress.com/

 

From: <[hidden email]> on behalf of prvn <[hidden email]>
Reply-To: <[hidden email]>
Date: Tuesday, December 19, 2017 at 8:01 AM
To: testng-users <[hidden email]>
Subject: Re: [testng-users] Is this how IInvokedMethodListener supposed to work?

 

Thanks Krishnan. I tried that and it worked for me. But two questions

 

  1. Is static field (In ReportImpl class) going to have a side effect when tests are executed in parallel?

[Krishnan] Yes and No. It all depends on what you are trying to do with the map. But in general if you are going to be both writing and reading from the map at the same time, then static maps are going to be an issue.

 

  1. I really cannot have Reporter.getCurrentTestResult().setAttribute("REPORT_DATA", report); in my test case. Is there any other way to persist the object through afterInvocation?

[Krishnan] You either do that, or you have your beforeInvocation() take care of initializing everything and then your afterInvocation() reading data. That means your @Test method does nothing to do the map. You obviously would need to query the map in some manner no ? Either you do it via an attribute setting in the ITestResult object or you make use of ThreadLocal.




On Monday, December 18, 2017 at 9:21:35 PM UTC-5, Krishnan Mahadevan wrote:

Including the correct TestClass version

 

@Listeners(TestListener.class)
public class TestClass {

   
@Test
   
public void testMethod() {
        ReportImpl report = (ReportImpl) Reporter.getCurrentTestResult().getAttribute(
"REPORT_DATA");
        report.populateMap();
        Reporter.getCurrentTestResult().setAttribute(
"REPORT_DATA", report);
    }
}

 

 

Thanks & Regards

Krishnan Mahadevan

 

"All the desirable things in life are either illegal, expensive, fattening or in love with someone else!"

My Scribblings @ http://wakened-cognition.blogspot.com/

My Technical Scribbings @ http://rationaleemotions.wordpress.com/

 

From: Krishnan Mahadevan <<a href="javascript:" target="_blank">krishnan.ma...@...>
Date: Tuesday, December 19, 2017 at 7:48 AM
To: <<a href="javascript:" target="_blank">testng...@...>
Subject: Re: [testng-users] Is this how IInvokedMethodListener supposed to work?

 

Praveen,

 

>>>> Now the question is in the `afterInvocation` I'm doing `report.getDataFromMap()` which in turn get's data from `ReportImp` class. Unfortunately `reportMap` is null because for some reasons the key/value that was put into this `reportMap` has been lost when the control was passed to `afterInvocation`. 

 

This is because, from within beforeInvocation() you are invoking Reporter.getCurrentTestResult() which is going to fetch the ITestResult object associated with “beforeInvocation()” now when you enter the @Test method, the ITestResult object of the current test method is what gets popped out when you do a Reporter.getCurrentTestResult(). And when you are entering your afterInvocation(), since its still on the same thread [ only beforeInvocation() > @Test > afterInvocation()  are guaranteed to run on the same thread ] you get the ITestResult object which doesn’t have what was persisted via the setAttribute() method.

 

I am guessing that perhaps the following changed code is what you need.

 

import org.testng.Reporter;
import org.testng.annotations.Listeners;
import org.testng.annotations.Test;

@Listeners(TestListener.class)
public class TestClass {

   
@Test
   
public void testMethod() {
        ReportImpl report =
new ReportImpl();
        report.populateMap();
        Reporter.getCurrentTestResult().setAttribute(
"REPORT_DATA", report);
    }
}

 

import java.util.HashMap;
import java.util.Map;

public class ReportImpl {

    Map<String, String>
reportMap = new HashMap<String, String>();

   
public void populateMap() {
       
reportMap.put("google", "alphabet");
       
reportMap.put("bing", "Microsoft");
       
reportMap.put("iOS", "apple");
    }

   
public void getDataFromMap() {
        String google =
reportMap.get("google");
        String ms =
reportMap.get("bing");
        System.
err.println(google + ms);
    }
}

 

import org.testng.IInvokedMethod;
import org.testng.IInvokedMethodListener;
import org.testng.ITestResult;

public class TestListener implements IInvokedMethodListener {

   
@Override
   
public void beforeInvocation(IInvokedMethod method, ITestResult testResult) {
        ReportImpl report =
new ReportImpl();
        testResult.setAttribute(
"REPORT_DATA", report);

    }

   
@Override
   
public void afterInvocation(IInvokedMethod method, ITestResult testResult) {
        ReportImpl report = (ReportImpl) testResult.getAttribute(
"REPORT_DATA");
        report.getDataFromMap();

    }
}

 

Output:

 

alphabetMicrosoft

 

===============================================

Default Suite

Total tests run: 1, Failures: 0, Skips: 0

===============================================

 

 

Process finished with exit code 0

 

 

 

 

Thanks & Regards

Krishnan Mahadevan

 

"All the desirable things in life are either illegal, expensive, fattening or in love with someone else!"

My Scribblings @ http://wakened-cognition.blogspot.com/

My Technical Scribbings @ http://rationaleemotions.wordpress.com/

 

From: <<a href="javascript:" target="_blank">testng...@...> on behalf of prvn <<a href="javascript:" target="_blank">neevar...@...>
Reply-To: <<a href="javascript:" target="_blank">testng...@...>
Date: Tuesday, December 19, 2017 at 6:10 AM
To: testng-users <<a href="javascript:" target="_blank">testng...@...>
Subject: [testng-users] Is this how IInvokedMethodListener supposed to work?

 

I have a test class as below

 

@Listeners(com.testng.test.TestListener.class)

public class TestClass {

 

    @Test

    public void testMethod() {

        ReportImpl report = new ReportImpl();

        report.populateMap();

    }

}

 

Then I have a `ReportImpl` class as below

 

public class ReportImpl {

 

    Map<String, String> reportMap = new HashMap<String, String>();

 

    public void populateMap() {

        reportMap.put("google", "alphabet");

        reportMap.put("bing", "Microsoft");

        reportMap.put("iOS", "apple");

    }

 

    public void getDataFromMap() {

        String google = reportMap.get("google");

        String ms = reportMap.get("bing");

        System.out.println(google + ms);

    }

}

 

 

Now I have a listener called `TestListener` which is implements `IInvokedMethodListener` as below

 

public class TestListener implements IInvokedMethodListener {

 

    @Override

    public void beforeInvocation(IInvokedMethod method, ITestResult testResult) {

        ReportImpl report = new ReportImpl();

        Reporter.getCurrentTestResult()

                .setAttribute("REPORT_DATA", report);

 

    }

 

    @Override

    public void afterInvocation(IInvokedMethod method, ITestResult testResult) {

        ReportImpl report = (ReportImpl) Reporter.getCurrentTestResult()

                                                 .getAttribute("REPORT_DATA");

        report.getDataFromMap();

 

    }

}

 

Now the question is in the `afterInvocation` I'm doing `report.getDataFromMap()` which in turn get's data from `ReportImp` class. Unfortunately `reportMap` is null because for some reasons the key/value that was put into this `reportMap` has been lost when the control was passed to `afterInvocation`. 

 

But when I make the `reportMap` to static it perfectly works fine. Is this how it's supposed to work? What would be the side effect for having `static` map when tests are run in parallel?

--
You received this message because you are subscribed to the Google Groups "testng-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to <a href="javascript:" target="_blank">testng-users...@....
To post to this group, send email to <a href="javascript:" target="_blank">testng...@....
Visit this group at https://groups.google.com/group/testng-users.
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "testng-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/testng-users.
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "testng-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/testng-users.
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Is this how IInvokedMethodListener supposed to work?

SUBRAMANYESWARA RAO BHAVIRISETTY
In reply to this post by praveen133t
Agreed and thanks to Krishnan for fixing actual issue.

Subramanyam 

On Monday, December 18, 2017, prvn <[hidden email]> wrote:
Sorry.. This is no where close to reporting. 

On Monday, December 18, 2017 at 9:09:58 PM UTC-5, SUBRAMANYESWARA RAO BHAVIRISETTY wrote:
I generally use reportng for the test reporting by configuring it as a listener in pom.

http://www.seleniumeasy.com/testng-tutorials/configuring-reportng-with-testng-to-generate-html-reports

Anything you want to log can be done in Reporter.log and it would get logged on the screen . https://jitpack.io/com/github/cbeust/testng/master-6.13.1-gf634d0a-4/javadoc/org/testng/Reporter.html has more details. Reporter class is definitely threadsafe.

Jenkins takes care of archiving the html reports.

Subramanyam



On Mon, Dec 18, 2017 at 6:01 PM, prvn <[hidden email]> wrote:
@Subramanyaeswara: I don't want to share same data across multiple tests. This is just an example. But imagine the "ReportImpl" class carries some information about the test itself. So it's unique data.

On Monday, December 18, 2017 at 8:58:32 PM UTC-5, SUBRAMANYESWARA RAO BHAVIRISETTY wrote:
If you declare it as static, the value will be retained across the invocations.  I guess static hashmaps are not thread safe. Please take a look at this link:
http://www.asjava.com/core-java/thread-safe-hash-map-in-java-and-their-performance-benchmark/

Just wanted to know why you wanted to share the same data structure across multiple tests.




On Mon, Dec 18, 2017 at 4:40 PM, prvn <[hidden email]> wrote:
I have a test class as below

@Listeners(com.testng.test.TestListener.class)

public class TestClass {


    @Test

    public void testMethod() {

        ReportImpl report = new ReportImpl();

        report.populateMap();

    }

}


Then I have a `ReportImpl` class as below


public class ReportImpl {


    Map<String, String> reportMap = new HashMap<String, String>();


    public void populateMap() {

        reportMap.put("google", "alphabet");

        reportMap.put("bing", "Microsoft");

        reportMap.put("iOS", "apple");

    }


    public void getDataFromMap() {

        String google = reportMap.get("google");

        String ms = reportMap.get("bing");

        System.out.println(google + ms);

    }

}



Now I have a listener called `TestListener` which is implements `IInvokedMethodListener` as below


public class TestListener implements IInvokedMethodListener {


    @Override

    public void beforeInvocation(IInvokedMethod method, ITestResult testResult) {

        ReportImpl report = new ReportImpl();

        Reporter.getCurrentTestResult()

                .setAttribute("REPORT_DATA", report);


    }


    @Override

    public void afterInvocation(IInvokedMethod method, ITestResult testResult) {

        ReportImpl report = (ReportImpl) Reporter.getCurrentTestResult()

                                                 .getAttribute("REPORT_DATA");

        report.getDataFromMap();


    }

}


Now the question is in the `afterInvocation` I'm doing `report.getDataFromMap()` which in turn get's data from `ReportImp` class. Unfortunately `reportMap` is null because for some reasons the key/value that was put into this `reportMap` has been lost when the control was passed to `afterInvocation`. 


But when I make the `reportMap` to static it perfectly works fine. Is this how it's supposed to work? What would be the side effect for having `static` map when tests are run in parallel?

--
You received this message because you are subscribed to the Google Groups "testng-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email]om.
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/testng-users.
For more options, visit https://groups.google.com/d/optout.



--
Subramanyam

--
You received this message because you are subscribed to the Google Groups "testng-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to testng-users...@googlegroups.com.
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/testng-users.
For more options, visit https://groups.google.com/d/optout.



--
Subramanyam

--
You received this message because you are subscribed to the Google Groups "testng-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/testng-users.
For more options, visit https://groups.google.com/d/optout.


--
Subramanyam

--
You received this message because you are subscribed to the Google Groups "testng-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/testng-users.
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Is this how IInvokedMethodListener supposed to work?

praveen133t
In reply to this post by Krishnan Mahadevan
Sure. Would be glad to explain what I'm trying to do.

1. Let's say I have 10 tests in my suite
2. There are only one @Test in each of these test classes
3. Each @Test is a selenium webdriver test
4. While each of these tests are running, It will fetch some data from the website and store it in the aforementioned `Map<String, String>`. 
5. After the test is done I want to read the `Map` in the `afterInvocation` and then do some processing for each @Test. 

I'm so focussed on afterInvocation because of it being part of a listener and listeners are way too convenient to manage and not clumsy. 

On Monday, December 18, 2017 at 9:37:00 PM UTC-5, Krishnan Mahadevan wrote:

Comments inline.

 

All said and done, what are you trying to solve? Can you please elaborate?

 

Thanks & Regards

Krishnan Mahadevan

 

"All the desirable things in life are either illegal, expensive, fattening or in love with someone else!"

My Scribblings @ <a href="http://wakened-cognition.blogspot.com/" target="_blank" rel="nofollow" onmousedown="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fwakened-cognition.blogspot.com%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHzOdYJCASIDF_28vQtkp9gnKAYSQ&#39;;return true;" onclick="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fwakened-cognition.blogspot.com%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHzOdYJCASIDF_28vQtkp9gnKAYSQ&#39;;return true;">http://wakened-cognition.blogspot.com/

My Technical Scribbings @ <a href="http://rationaleemotions.wordpress.com/" target="_blank" rel="nofollow" onmousedown="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Frationaleemotions.wordpress.com%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNEcBOKyRn0lpL8LDbBuyAlKdwgXwQ&#39;;return true;" onclick="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Frationaleemotions.wordpress.com%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNEcBOKyRn0lpL8LDbBuyAlKdwgXwQ&#39;;return true;">http://rationaleemotions.wordpress.com/

 

From: <<a href="javascript:" target="_blank" gdf-obfuscated-mailto="fFBXylhQDAAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">testng...@...> on behalf of prvn <<a href="javascript:" target="_blank" gdf-obfuscated-mailto="fFBXylhQDAAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">neevar...@...>
Reply-To: <<a href="javascript:" target="_blank" gdf-obfuscated-mailto="fFBXylhQDAAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">testng...@...>
Date: Tuesday, December 19, 2017 at 8:01 AM
To: testng-users <<a href="javascript:" target="_blank" gdf-obfuscated-mailto="fFBXylhQDAAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">testng...@...>
Subject: Re: [testng-users] Is this how IInvokedMethodListener supposed to work?

 

Thanks Krishnan. I tried that and it worked for me. But two questions

 

  1. Is static field (In ReportImpl class) going to have a side effect when tests are executed in parallel?

[Krishnan] Yes and No. It all depends on what you are trying to do with the map. But in general if you are going to be both writing and reading from the map at the same time, then static maps are going to be an issue.

 

  1. I really cannot have Reporter.getCurrentTestResult().setAttribute("REPORT_DATA", report); in my test case. Is there any other way to persist the object through afterInvocation?

[Krishnan] You either do that, or you have your beforeInvocation() take care of initializing everything and then your afterInvocation() reading data. That means your @Test method does nothing to do the map. You obviously would need to query the map in some manner no ? Either you do it via an attribute setting in the ITestResult object or you make use of ThreadLocal.




On Monday, December 18, 2017 at 9:21:35 PM UTC-5, Krishnan Mahadevan wrote:

Including the correct TestClass version

 

@Listeners(TestListener.class)
public class TestClass {

   
@Test
   
public void testMethod() {
        ReportImpl report = (ReportImpl) Reporter.getCurrentTestResult().getAttribute(
"REPORT_DATA");
        report.populateMap();
        Reporter.getCurrentTestResult().setAttribute(
"REPORT_DATA", report);
    }
}

 

 

Thanks & Regards

Krishnan Mahadevan

 

"All the desirable things in life are either illegal, expensive, fattening or in love with someone else!"

My Scribblings @ <a href="http://wakened-cognition.blogspot.com/" target="_blank" rel="nofollow" onmousedown="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fwakened-cognition.blogspot.com%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHzOdYJCASIDF_28vQtkp9gnKAYSQ&#39;;return true;" onclick="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fwakened-cognition.blogspot.com%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHzOdYJCASIDF_28vQtkp9gnKAYSQ&#39;;return true;">http://wakened-cognition.blogspot.com/

My Technical Scribbings @ <a href="http://rationaleemotions.wordpress.com/" target="_blank" rel="nofollow" onmousedown="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Frationaleemotions.wordpress.com%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNEcBOKyRn0lpL8LDbBuyAlKdwgXwQ&#39;;return true;" onclick="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Frationaleemotions.wordpress.com%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNEcBOKyRn0lpL8LDbBuyAlKdwgXwQ&#39;;return true;">http://rationaleemotions.wordpress.com/

 

From: Krishnan Mahadevan <[hidden email]>
Date: Tuesday, December 19, 2017 at 7:48 AM
To: <[hidden email]>
Subject: Re: [testng-users] Is this how IInvokedMethodListener supposed to work?

 

Praveen,

 

>>>> Now the question is in the `afterInvocation` I'm doing `report.getDataFromMap()` which in turn get's data from `ReportImp` class. Unfortunately `reportMap` is null because for some reasons the key/value that was put into this `reportMap` has been lost when the control was passed to `afterInvocation`. 

 

This is because, from within beforeInvocation() you are invoking Reporter.getCurrentTestResult() which is going to fetch the ITestResult object associated with “beforeInvocation()” now when you enter the @Test method, the ITestResult object of the current test method is what gets popped out when you do a Reporter.getCurrentTestResult(). And when you are entering your afterInvocation(), since its still on the same thread [ only beforeInvocation() > @Test > afterInvocation()  are guaranteed to run on the same thread ] you get the ITestResult object which doesn’t have what was persisted via the setAttribute() method.

 

I am guessing that perhaps the following changed code is what you need.

 

import org.testng.Reporter;
import org.testng.annotations.Listeners;
import org.testng.annotations.Test;

@Listeners(TestListener.class)
public class TestClass {

   
@Test
   
public void testMethod() {
        ReportImpl report =
new ReportImpl();
        report.populateMap();
        Reporter.getCurrentTestResult().setAttribute(
"REPORT_DATA", report);
    }
}

 

import java.util.HashMap;
import java.util.Map;

public class ReportImpl {

    Map<String, String>
reportMap = new HashMap<String, String>();

   
public void populateMap() {
       
reportMap.put("google", "alphabet");
       
reportMap.put("bing", "Microsoft");
       
reportMap.put("iOS", "apple");
    }

   
public void getDataFromMap() {
        String google =
reportMap.get("google");
        String ms =
reportMap.get("bing");
        System.
err.println(google + ms);
    }
}

 

import org.testng.IInvokedMethod;
import org.testng.IInvokedMethodListener;
import org.testng.ITestResult;

public class TestListener implements IInvokedMethodListener {

   
@Override
   
public void beforeInvocation(IInvokedMethod method, ITestResult testResult) {
        ReportImpl report =
new ReportImpl();
        testResult.setAttribute(
"REPORT_DATA", report);

    }

   
@Override
   
public void afterInvocation(IInvokedMethod method, ITestResult testResult) {
        ReportImpl report = (ReportImpl) testResult.getAttribute(
"REPORT_DATA");
        report.getDataFromMap();

    }
}

 

Output:

 

alphabetMicrosoft

 

===============================================

Default Suite

Total tests run: 1, Failures: 0, Skips: 0

===============================================

 

 

Process finished with exit code 0

 

 

 

 

Thanks & Regards

Krishnan Mahadevan

 

"All the desirable things in life are either illegal, expensive, fattening or in love with someone else!"

My Scribblings @ <a href="http://wakened-cognition.blogspot.com/" target="_blank" rel="nofollow" onmousedown="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fwakened-cognition.blogspot.com%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHzOdYJCASIDF_28vQtkp9gnKAYSQ&#39;;return true;" onclick="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fwakened-cognition.blogspot.com%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHzOdYJCASIDF_28vQtkp9gnKAYSQ&#39;;return true;">http://wakened-cognition.blogspot.com/

My Technical Scribbings @ <a href="http://rationaleemotions.wordpress.com/" target="_blank" rel="nofollow" onmousedown="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Frationaleemotions.wordpress.com%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNEcBOKyRn0lpL8LDbBuyAlKdwgXwQ&#39;;return true;" onclick="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Frationaleemotions.wordpress.com%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNEcBOKyRn0lpL8LDbBuyAlKdwgXwQ&#39;;return true;">http://rationaleemotions.wordpress.com/

 

From: <[hidden email]> on behalf of prvn <[hidden email]>
Reply-To: <[hidden email]>
Date: Tuesday, December 19, 2017 at 6:10 AM
To: testng-users <[hidden email]>
Subject: [testng-users] Is this how IInvokedMethodListener supposed to work?

 

I have a test class as below

 

@Listeners(com.testng.test.TestListener.class)

public class TestClass {

 

    @Test

    public void testMethod() {

        ReportImpl report = new ReportImpl();

        report.populateMap();

    }

}

 

Then I have a `ReportImpl` class as below

 

public class ReportImpl {

 

    Map<String, String> reportMap = new HashMap<String, String>();

 

    public void populateMap() {

        reportMap.put("google", "alphabet");

        reportMap.put("bing", "Microsoft");

        reportMap.put("iOS", "apple");

    }

 

    public void getDataFromMap() {

        String google = reportMap.get("google");

        String ms = reportMap.get("bing");

        System.out.println(google + ms);

    }

}

 

 

Now I have a listener called `TestListener` which is implements `IInvokedMethodListener` as below

 

public class TestListener implements IInvokedMethodListener {

 

    @Override

    public void beforeInvocation(IInvokedMethod method, ITestResult testResult) {

        ReportImpl report = new ReportImpl();

        Reporter.getCurrentTestResult()

                .setAttribute("REPORT_DATA", report);

 

    }

 

    @Override

    public void afterInvocation(IInvokedMethod method, ITestResult testResult) {

        ReportImpl report = (ReportImpl) Reporter.getCurrentTestResult()

                                                 .getAttribute("REPORT_DATA");

        report.getDataFromMap();

 

    }

}

 

Now the question is in the `afterInvocation` I'm doing `report.getDataFromMap()` which in turn get's data from `ReportImp` class. Unfortunately `reportMap` is null because for some reasons the key/value that was put into this `reportMap` has been lost when the control was passed to `afterInvocation`. 

 

But when I make the `reportMap` to static it perfectly works fine. Is this how it's supposed to work? What would be the side effect for having `static` map when tests are run in parallel?

--
You received this message because you are subscribed to the Google Groups "testng-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to testng-users...@googlegroups.com.
To post to this group, send email to [hidden email].
Visit this group at <a href="https://groups.google.com/group/testng-users" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://groups.google.com/group/testng-users&#39;;return true;" onclick="this.href=&#39;https://groups.google.com/group/testng-users&#39;;return true;">https://groups.google.com/group/testng-users.
For more options, visit <a href="https://groups.google.com/d/optout" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://groups.google.com/d/optout&#39;;return true;" onclick="this.href=&#39;https://groups.google.com/d/optout&#39;;return true;">https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "testng-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to <a href="javascript:" target="_blank" gdf-obfuscated-mailto="fFBXylhQDAAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">testng-users...@googlegroups.com.
To post to this group, send email to <a href="javascript:" target="_blank" gdf-obfuscated-mailto="fFBXylhQDAAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">testng...@....
Visit this group at <a href="https://groups.google.com/group/testng-users" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://groups.google.com/group/testng-users&#39;;return true;" onclick="this.href=&#39;https://groups.google.com/group/testng-users&#39;;return true;">https://groups.google.com/group/testng-users.
For more options, visit <a href="https://groups.google.com/d/optout" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://groups.google.com/d/optout&#39;;return true;" onclick="this.href=&#39;https://groups.google.com/d/optout&#39;;return true;">https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "testng-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/testng-users.
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Is this how IInvokedMethodListener supposed to work?

Krishnan Mahadevan

Great. That makes sense!

 

Just to re-iterate, you have only one of the following three options.

 

  1. Use the solution that I shared on an as-is basis [ But guess you aren’t ready for that]
  2. Leverage IHookable by doing the following:
    1. Build a base class which implements the IHookable interface. When you do this, TestNG will indirectly invoke your @Test methods via the run() of your base class. So, it’s kind of like a proxy to your actual test method invocation.
    2. Within org.testng.IHookable#run implement the logic of extracting your ReportImpl object from the current ITestResult object [ you have access to it in the run() method], do the data fetch from website, persist it back to the ITestResult object
  3. Leverage ThreadLocal, so that every thread gets its own copy of the ReportImpl object [ and thus the map as well] and you don’t have to worry about Thread safety.

 

Thanks & Regards

Krishnan Mahadevan

 

"All the desirable things in life are either illegal, expensive, fattening or in love with someone else!"

My Scribblings @ http://wakened-cognition.blogspot.com/

My Technical Scribbings @ http://rationaleemotions.wordpress.com/

 

From: <[hidden email]> on behalf of prvn <[hidden email]>
Reply-To: <[hidden email]>
Date: Tuesday, December 19, 2017 at 8:19 AM
To: testng-users <[hidden email]>
Subject: Re: [testng-users] Is this how IInvokedMethodListener supposed to work?

 

Sure. Would be glad to explain what I'm trying to do.

 

1. Let's say I have 10 tests in my suite

2. There are only one @Test in each of these test classes

3. Each @Test is a selenium webdriver test

4. While each of these tests are running, It will fetch some data from the website and store it in the aforementioned `Map<String, String>`. 

5. After the test is done I want to read the `Map` in the `afterInvocation` and then do some processing for each @Test. 

 

I'm so focussed on afterInvocation because of it being part of a listener and listeners are way too convenient to manage and not clumsy. 

On Monday, December 18, 2017 at 9:37:00 PM UTC-5, Krishnan Mahadevan wrote:

Comments inline.

 

All said and done, what are you trying to solve? Can you please elaborate?

 

Thanks & Regards

Krishnan Mahadevan

 

"All the desirable things in life are either illegal, expensive, fattening or in love with someone else!"

My Scribblings @ http://wakened-cognition.blogspot.com/

My Technical Scribbings @ http://rationaleemotions.wordpress.com/

 

From: <<a href="javascript:" target="_blank">testng...@...> on behalf of prvn <<a href="javascript:" target="_blank">neevar...@...>
Reply-To: <<a href="javascript:" target="_blank">testng...@...>
Date: Tuesday, December 19, 2017 at 8:01 AM
To: testng-users <<a href="javascript:" target="_blank">testng...@...>
Subject: Re: [testng-users] Is this how IInvokedMethodListener supposed to work?

 

Thanks Krishnan. I tried that and it worked for me. But two questions

 

  1. Is static field (In ReportImpl class) going to have a side effect when tests are executed in parallel?

[Krishnan] Yes and No. It all depends on what you are trying to do with the map. But in general if you are going to be both writing and reading from the map at the same time, then static maps are going to be an issue.

 

  1. I really cannot have Reporter.getCurrentTestResult().setAttribute("REPORT_DATA", report); in my test case. Is there any other way to persist the object through afterInvocation?

[Krishnan] You either do that, or you have your beforeInvocation() take care of initializing everything and then your afterInvocation() reading data. That means your @Test method does nothing to do the map. You obviously would need to query the map in some manner no ? Either you do it via an attribute setting in the ITestResult object or you make use of ThreadLocal.




On Monday, December 18, 2017 at 9:21:35 PM UTC-5, Krishnan Mahadevan wrote:

Including the correct TestClass version

 

@Listeners(TestListener.class)
public class TestClass {

   
@Test
   
public void testMethod() {
        ReportImpl report = (ReportImpl) Reporter.getCurrentTestResult().getAttribute(
"REPORT_DATA");
        report.populateMap();
        Reporter.getCurrentTestResult().setAttribute(
"REPORT_DATA", report);
    }
}

 

 

Thanks & Regards

Krishnan Mahadevan

 

"All the desirable things in life are either illegal, expensive, fattening or in love with someone else!"

My Scribblings @ http://wakened-cognition.blogspot.com/

My Technical Scribbings @ http://rationaleemotions.wordpress.com/

 

From: Krishnan Mahadevan <[hidden email]>
Date: Tuesday, December 19, 2017 at 7:48 AM
To: <[hidden email]>
Subject: Re: [testng-users] Is this how IInvokedMethodListener supposed to work?

 

Praveen,

 

>>>> Now the question is in the `afterInvocation` I'm doing `report.getDataFromMap()` which in turn get's data from `ReportImp` class. Unfortunately `reportMap` is null because for some reasons the key/value that was put into this `reportMap` has been lost when the control was passed to `afterInvocation`. 

 

This is because, from within beforeInvocation() you are invoking Reporter.getCurrentTestResult() which is going to fetch the ITestResult object associated with “beforeInvocation()” now when you enter the @Test method, the ITestResult object of the current test method is what gets popped out when you do a Reporter.getCurrentTestResult(). And when you are entering your afterInvocation(), since its still on the same thread [ only beforeInvocation() > @Test > afterInvocation()  are guaranteed to run on the same thread ] you get the ITestResult object which doesn’t have what was persisted via the setAttribute() method.

 

I am guessing that perhaps the following changed code is what you need.

 

import org.testng.Reporter;
import org.testng.annotations.Listeners;
import org.testng.annotations.Test;

@Listeners(TestListener.class)
public class TestClass {

   
@Test
   
public void testMethod() {
        ReportImpl report =
new ReportImpl();
        report.populateMap();
        Reporter.getCurrentTestResult().setAttribute(
"REPORT_DATA", report);
    }
}

 

import java.util.HashMap;
import java.util.Map;

public class ReportImpl {

    Map<String, String>
reportMap = new HashMap<String, String>();

   
public void populateMap() {
       
reportMap.put("google", "alphabet");
       
reportMap.put("bing", "Microsoft");
       
reportMap.put("iOS", "apple");
    }

   
public void getDataFromMap() {
        String google =
reportMap.get("google");
        String ms =
reportMap.get("bing");
        System.
err.println(google + ms);
    }
}

 

import org.testng.IInvokedMethod;
import org.testng.IInvokedMethodListener;
import org.testng.ITestResult;

public class TestListener implements IInvokedMethodListener {

   
@Override
   
public void beforeInvocation(IInvokedMethod method, ITestResult testResult) {
        ReportImpl report =
new ReportImpl();
        testResult.setAttribute(
"REPORT_DATA", report);

    }

   
@Override
   
public void afterInvocation(IInvokedMethod method, ITestResult testResult) {
        ReportImpl report = (ReportImpl) testResult.getAttribute(
"REPORT_DATA");
        report.getDataFromMap();

    }
}

 

Output:

 

alphabetMicrosoft

 

===============================================

Default Suite

Total tests run: 1, Failures: 0, Skips: 0

===============================================

 

 

Process finished with exit code 0

 

 

 

 

Thanks & Regards

Krishnan Mahadevan

 

"All the desirable things in life are either illegal, expensive, fattening or in love with someone else!"

My Scribblings @ http://wakened-cognition.blogspot.com/

My Technical Scribbings @ http://rationaleemotions.wordpress.com/

 

From: <[hidden email]> on behalf of prvn <[hidden email]>
Reply-To: <[hidden email]>
Date: Tuesday, December 19, 2017 at 6:10 AM
To: testng-users <[hidden email]>
Subject: [testng-users] Is this how IInvokedMethodListener supposed to work?

 

I have a test class as below

 

@Listeners(com.testng.test.TestListener.class)

public class TestClass {

 

    @Test

    public void testMethod() {

        ReportImpl report = new ReportImpl();

        report.populateMap();

    }

}

 

Then I have a `ReportImpl` class as below

 

public class ReportImpl {

 

    Map<String, String> reportMap = new HashMap<String, String>();

 

    public void populateMap() {

        reportMap.put("google", "alphabet");

        reportMap.put("bing", "Microsoft");

        reportMap.put("iOS", "apple");

    }

 

    public void getDataFromMap() {

        String google = reportMap.get("google");

        String ms = reportMap.get("bing");

        System.out.println(google + ms);

    }

}

 

 

Now I have a listener called `TestListener` which is implements `IInvokedMethodListener` as below

 

public class TestListener implements IInvokedMethodListener {

 

    @Override

    public void beforeInvocation(IInvokedMethod method, ITestResult testResult) {

        ReportImpl report = new ReportImpl();

        Reporter.getCurrentTestResult()

                .setAttribute("REPORT_DATA", report);

 

    }

 

    @Override

    public void afterInvocation(IInvokedMethod method, ITestResult testResult) {

        ReportImpl report = (ReportImpl) Reporter.getCurrentTestResult()

                                                 .getAttribute("REPORT_DATA");

        report.getDataFromMap();

 

    }

}

 

Now the question is in the `afterInvocation` I'm doing `report.getDataFromMap()` which in turn get's data from `ReportImp` class. Unfortunately `reportMap` is null because for some reasons the key/value that was put into this `reportMap` has been lost when the control was passed to `afterInvocation`. 

 

But when I make the `reportMap` to static it perfectly works fine. Is this how it's supposed to work? What would be the side effect for having `static` map when tests are run in parallel?

--
You received this message because you are subscribed to the Google Groups "testng-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/testng-users.
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "testng-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to <a href="javascript:" target="_blank">testng-users...@....
To post to this group, send email to <a href="javascript:" target="_blank">testng...@....
Visit this group at https://groups.google.com/group/testng-users.
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "testng-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/testng-users.
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "testng-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/testng-users.
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Is this how IInvokedMethodListener supposed to work?

praveen133t
Thanks Krishnan.

#3 is easy to implement. I will go with that. Thanks a lot once again.

On Monday, December 18, 2017 at 9:56:25 PM UTC-5, Krishnan Mahadevan wrote:

Great. That makes sense!

 

Just to re-iterate, you have only one of the following three options.

 

  1. Use the solution that I shared on an as-is basis [ But guess you aren’t ready for that]
  2. Leverage IHookable by doing the following:
    1. Build a base class which implements the IHookable interface. When you do this, TestNG will indirectly invoke your @Test methods via the run() of your base class. So, it’s kind of like a proxy to your actual test method invocation.
    2. Within org.testng.IHookable#run implement the logic of extracting your ReportImpl object from the current ITestResult object [ you have access to it in the run() method], do the data fetch from website, persist it back to the ITestResult object
  3. Leverage ThreadLocal, so that every thread gets its own copy of the ReportImpl object [ and thus the map as well] and you don’t have to worry about Thread safety.

 

Thanks & Regards

Krishnan Mahadevan

 

"All the desirable things in life are either illegal, expensive, fattening or in love with someone else!"

My Scribblings @ <a href="http://wakened-cognition.blogspot.com/" target="_blank" rel="nofollow" onmousedown="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fwakened-cognition.blogspot.com%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHzOdYJCASIDF_28vQtkp9gnKAYSQ&#39;;return true;" onclick="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fwakened-cognition.blogspot.com%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHzOdYJCASIDF_28vQtkp9gnKAYSQ&#39;;return true;">http://wakened-cognition.blogspot.com/

My Technical Scribbings @ <a href="http://rationaleemotions.wordpress.com/" target="_blank" rel="nofollow" onmousedown="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Frationaleemotions.wordpress.com%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNEcBOKyRn0lpL8LDbBuyAlKdwgXwQ&#39;;return true;" onclick="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Frationaleemotions.wordpress.com%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNEcBOKyRn0lpL8LDbBuyAlKdwgXwQ&#39;;return true;">http://rationaleemotions.wordpress.com/

 

From: <<a href="javascript:" target="_blank" gdf-obfuscated-mailto="bYTYMGhRDAAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">testng...@...> on behalf of prvn <<a href="javascript:" target="_blank" gdf-obfuscated-mailto="bYTYMGhRDAAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">neevar...@...>
Reply-To: <<a href="javascript:" target="_blank" gdf-obfuscated-mailto="bYTYMGhRDAAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">testng...@...>
Date: Tuesday, December 19, 2017 at 8:19 AM
To: testng-users <<a href="javascript:" target="_blank" gdf-obfuscated-mailto="bYTYMGhRDAAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">testng...@...>
Subject: Re: [testng-users] Is this how IInvokedMethodListener supposed to work?

 

Sure. Would be glad to explain what I'm trying to do.

 

1. Let's say I have 10 tests in my suite

2. There are only one @Test in each of these test classes

3. Each @Test is a selenium webdriver test

4. While each of these tests are running, It will fetch some data from the website and store it in the aforementioned `Map<String, String>`. 

5. After the test is done I want to read the `Map` in the `afterInvocation` and then do some processing for each @Test. 

 

I'm so focussed on afterInvocation because of it being part of a listener and listeners are way too convenient to manage and not clumsy. 

On Monday, December 18, 2017 at 9:37:00 PM UTC-5, Krishnan Mahadevan wrote:

Comments inline.

 

All said and done, what are you trying to solve? Can you please elaborate?

 

Thanks & Regards

Krishnan Mahadevan

 

"All the desirable things in life are either illegal, expensive, fattening or in love with someone else!"

My Scribblings @ <a href="http://wakened-cognition.blogspot.com/" target="_blank" rel="nofollow" onmousedown="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fwakened-cognition.blogspot.com%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHzOdYJCASIDF_28vQtkp9gnKAYSQ&#39;;return true;" onclick="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fwakened-cognition.blogspot.com%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHzOdYJCASIDF_28vQtkp9gnKAYSQ&#39;;return true;">http://wakened-cognition.blogspot.com/

My Technical Scribbings @ <a href="http://rationaleemotions.wordpress.com/" target="_blank" rel="nofollow" onmousedown="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Frationaleemotions.wordpress.com%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNEcBOKyRn0lpL8LDbBuyAlKdwgXwQ&#39;;return true;" onclick="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Frationaleemotions.wordpress.com%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNEcBOKyRn0lpL8LDbBuyAlKdwgXwQ&#39;;return true;">http://rationaleemotions.wordpress.com/

 

From: <[hidden email]> on behalf of prvn <[hidden email]>
Reply-To: <[hidden email]>
Date: Tuesday, December 19, 2017 at 8:01 AM
To: testng-users <[hidden email]>
Subject: Re: [testng-users] Is this how IInvokedMethodListener supposed to work?

 

Thanks Krishnan. I tried that and it worked for me. But two questions

 

  1. Is static field (In ReportImpl class) going to have a side effect when tests are executed in parallel?

[Krishnan] Yes and No. It all depends on what you are trying to do with the map. But in general if you are going to be both writing and reading from the map at the same time, then static maps are going to be an issue.

 

  1. I really cannot have Reporter.getCurrentTestResult().setAttribute("REPORT_DATA", report); in my test case. Is there any other way to persist the object through afterInvocation?

[Krishnan] You either do that, or you have your beforeInvocation() take care of initializing everything and then your afterInvocation() reading data. That means your @Test method does nothing to do the map. You obviously would need to query the map in some manner no ? Either you do it via an attribute setting in the ITestResult object or you make use of ThreadLocal.




On Monday, December 18, 2017 at 9:21:35 PM UTC-5, Krishnan Mahadevan wrote:

Including the correct TestClass version

 

@Listeners(TestListener.class)
public class TestClass {

   
@Test
   
public void testMethod() {
        ReportImpl report = (ReportImpl) Reporter.getCurrentTestResult().getAttribute(
"REPORT_DATA");
        report.populateMap();
        Reporter.getCurrentTestResult().setAttribute(
"REPORT_DATA", report);
    }
}

 

 

Thanks & Regards

Krishnan Mahadevan

 

"All the desirable things in life are either illegal, expensive, fattening or in love with someone else!"

My Scribblings @ <a href="http://wakened-cognition.blogspot.com/" target="_blank" rel="nofollow" onmousedown="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fwakened-cognition.blogspot.com%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHzOdYJCASIDF_28vQtkp9gnKAYSQ&#39;;return true;" onclick="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fwakened-cognition.blogspot.com%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHzOdYJCASIDF_28vQtkp9gnKAYSQ&#39;;return true;">http://wakened-cognition.blogspot.com/

My Technical Scribbings @ <a href="http://rationaleemotions.wordpress.com/" target="_blank" rel="nofollow" onmousedown="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Frationaleemotions.wordpress.com%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNEcBOKyRn0lpL8LDbBuyAlKdwgXwQ&#39;;return true;" onclick="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Frationaleemotions.wordpress.com%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNEcBOKyRn0lpL8LDbBuyAlKdwgXwQ&#39;;return true;">http://rationaleemotions.wordpress.com/

 

From: Krishnan Mahadevan <[hidden email]>
Date: Tuesday, December 19, 2017 at 7:48 AM
To: <[hidden email]>
Subject: Re: [testng-users] Is this how IInvokedMethodListener supposed to work?

 

Praveen,

 

>>>> Now the question is in the `afterInvocation` I'm doing `report.getDataFromMap()` which in turn get's data from `ReportImp` class. Unfortunately `reportMap` is null because for some reasons the key/value that was put into this `reportMap` has been lost when the control was passed to `afterInvocation`. 

 

This is because, from within beforeInvocation() you are invoking Reporter.getCurrentTestResult() which is going to fetch the ITestResult object associated with “beforeInvocation()” now when you enter the @Test method, the ITestResult object of the current test method is what gets popped out when you do a Reporter.getCurrentTestResult(). And when you are entering your afterInvocation(), since its still on the same thread [ only beforeInvocation() > @Test > afterInvocation()  are guaranteed to run on the same thread ] you get the ITestResult object which doesn’t have what was persisted via the setAttribute() method.

 

I am guessing that perhaps the following changed code is what you need.

 

import org.testng.Reporter;
import org.testng.annotations.Listeners;
import org.testng.annotations.Test;

@Listeners(TestListener.class)
public class TestClass {

   
@Test
   
public void testMethod() {
        ReportImpl report =
new ReportImpl();
        report.populateMap();
        Reporter.getCurrentTestResult().setAttribute(
"REPORT_DATA", report);
    }
}

 

import java.util.HashMap;
import java.util.Map;

public class ReportImpl {

    Map<String, String>
reportMap = new HashMap<String, String>();

   
public void populateMap() {
       
reportMap.put("google", "alphabet");
       
reportMap.put("bing", "Microsoft");
       
reportMap.put("iOS", "apple");
    }

   
public void getDataFromMap() {
        String google =
reportMap.get("google");
        String ms =
reportMap.get("bing");
        System.
err.println(google + ms);
    }
}

 

import org.testng.IInvokedMethod;
import org.testng.IInvokedMethodListener;
import org.testng.ITestResult;

public class TestListener implements IInvokedMethodListener {

   
@Override
   
public void beforeInvocation(IInvokedMethod method, ITestResult testResult) {
        ReportImpl report =
new ReportImpl();
        testResult.setAttribute(
"REPORT_DATA", report);

    }

   
@Override
   
public void afterInvocation(IInvokedMethod method, ITestResult testResult) {
        ReportImpl report = (ReportImpl) testResult.getAttribute(
"REPORT_DATA");
        report.getDataFromMap();

    }
}

 

Output:

 

alphabetMicrosoft

 

===============================================

Default Suite

Total tests run: 1, Failures: 0, Skips: 0

===============================================

 

 

Process finished with exit code 0

 

 

 

 

Thanks & Regards

Krishnan Mahadevan

 

"All the desirable things in life are either illegal, expensive, fattening or in love with someone else!"

My Scribblings @ <a href="http://wakened-cognition.blogspot.com/" target="_blank" rel="nofollow" onmousedown="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fwakened-cognition.blogspot.com%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHzOdYJCASIDF_28vQtkp9gnKAYSQ&#39;;return true;" onclick="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fwakened-cognition.blogspot.com%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHzOdYJCASIDF_28vQtkp9gnKAYSQ&#39;;return true;">http://wakened-cognition.blogspot.com/

My Technical Scribbings @ <a href="http://rationaleemotions.wordpress.com/" target="_blank" rel="nofollow" onmousedown="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Frationaleemotions.wordpress.com%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNEcBOKyRn0lpL8LDbBuyAlKdwgXwQ&#39;;return true;" onclick="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Frationaleemotions.wordpress.com%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNEcBOKyRn0lpL8LDbBuyAlKdwgXwQ&#39;;return true;">http://rationaleemotions.wordpress.com/

 

From: <[hidden email]> on behalf of prvn <[hidden email]>
Reply-To: <[hidden email]>
Date: Tuesday, December 19, 2017 at 6:10 AM
To: testng-users <[hidden email]>
Subject: [testng-users] Is this how IInvokedMethodListener supposed to work?

 

I have a test class as below

 

@Listeners(com.testng.test.TestListener.class)

public class TestClass {

 

    @Test

    public void testMethod() {

        ReportImpl report = new ReportImpl();

        report.populateMap();

    }

}

 

Then I have a `ReportImpl` class as below

 

public class ReportImpl {

 

    Map<String, String> reportMap = new HashMap<String, String>();

 

    public void populateMap() {

        reportMap.put("google", "alphabet");

        reportMap.put("bing", "Microsoft");

        reportMap.put("iOS", "apple");

    }

 

    public void getDataFromMap() {

        String google = reportMap.get("google");

        String ms = reportMap.get("bing");

        System.out.println(google + ms);

    }

}

 

 

Now I have a listener called `TestListener` which is implements `IInvokedMethodListener` as below

 

public class TestListener implements IInvokedMethodListener {

 

    @Override

    public void beforeInvocation(IInvokedMethod method, ITestResult testResult) {

        ReportImpl report = new ReportImpl();

        Reporter.getCurrentTestResult()

                .setAttribute("REPORT_DATA", report);

 

    }

 

    @Override

    public void afterInvocation(IInvokedMethod method, ITestResult testResult) {

        ReportImpl report = (ReportImpl) Reporter.getCurrentTestResult()

                                                 .getAttribute("REPORT_DATA");

        report.getDataFromMap();

 

    }

}

 

Now the question is in the `afterInvocation` I'm doing `report.getDataFromMap()` which in turn get's data from `ReportImp` class. Unfortunately `reportMap` is null because for some reasons the key/value that was put into this `reportMap` has been lost when the control was passed to `afterInvocation`. 

 

But when I make the `reportMap` to static it perfectly works fine. Is this how it's supposed to work? What would be the side effect for having `static` map when tests are run in parallel?

--
You received this message because you are subscribed to the Google Groups "testng-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to testng-users...@googlegroups.com.
To post to this group, send email to [hidden email].
Visit this group at <a href="https://groups.google.com/group/testng-users" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://groups.google.com/group/testng-users&#39;;return true;" onclick="this.href=&#39;https://groups.google.com/group/testng-users&#39;;return true;">https://groups.google.com/group/testng-users.
For more options, visit <a href="https://groups.google.com/d/optout" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://groups.google.com/d/optout&#39;;return true;" onclick="this.href=&#39;https://groups.google.com/d/optout&#39;;return true;">https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "testng-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to testng-users...@googlegroups.com.
To post to this group, send email to [hidden email].
Visit this group at <a href="https://groups.google.com/group/testng-users" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://groups.google.com/group/testng-users&#39;;return true;" onclick="this.href=&#39;https://groups.google.com/group/testng-users&#39;;return true;">https://groups.google.com/group/testng-users.
For more options, visit <a href="https://groups.google.com/d/optout" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://groups.google.com/d/optout&#39;;return true;" onclick="this.href=&#39;https://groups.google.com/d/optout&#39;;return true;">https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "testng-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to <a href="javascript:" target="_blank" gdf-obfuscated-mailto="bYTYMGhRDAAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">testng-users...@googlegroups.com.
To post to this group, send email to <a href="javascript:" target="_blank" gdf-obfuscated-mailto="bYTYMGhRDAAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">testng...@....
Visit this group at <a href="https://groups.google.com/group/testng-users" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://groups.google.com/group/testng-users&#39;;return true;" onclick="this.href=&#39;https://groups.google.com/group/testng-users&#39;;return true;">https://groups.google.com/group/testng-users.
For more options, visit <a href="https://groups.google.com/d/optout" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://groups.google.com/d/optout&#39;;return true;" onclick="this.href=&#39;https://groups.google.com/d/optout&#39;;return true;">https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "testng-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/testng-users.
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Is this how IInvokedMethodListener supposed to work?

Krishnan Mahadevan

Ok! In that case, ensure that your Listener’s beforeInvocation(), @Test method and afterInvocation() are working with :

 

private static final ThreadLocal<ReportImpl> = new ThreadLocal<>();

 

along with an appropriate getCurrentReport() and setCurrentReport() static methods, to interact with the ThreadLocal.

 

Thanks & Regards

Krishnan Mahadevan

 

"All the desirable things in life are either illegal, expensive, fattening or in love with someone else!"

My Scribblings @ http://wakened-cognition.blogspot.com/

My Technical Scribbings @ http://rationaleemotions.wordpress.com/

 

From: <[hidden email]> on behalf of prvn <[hidden email]>
Reply-To: <[hidden email]>
Date: Tuesday, December 19, 2017 at 8:28 AM
To: testng-users <[hidden email]>
Subject: Re: [testng-users] Is this how IInvokedMethodListener supposed to work?

 

Thanks Krishnan.

 

#3 is easy to implement. I will go with that. Thanks a lot once again.

On Monday, December 18, 2017 at 9:56:25 PM UTC-5, Krishnan Mahadevan wrote:

Great. That makes sense!

 

Just to re-iterate, you have only one of the following three options.

 

  1. Use the solution that I shared on an as-is basis [ But guess you aren’t ready for that]
  2. Leverage IHookable by doing the following:
    1. Build a base class which implements the IHookable interface. When you do this, TestNG will indirectly invoke your @Test methods via the run() of your base class. So, it’s kind of like a proxy to your actual test method invocation.
    2. Within org.testng.IHookable#run implement the logic of extracting your ReportImpl object from the current ITestResult object [ you have access to it in the run() method], do the data fetch from website, persist it back to the ITestResult object
  1. Leverage ThreadLocal, so that every thread gets its own copy of the ReportImpl object [ and thus the map as well] and you don’t have to worry about Thread safety.

 

Thanks & Regards

Krishnan Mahadevan

 

"All the desirable things in life are either illegal, expensive, fattening or in love with someone else!"

My Scribblings @ http://wakened-cognition.blogspot.com/

My Technical Scribbings @ http://rationaleemotions.wordpress.com/

 

From: <<a href="javascript:" target="_blank">testng...@...> on behalf of prvn <<a href="javascript:" target="_blank">neevar...@...>
Reply-To: <<a href="javascript:" target="_blank">testng...@...>
Date: Tuesday, December 19, 2017 at 8:19 AM
To: testng-users <<a href="javascript:" target="_blank">testng...@...>
Subject: Re: [testng-users] Is this how IInvokedMethodListener supposed to work?

 

Sure. Would be glad to explain what I'm trying to do.

 

1. Let's say I have 10 tests in my suite

2. There are only one @Test in each of these test classes

3. Each @Test is a selenium webdriver test

4. While each of these tests are running, It will fetch some data from the website and store it in the aforementioned `Map<String, String>`. 

5. After the test is done I want to read the `Map` in the `afterInvocation` and then do some processing for each @Test. 

 

I'm so focussed on afterInvocation because of it being part of a listener and listeners are way too convenient to manage and not clumsy. 

On Monday, December 18, 2017 at 9:37:00 PM UTC-5, Krishnan Mahadevan wrote:

Comments inline.

 

All said and done, what are you trying to solve? Can you please elaborate?

 

Thanks & Regards

Krishnan Mahadevan

 

"All the desirable things in life are either illegal, expensive, fattening or in love with someone else!"

My Scribblings @ http://wakened-cognition.blogspot.com/

My Technical Scribbings @ http://rationaleemotions.wordpress.com/

 

From: <[hidden email]> on behalf of prvn <[hidden email]>
Reply-To: <[hidden email]>
Date: Tuesday, December 19, 2017 at 8:01 AM
To: testng-users <[hidden email]>
Subject: Re: [testng-users] Is this how IInvokedMethodListener supposed to work?

 

Thanks Krishnan. I tried that and it worked for me. But two questions

 

  1. Is static field (In ReportImpl class) going to have a side effect when tests are executed in parallel?

[Krishnan] Yes and No. It all depends on what you are trying to do with the map. But in general if you are going to be both writing and reading from the map at the same time, then static maps are going to be an issue.

 

  1. I really cannot have Reporter.getCurrentTestResult().setAttribute("REPORT_DATA", report); in my test case. Is there any other way to persist the object through afterInvocation?

[Krishnan] You either do that, or you have your beforeInvocation() take care of initializing everything and then your afterInvocation() reading data. That means your @Test method does nothing to do the map. You obviously would need to query the map in some manner no ? Either you do it via an attribute setting in the ITestResult object or you make use of ThreadLocal.




On Monday, December 18, 2017 at 9:21:35 PM UTC-5, Krishnan Mahadevan wrote:

Including the correct TestClass version

 

@Listeners(TestListener.class)
public class TestClass {

   
@Test
   
public void testMethod() {
        ReportImpl report = (ReportImpl) Reporter.getCurrentTestResult().getAttribute(
"REPORT_DATA");
        report.populateMap();
        Reporter.getCurrentTestResult().setAttribute(
"REPORT_DATA", report);
    }
}

 

 

Thanks & Regards

Krishnan Mahadevan

 

"All the desirable things in life are either illegal, expensive, fattening or in love with someone else!"

My Scribblings @ http://wakened-cognition.blogspot.com/

My Technical Scribbings @ http://rationaleemotions.wordpress.com/

 

From: Krishnan Mahadevan <[hidden email]>
Date: Tuesday, December 19, 2017 at 7:48 AM
To: <[hidden email]>
Subject: Re: [testng-users] Is this how IInvokedMethodListener supposed to work?

 

Praveen,

 

>>>> Now the question is in the `afterInvocation` I'm doing `report.getDataFromMap()` which in turn get's data from `ReportImp` class. Unfortunately `reportMap` is null because for some reasons the key/value that was put into this `reportMap` has been lost when the control was passed to `afterInvocation`. 

 

This is because, from within beforeInvocation() you are invoking Reporter.getCurrentTestResult() which is going to fetch the ITestResult object associated with “beforeInvocation()” now when you enter the @Test method, the ITestResult object of the current test method is what gets popped out when you do a Reporter.getCurrentTestResult(). And when you are entering your afterInvocation(), since its still on the same thread [ only beforeInvocation() > @Test > afterInvocation()  are guaranteed to run on the same thread ] you get the ITestResult object which doesn’t have what was persisted via the setAttribute() method.

 

I am guessing that perhaps the following changed code is what you need.

 

import org.testng.Reporter;
import org.testng.annotations.Listeners;
import org.testng.annotations.Test;

@Listeners(TestListener.class)
public class TestClass {

   
@Test
   
public void testMethod() {
        ReportImpl report =
new ReportImpl();
        report.populateMap();
        Reporter.getCurrentTestResult().setAttribute(
"REPORT_DATA", report);
    }
}

 

import java.util.HashMap;
import java.util.Map;

public class ReportImpl {

    Map<String, String>
reportMap = new HashMap<String, String>();

   
public void populateMap() {
       
reportMap.put("google", "alphabet");
       
reportMap.put("bing", "Microsoft");
       
reportMap.put("iOS", "apple");
    }

   
public void getDataFromMap() {
        String google =
reportMap.get("google");
        String ms =
reportMap.get("bing");
        System.
err.println(google + ms);
    }
}

 

import org.testng.IInvokedMethod;
import org.testng.IInvokedMethodListener;
import org.testng.ITestResult;

public class TestListener implements IInvokedMethodListener {

   
@Override
   
public void beforeInvocation(IInvokedMethod method, ITestResult testResult) {
        ReportImpl report =
new ReportImpl();
        testResult.setAttribute(
"REPORT_DATA", report);

    }

   
@Override
   
public void afterInvocation(IInvokedMethod method, ITestResult testResult) {
        ReportImpl report = (ReportImpl) testResult.getAttribute(
"REPORT_DATA");
        report.getDataFromMap();

    }
}

 

Output:

 

alphabetMicrosoft

 

===============================================

Default Suite

Total tests run: 1, Failures: 0, Skips: 0

===============================================

 

 

Process finished with exit code 0

 

 

 

 

Thanks & Regards

Krishnan Mahadevan

 

"All the desirable things in life are either illegal, expensive, fattening or in love with someone else!"

My Scribblings @ http://wakened-cognition.blogspot.com/

My Technical Scribbings @ http://rationaleemotions.wordpress.com/

 

From: <[hidden email]> on behalf of prvn <[hidden email]>
Reply-To: <[hidden email]>
Date: Tuesday, December 19, 2017 at 6:10 AM
To: testng-users <[hidden email]>
Subject: [testng-users] Is this how IInvokedMethodListener supposed to work?

 

I have a test class as below

 

@Listeners(com.testng.test.TestListener.class)

public class TestClass {

 

    @Test

    public void testMethod() {

        ReportImpl report = new ReportImpl();

        report.populateMap();

    }

}

 

Then I have a `ReportImpl` class as below

 

public class ReportImpl {

 

    Map<String, String> reportMap = new HashMap<String, String>();

 

    public void populateMap() {

        reportMap.put("google", "alphabet");

        reportMap.put("bing", "Microsoft");

        reportMap.put("iOS", "apple");

    }

 

    public void getDataFromMap() {

        String google = reportMap.get("google");

        String ms = reportMap.get("bing");

        System.out.println(google + ms);

    }

}

 

 

Now I have a listener called `TestListener` which is implements `IInvokedMethodListener` as below

 

public class TestListener implements IInvokedMethodListener {

 

    @Override

    public void beforeInvocation(IInvokedMethod method, ITestResult testResult) {

        ReportImpl report = new ReportImpl();

        Reporter.getCurrentTestResult()

                .setAttribute("REPORT_DATA", report);

 

    }

 

    @Override

    public void afterInvocation(IInvokedMethod method, ITestResult testResult) {

        ReportImpl report = (ReportImpl) Reporter.getCurrentTestResult()

                                                 .getAttribute("REPORT_DATA");

        report.getDataFromMap();

 

    }

}

 

Now the question is in the `afterInvocation` I'm doing `report.getDataFromMap()` which in turn get's data from `ReportImp` class. Unfortunately `reportMap` is null because for some reasons the key/value that was put into this `reportMap` has been lost when the control was passed to `afterInvocation`. 

 

But when I make the `reportMap` to static it perfectly works fine. Is this how it's supposed to work? What would be the side effect for having `static` map when tests are run in parallel?

--
You received this message because you are subscribed to the Google Groups "testng-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/testng-users.
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "testng-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/testng-users.
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "testng-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to <a href="javascript:" target="_blank">testng-users...@....
To post to this group, send email to <a href="javascript:" target="_blank">testng...@....
Visit this group at https://groups.google.com/group/testng-users.
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "testng-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/testng-users.
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "testng-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/testng-users.
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Is this how IInvokedMethodListener supposed to work?

praveen133t
Thank you very much! That worked like a charm!

On Monday, December 18, 2017 at 10:01:06 PM UTC-5, Krishnan Mahadevan wrote:

Ok! In that case, ensure that your Listener’s beforeInvocation(), @Test method and afterInvocation() are working with :

 

private static final ThreadLocal<ReportImpl> = new ThreadLocal<>();

 

along with an appropriate getCurrentReport() and setCurrentReport() static methods, to interact with the ThreadLocal.

 

Thanks & Regards

Krishnan Mahadevan

 

"All the desirable things in life are either illegal, expensive, fattening or in love with someone else!"

My Scribblings @ <a href="http://wakened-cognition.blogspot.com/" target="_blank" rel="nofollow" onmousedown="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fwakened-cognition.blogspot.com%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHzOdYJCASIDF_28vQtkp9gnKAYSQ&#39;;return true;" onclick="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fwakened-cognition.blogspot.com%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHzOdYJCASIDF_28vQtkp9gnKAYSQ&#39;;return true;">http://wakened-cognition.blogspot.com/

My Technical Scribbings @ <a href="http://rationaleemotions.wordpress.com/" target="_blank" rel="nofollow" onmousedown="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Frationaleemotions.wordpress.com%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNEcBOKyRn0lpL8LDbBuyAlKdwgXwQ&#39;;return true;" onclick="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Frationaleemotions.wordpress.com%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNEcBOKyRn0lpL8LDbBuyAlKdwgXwQ&#39;;return true;">http://rationaleemotions.wordpress.com/

 

From: <<a href="javascript:" target="_blank" gdf-obfuscated-mailto="d9PRkalRDAAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">testng...@...> on behalf of prvn <<a href="javascript:" target="_blank" gdf-obfuscated-mailto="d9PRkalRDAAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">neevar...@...>
Reply-To: <<a href="javascript:" target="_blank" gdf-obfuscated-mailto="d9PRkalRDAAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">testng...@...>
Date: Tuesday, December 19, 2017 at 8:28 AM
To: testng-users <<a href="javascript:" target="_blank" gdf-obfuscated-mailto="d9PRkalRDAAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">testng...@...>
Subject: Re: [testng-users] Is this how IInvokedMethodListener supposed to work?

 

Thanks Krishnan.

 

#3 is easy to implement. I will go with that. Thanks a lot once again.

On Monday, December 18, 2017 at 9:56:25 PM UTC-5, Krishnan Mahadevan wrote:

Great. That makes sense!

 

Just to re-iterate, you have only one of the following three options.

 

  1. Use the solution that I shared on an as-is basis [ But guess you aren’t ready for that]
  2. Leverage IHookable by doing the following:
    1. Build a base class which implements the IHookable interface. When you do this, TestNG will indirectly invoke your @Test methods via the run() of your base class. So, it’s kind of like a proxy to your actual test method invocation.
    2. Within org.testng.IHookable#run implement the logic of extracting your ReportImpl object from the current ITestResult object [ you have access to it in the run() method], do the data fetch from website, persist it back to the ITestResult object
  1. Leverage ThreadLocal, so that every thread gets its own copy of the ReportImpl object [ and thus the map as well] and you don’t have to worry about Thread safety.

 

Thanks & Regards

Krishnan Mahadevan

 

"All the desirable things in life are either illegal, expensive, fattening or in love with someone else!"

My Scribblings @ <a href="http://wakened-cognition.blogspot.com/" target="_blank" rel="nofollow" onmousedown="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fwakened-cognition.blogspot.com%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHzOdYJCASIDF_28vQtkp9gnKAYSQ&#39;;return true;" onclick="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fwakened-cognition.blogspot.com%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHzOdYJCASIDF_28vQtkp9gnKAYSQ&#39;;return true;">http://wakened-cognition.blogspot.com/

My Technical Scribbings @ <a href="http://rationaleemotions.wordpress.com/" target="_blank" rel="nofollow" onmousedown="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Frationaleemotions.wordpress.com%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNEcBOKyRn0lpL8LDbBuyAlKdwgXwQ&#39;;return true;" onclick="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Frationaleemotions.wordpress.com%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNEcBOKyRn0lpL8LDbBuyAlKdwgXwQ&#39;;return true;">http://rationaleemotions.wordpress.com/

 

From: <[hidden email]> on behalf of prvn <[hidden email]>
Reply-To: <[hidden email]>
Date: Tuesday, December 19, 2017 at 8:19 AM
To: testng-users <[hidden email]>
Subject: Re: [testng-users] Is this how IInvokedMethodListener supposed to work?

 

Sure. Would be glad to explain what I'm trying to do.

 

1. Let's say I have 10 tests in my suite

2. There are only one @Test in each of these test classes

3. Each @Test is a selenium webdriver test

4. While each of these tests are running, It will fetch some data from the website and store it in the aforementioned `Map<String, String>`. 

5. After the test is done I want to read the `Map` in the `afterInvocation` and then do some processing for each @Test. 

 

I'm so focussed on afterInvocation because of it being part of a listener and listeners are way too convenient to manage and not clumsy. 

On Monday, December 18, 2017 at 9:37:00 PM UTC-5, Krishnan Mahadevan wrote:

Comments inline.

 

All said and done, what are you trying to solve? Can you please elaborate?

 

Thanks & Regards

Krishnan Mahadevan

 

"All the desirable things in life are either illegal, expensive, fattening or in love with someone else!"

My Scribblings @ <a href="http://wakened-cognition.blogspot.com/" target="_blank" rel="nofollow" onmousedown="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fwakened-cognition.blogspot.com%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHzOdYJCASIDF_28vQtkp9gnKAYSQ&#39;;return true;" onclick="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fwakened-cognition.blogspot.com%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHzOdYJCASIDF_28vQtkp9gnKAYSQ&#39;;return true;">http://wakened-cognition.blogspot.com/

My Technical Scribbings @ <a href="http://rationaleemotions.wordpress.com/" target="_blank" rel="nofollow" onmousedown="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Frationaleemotions.wordpress.com%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNEcBOKyRn0lpL8LDbBuyAlKdwgXwQ&#39;;return true;" onclick="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Frationaleemotions.wordpress.com%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNEcBOKyRn0lpL8LDbBuyAlKdwgXwQ&#39;;return true;">http://rationaleemotions.wordpress.com/

 

From: <[hidden email]> on behalf of prvn <[hidden email]>
Reply-To: <[hidden email]>
Date: Tuesday, December 19, 2017 at 8:01 AM
To: testng-users <[hidden email]>
Subject: Re: [testng-users] Is this how IInvokedMethodListener supposed to work?

 

Thanks Krishnan. I tried that and it worked for me. But two questions

 

  1. Is static field (In ReportImpl class) going to have a side effect when tests are executed in parallel?

[Krishnan] Yes and No. It all depends on what you are trying to do with the map. But in general if you are going to be both writing and reading from the map at the same time, then static maps are going to be an issue.

 

  1. I really cannot have Reporter.getCurrentTestResult().setAttribute("REPORT_DATA", report); in my test case. Is there any other way to persist the object through afterInvocation?

[Krishnan] You either do that, or you have your beforeInvocation() take care of initializing everything and then your afterInvocation() reading data. That means your @Test method does nothing to do the map. You obviously would need to query the map in some manner no ? Either you do it via an attribute setting in the ITestResult object or you make use of ThreadLocal.




On Monday, December 18, 2017 at 9:21:35 PM UTC-5, Krishnan Mahadevan wrote:

Including the correct TestClass version

 

@Listeners(TestListener.class)
public class TestClass {

   
@Test
   
public void testMethod() {
        ReportImpl report = (ReportImpl) Reporter.getCurrentTestResult().getAttribute(
"REPORT_DATA");
        report.populateMap();
        Reporter.getCurrentTestResult().setAttribute(
"REPORT_DATA", report);
    }
}

 

 

Thanks & Regards

Krishnan Mahadevan

 

"All the desirable things in life are either illegal, expensive, fattening or in love with someone else!"

My Scribblings @ <a href="http://wakened-cognition.blogspot.com/" target="_blank" rel="nofollow" onmousedown="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fwakened-cognition.blogspot.com%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHzOdYJCASIDF_28vQtkp9gnKAYSQ&#39;;return true;" onclick="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fwakened-cognition.blogspot.com%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHzOdYJCASIDF_28vQtkp9gnKAYSQ&#39;;return true;">http://wakened-cognition.blogspot.com/

My Technical Scribbings @ <a href="http://rationaleemotions.wordpress.com/" target="_blank" rel="nofollow" onmousedown="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Frationaleemotions.wordpress.com%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNEcBOKyRn0lpL8LDbBuyAlKdwgXwQ&#39;;return true;" onclick="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Frationaleemotions.wordpress.com%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNEcBOKyRn0lpL8LDbBuyAlKdwgXwQ&#39;;return true;">http://rationaleemotions.wordpress.com/

 

From: Krishnan Mahadevan <[hidden email]>
Date: Tuesday, December 19, 2017 at 7:48 AM
To: <[hidden email]>
Subject: Re: [testng-users] Is this how IInvokedMethodListener supposed to work?

 

Praveen,

 

>>>> Now the question is in the `afterInvocation` I'm doing `report.getDataFromMap()` which in turn get's data from `ReportImp` class. Unfortunately `reportMap` is null because for some reasons the key/value that was put into this `reportMap` has been lost when the control was passed to `afterInvocation`. 

 

This is because, from within beforeInvocation() you are invoking Reporter.getCurrentTestResult() which is going to fetch the ITestResult object associated with “beforeInvocation()” now when you enter the @Test method, the ITestResult object of the current test method is what gets popped out when you do a Reporter.getCurrentTestResult(). And when you are entering your afterInvocation(), since its still on the same thread [ only beforeInvocation() > @Test > afterInvocation()  are guaranteed to run on the same thread ] you get the ITestResult object which doesn’t have what was persisted via the setAttribute() method.

 

I am guessing that perhaps the following changed code is what you need.

 

import org.testng.Reporter;
import org.testng.annotations.Listeners;
import org.testng.annotations.Test;

@Listeners(TestListener.class)
public class TestClass {

   
@Test
   
public void testMethod() {
        ReportImpl report =
new ReportImpl();
        report.populateMap();
        Reporter.getCurrentTestResult().setAttribute(
"REPORT_DATA", report);
    }
}

 

import java.util.HashMap;
import java.util.Map;

public class ReportImpl {

    Map<String, String>
reportMap = new HashMap<String, String>();

   
public void populateMap() {
       
reportMap.put("google", "alphabet");
       
reportMap.put("bing", "Microsoft");
       
reportMap.put("iOS", "apple");
    }

   
public void getDataFromMap() {
        String google =
reportMap.get("google");
        String ms =
reportMap.get("bing");
        System.
err.println(google + ms);
    }
}

 

import org.testng.IInvokedMethod;
import org.testng.IInvokedMethodListener;
import org.testng.ITestResult;

public class TestListener implements IInvokedMethodListener {

   
@Override
   
public void beforeInvocation(IInvokedMethod method, ITestResult testResult) {
        ReportImpl report =
new ReportImpl();
        testResult.setAttribute(
"REPORT_DATA", report);

    }

   
@Override
   
public void afterInvocation(IInvokedMethod method, ITestResult testResult) {
        ReportImpl report = (ReportImpl) testResult.getAttribute(
"REPORT_DATA");
        report.getDataFromMap();

    }
}

 

Output:

 

alphabetMicrosoft

 

===============================================

Default Suite

Total tests run: 1, Failures: 0, Skips: 0

===============================================

 

 

Process finished with exit code 0

 

 

 

 

Thanks & Regards

Krishnan Mahadevan

 

"All the desirable things in life are either illegal, expensive, fattening or in love with someone else!"

My Scribblings @ <a href="http://wakened-cognition.blogspot.com/" target="_blank" rel="nofollow" onmousedown="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fwakened-cognition.blogspot.com%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHzOdYJCASIDF_28vQtkp9gnKAYSQ&#39;;return true;" onclick="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fwakened-cognition.blogspot.com%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHzOdYJCASIDF_28vQtkp9gnKAYSQ&#39;;return true;">http://wakened-cognition.blogspot.com/

My Technical Scribbings @ <a href="http://rationaleemotions.wordpress.com/" target="_blank" rel="nofollow" onmousedown="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Frationaleemotions.wordpress.com%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNEcBOKyRn0lpL8LDbBuyAlKdwgXwQ&#39;;return true;" onclick="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Frationaleemotions.wordpress.com%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNEcBOKyRn0lpL8LDbBuyAlKdwgXwQ&#39;;return true;">http://rationaleemotions.wordpress.com/

 

From: <[hidden email]> on behalf of prvn <[hidden email]>
Reply-To: <[hidden email]>
Date: Tuesday, December 19, 2017 at 6:10 AM
To: testng-users <[hidden email]>
Subject: [testng-users] Is this how IInvokedMethodListener supposed to work?

 

I have a test class as below

 

@Listeners(com.testng.test.TestListener.class)

public class TestClass {

 

    @Test

    public void testMethod() {

        ReportImpl report = new ReportImpl();

        report.populateMap();

    }

}

 

Then I have a `ReportImpl` class as below

 

public class ReportImpl {

 

    Map<String, String> reportMap = new HashMap<String, String>();

 

    public void populateMap() {

        reportMap.put("google", "alphabet");

        reportMap.put("bing", "Microsoft");

        reportMap.put("iOS", "apple");

    }

 

    public void getDataFromMap() {

        String google = reportMap.get("google");

        String ms = reportMap.get("bing");

        System.out.println(google + ms);

    }

}

 

 

Now I have a listener called `TestListener` which is implements `IInvokedMethodListener` as below

 

public class TestListener implements IInvokedMethodListener {

 

    @Override

    public void beforeInvocation(IInvokedMethod method, ITestResult testResult) {

        ReportImpl report = new ReportImpl();

        Reporter.getCurrentTestResult()

                .setAttribute("REPORT_DATA", report);

 

    }

 

    @Override

    public void afterInvocation(IInvokedMethod method, ITestResult testResult) {

        ReportImpl report = (ReportImpl) Reporter.getCurrentTestResult()

                                                 .getAttribute("REPORT_DATA");

        report.getDataFromMap();

 

    }

}

 

Now the question is in the `afterInvocation` I'm doing `report.getDataFromMap()` which in turn get's data from `ReportImp` class. Unfortunately `reportMap` is null because for some reasons the key/value that was put into this `reportMap` has been lost when the control was passed to `afterInvocation`. 

 

But when I make the `reportMap` to static it perfectly works fine. Is this how it's supposed to work? What would be the side effect for having `static` map when tests are run in parallel?

--
You received this message because you are subscribed to the Google Groups "testng-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to testng-users...@googlegroups.com.
To post to this group, send email to [hidden email].
Visit this group at <a href="https://groups.google.com/group/testng-users" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://groups.google.com/group/testng-users&#39;;return true;" onclick="this.href=&#39;https://groups.google.com/group/testng-users&#39;;return true;">https://groups.google.com/group/testng-users.
For more options, visit <a href="https://groups.google.com/d/optout" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://groups.google.com/d/optout&#39;;return true;" onclick="this.href=&#39;https://groups.google.com/d/optout&#39;;return true;">https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "testng-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to testng-users...@googlegroups.com.
To post to this group, send email to [hidden email].
Visit this group at <a href="https://groups.google.com/group/testng-users" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://groups.google.com/group/testng-users&#39;;return true;" onclick="this.href=&#39;https://groups.google.com/group/testng-users&#39;;return true;">https://groups.google.com/group/testng-users.
For more options, visit <a href="https://groups.google.com/d/optout" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://groups.google.com/d/optout&#39;;return true;" onclick="this.href=&#39;https://groups.google.com/d/optout&#39;;return true;">https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "testng-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to testng-users...@googlegroups.com.
To post to this group, send email to [hidden email].
Visit this group at <a href="https://groups.google.com/group/testng-users" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://groups.google.com/group/testng-users&#39;;return true;" onclick="this.href=&#39;https://groups.google.com/group/testng-users&#39;;return true;">https://groups.google.com/group/testng-users.
For more options, visit <a href="https://groups.google.com/d/optout" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://groups.google.com/d/optout&#39;;return true;" onclick="this.href=&#39;https://groups.google.com/d/optout&#39;;return true;">https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "testng-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to <a href="javascript:" target="_blank" gdf-obfuscated-mailto="d9PRkalRDAAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">testng-users...@googlegroups.com.
To post to this group, send email to <a href="javascript:" target="_blank" gdf-obfuscated-mailto="d9PRkalRDAAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">testng...@....
Visit this group at <a href="https://groups.google.com/group/testng-users" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://groups.google.com/group/testng-users&#39;;return true;" onclick="this.href=&#39;https://groups.google.com/group/testng-users&#39;;return true;">https://groups.google.com/group/testng-users.
For more options, visit <a href="https://groups.google.com/d/optout" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://groups.google.com/d/optout&#39;;return true;" onclick="this.href=&#39;https://groups.google.com/d/optout&#39;;return true;">https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "testng-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at https://groups.google.com/group/testng-users.
For more options, visit https://groups.google.com/d/optout.