Run @BeforeTest in same thread - paralle run - Selenium webdriver - testng

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

Run @BeforeTest in same thread - paralle run - Selenium webdriver - testng

garvitagirotraev

I want to run test in parallel.


 My driver is instantiated in base constructor and url and login are done in @BeforeTest. While running parallel = 'classes', @BeforeClass is not working correctly. Please find link to demo project https://github.com/reactJestuser/DemoParallelRun/tree/master/DemoRun


I am running 2 test in parallel, one browser opens and login credentials are entered twice while for other test only browser is instantiated, url and login details are not entered.

Also, is there any way I can use same session to run test in parallel? so that every time browser is opened, its already logged in.


Thanks !!

--
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: Run @BeforeTest in same thread - paralle run - Selenium webdriver - testng

garvitagirotraev
I tried group-by-instance = true and also checked thread id in @BeforeClass. @BeforeClass is starting in same thread as driver still its not working.

On Thursday, April 19, 2018 at 12:22:26 AM UTC+5:30, [hidden email] wrote:

I want to run test in parallel.


 My driver is instantiated in base constructor and url and login are done in @BeforeTest. While running parallel = 'classes', @BeforeClass is not working correctly. Please find link to demo project <a href="https://github.com/reactJestuser/DemoParallelRun/tree/master/DemoRun" rel="nofollow" style="font-family:inherit;font-style:inherit;font-variant:inherit;font-weight:inherit;font-stretch:inherit;line-height:inherit;vertical-align:baseline;color:rgb(0,89,153)" target="_blank" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2FreactJestuser%2FDemoParallelRun%2Ftree%2Fmaster%2FDemoRun\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHc2OTPXmZgu0O379mER_W3mwR1ng&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2FreactJestuser%2FDemoParallelRun%2Ftree%2Fmaster%2FDemoRun\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHc2OTPXmZgu0O379mER_W3mwR1ng&#39;;return true;">https://github.com/reactJestuser/DemoParallelRun/tree/master/DemoRun


I am running 2 test in parallel, one browser opens and login credentials are entered twice while for other test only browser is instantiated, url and login details are not entered.

Also, is there any way I can use same session to run test in parallel? so that every time browser is opened, its already logged in.


Thanks !!

--
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: Run @BeforeTest in same thread - paralle run - Selenium webdriver - testng

Scott Babcock
In reply to this post by garvitagirotraev
Your demo project confuses me. 
  • You're allocating the driver in the class constructor, which means that you'll only ever get one driver per class regardless of the number of test methods in the class.
  • You're performing navigation and login operations in a @BeforeSuite method, which is why this set of actions only happens once. The suite is the outermost level of test hierarchy in TestNG.
I think you want to allocate the driver and preform navigation/login in a @BeforeTest method instead. This certainly makes a lot more sense for most scenarios.

Check out the Selenium Foundation library (https://github.com/Nordstrom/Selenium-Foundation). This library enables you to build your tests with this sort of execution flow with a lot effort. Among other things, it will automatically allocate a driver and navigate to your specified initial page, and it will propagate the driver from the @BeforeTest method to the test methods for you.

On Wednesday, April 18, 2018 at 11:52:26 AM UTC-7, [hidden email] wrote:

I want to run test in parallel.


 My driver is instantiated in base constructor and url and login are done in @BeforeTest. While running parallel = 'classes', @BeforeClass is not working correctly. Please find link to demo project <a href="https://github.com/reactJestuser/DemoParallelRun/tree/master/DemoRun" rel="nofollow" style="font-family:inherit;font-style:inherit;font-variant:inherit;font-weight:inherit;font-stretch:inherit;line-height:inherit;vertical-align:baseline;color:rgb(0,89,153)" target="_blank" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2FreactJestuser%2FDemoParallelRun%2Ftree%2Fmaster%2FDemoRun\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHc2OTPXmZgu0O379mER_W3mwR1ng&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2FreactJestuser%2FDemoParallelRun%2Ftree%2Fmaster%2FDemoRun\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHc2OTPXmZgu0O379mER_W3mwR1ng&#39;;return true;">https://github.com/reactJestuser/DemoParallelRun/tree/master/DemoRun


I am running 2 test in parallel, one browser opens and login credentials are entered twice while for other test only browser is instantiated, url and login details are not entered.

Also, is there any way I can use same session to run test in parallel? so that every time browser is opened, its already logged in.


Thanks !!

--
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: Run @BeforeTest in same thread - paralle run - Selenium webdriver - testng

Scott Babcock
One other thing... You've defined the storage for your driver object as 'static' in your base class, which means you only ever have one, regardless of the number of sub-classes you define. Consequently, you'll only be able to interact with the most recently allocated driver. In the case of your demo project, the reference to the first driver will be overwritten by the second driver.

In TestNG, you should store values like the driver object in test properties. The TestNG Foundation library (https://github.com/Nordstrom/TestNG-Foundation) includes a feature that automatically propagates test property values from *before* method to test method to *after* method. Selenium Foundation uses this feature to propagate the driver objects it creates.

On Sunday, April 29, 2018 at 7:19:06 PM UTC-7, Scott Babcock wrote:
Your demo project confuses me. 
  • You're allocating the driver in the class constructor, which means that you'll only ever get one driver per class regardless of the number of test methods in the class.
  • You're performing navigation and login operations in a @BeforeSuite method, which is why this set of actions only happens once. The suite is the outermost level of test hierarchy in TestNG.
I think you want to allocate the driver and preform navigation/login in a @BeforeTest method instead. This certainly makes a lot more sense for most scenarios.

Check out the Selenium Foundation library (<a href="https://github.com/Nordstrom/Selenium-Foundation" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2FNordstrom%2FSelenium-Foundation\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNGdcpQcQWvEXWh_rWtyqSaXrQc7DQ&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2FNordstrom%2FSelenium-Foundation\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNGdcpQcQWvEXWh_rWtyqSaXrQc7DQ&#39;;return true;">https://github.com/Nordstrom/Selenium-Foundation). This library enables you to build your tests with this sort of execution flow with a lot effort. Among other things, it will automatically allocate a driver and navigate to your specified initial page, and it will propagate the driver from the @BeforeTest method to the test methods for you.

On Wednesday, April 18, 2018 at 11:52:26 AM UTC-7, [hidden email] wrote:

I want to run test in parallel.


 My driver is instantiated in base constructor and url and login are done in @BeforeTest. While running parallel = 'classes', @BeforeClass is not working correctly. Please find link to demo project <a href="https://github.com/reactJestuser/DemoParallelRun/tree/master/DemoRun" rel="nofollow" style="font-family:inherit;font-style:inherit;font-variant:inherit;font-weight:inherit;font-stretch:inherit;line-height:inherit;vertical-align:baseline;color:rgb(0,89,153)" target="_blank" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2FreactJestuser%2FDemoParallelRun%2Ftree%2Fmaster%2FDemoRun\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHc2OTPXmZgu0O379mER_W3mwR1ng&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2FreactJestuser%2FDemoParallelRun%2Ftree%2Fmaster%2FDemoRun\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHc2OTPXmZgu0O379mER_W3mwR1ng&#39;;return true;">https://github.com/reactJestuser/DemoParallelRun/tree/master/DemoRun


I am running 2 test in parallel, one browser opens and login credentials are entered twice while for other test only browser is instantiated, url and login details are not entered.

Also, is there any way I can use same session to run test in parallel? so that every time browser is opened, its already logged in.


Thanks !!

--
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: Run @BeforeTest in same thread - paralle run - Selenium webdriver - testng

Krishnan Mahadevan

Scott,

There are other ways in which the driver object can be made available to a @Test method in a threadsafe manner. It needn’t be via properties always.

 

One could:

  1. Do it via ThreadLocale variables which get updated/cleanedup via IInvokedMethodListener implementations through its beforeInvocation()/afterInvocation()
  2. Do it via a @BeforeMethod and @AfterMethod wherein the config method just packs the driver object as a special attribute in the @Test method’s ITestResult object.

 

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 Scott Babcock <[hidden email]>
Reply-To: <[hidden email]>
Date: Monday, April 30, 2018 at 8:10 AM
To: testng-users <[hidden email]>
Subject: [testng-users] Re: Run @BeforeTest in same thread - paralle run - Selenium webdriver - testng

 

One other thing... You've defined the storage for your driver object as 'static' in your base class, which means you only ever have one, regardless of the number of sub-classes you define. Consequently, you'll only be able to interact with the most recently allocated driver. In the case of your demo project, the reference to the first driver will be overwritten by the second driver.

 

In TestNG, you should store values like the driver object in test properties. The TestNG Foundation library (https://github.com/Nordstrom/TestNG-Foundation) includes a feature that automatically propagates test property values from *before* method to test method to *after* method. Selenium Foundation uses this feature to propagate the driver objects it creates.

On Sunday, April 29, 2018 at 7:19:06 PM UTC-7, Scott Babcock wrote:

Your demo project confuses me. 

  • You're allocating the driver in the class constructor, which means that you'll only ever get one driver per class regardless of the number of test methods in the class.
  • You're performing navigation and login operations in a @BeforeSuite method, which is why this set of actions only happens once. The suite is the outermost level of test hierarchy in TestNG.

I think you want to allocate the driver and preform navigation/login in a @BeforeTest method instead. This certainly makes a lot more sense for most scenarios.

 

Check out the Selenium Foundation library (https://github.com/Nordstrom/Selenium-Foundation). This library enables you to build your tests with this sort of execution flow with a lot effort. Among other things, it will automatically allocate a driver and navigate to your specified initial page, and it will propagate the driver from the @BeforeTest method to the test methods for you.


On Wednesday, April 18, 2018 at 11:52:26 AM UTC-7, [hidden email] wrote:

I want to run test in parallel.

 

 My driver is instantiated in base constructor and url and login are done in @BeforeTest. While running parallel = 'classes', @BeforeClass is not working correctly. Please find link to demo project https://github.com/reactJestuser/DemoParallelRun/tree/master/DemoRun

 

I am running 2 test in parallel, one browser opens and login credentials are entered twice while for other test only browser is instantiated, url and login details are not entered.

Also, is there any way I can use same session to run test in parallel? so that every time browser is opened, its already logged in.

 

Thanks !!

--
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: Run @BeforeTest in same thread - paralle run - Selenium webdriver - testng

Scott Babcock
You could use ThreadLocal, but why take the roll-your-own approach when the framework provides a built-in facility designed specifically for this purpose?

As for your second option, this *is* the test properties to which I'm referring. The challenge is that each phase of test execution gets a different test result object. The @BeforeMethod method doesn't have access to the test result object of the @Test method. In fact, it doesn't even exist at that point. This is the issue that TestNG Foundation handles for you - propagating test properties from one phase to the next.

On Sunday, April 29, 2018 at 7:43:23 PM UTC-7, Krishnan Mahadevan wrote:

Scott,

There are other ways in which the driver object can be made available to a @Test method in a threadsafe manner. It needn’t be via properties always.

 

One could:

  1. Do it via ThreadLocale variables which get updated/cleanedup via IInvokedMethodListener implementations through its beforeInvocation()/afterInvocation()
  2. Do it via a @BeforeMethod and @AfterMethod wherein the config method just packs the driver object as a special attribute in the @Test method’s ITestResult object.

 

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="3Umdu0MpBAAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">testng...@...> on behalf of Scott Babcock <<a href="javascript:" target="_blank" gdf-obfuscated-mailto="3Umdu0MpBAAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">sco...@...>
Reply-To: <<a href="javascript:" target="_blank" gdf-obfuscated-mailto="3Umdu0MpBAAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">testng...@...>
Date: Monday, April 30, 2018 at 8:10 AM
To: testng-users <<a href="javascript:" target="_blank" gdf-obfuscated-mailto="3Umdu0MpBAAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">testng...@...>
Subject: [testng-users] Re: Run @BeforeTest in same thread - paralle run - Selenium webdriver - testng

 

One other thing... You've defined the storage for your driver object as 'static' in your base class, which means you only ever have one, regardless of the number of sub-classes you define. Consequently, you'll only be able to interact with the most recently allocated driver. In the case of your demo project, the reference to the first driver will be overwritten by the second driver.

 

In TestNG, you should store values like the driver object in test properties. The TestNG Foundation library (<a href="https://github.com/Nordstrom/TestNG-Foundation" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2FNordstrom%2FTestNG-Foundation\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNGc8_sMCtGoijoSYGQ1qjtuyfi6aQ&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2FNordstrom%2FTestNG-Foundation\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNGc8_sMCtGoijoSYGQ1qjtuyfi6aQ&#39;;return true;">https://github.com/Nordstrom/TestNG-Foundation) includes a feature that automatically propagates test property values from *before* method to test method to *after* method. Selenium Foundation uses this feature to propagate the driver objects it creates.

On Sunday, April 29, 2018 at 7:19:06 PM UTC-7, Scott Babcock wrote:

Your demo project confuses me. 

  • You're allocating the driver in the class constructor, which means that you'll only ever get one driver per class regardless of the number of test methods in the class.
  • You're performing navigation and login operations in a @BeforeSuite method, which is why this set of actions only happens once. The suite is the outermost level of test hierarchy in TestNG.

I think you want to allocate the driver and preform navigation/login in a @BeforeTest method instead. This certainly makes a lot more sense for most scenarios.

 

Check out the Selenium Foundation library (<a href="https://github.com/Nordstrom/Selenium-Foundation" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2FNordstrom%2FSelenium-Foundation\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNGdcpQcQWvEXWh_rWtyqSaXrQc7DQ&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2FNordstrom%2FSelenium-Foundation\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNGdcpQcQWvEXWh_rWtyqSaXrQc7DQ&#39;;return true;">https://github.com/Nordstrom/Selenium-Foundation). This library enables you to build your tests with this sort of execution flow with a lot effort. Among other things, it will automatically allocate a driver and navigate to your specified initial page, and it will propagate the driver from the @BeforeTest method to the test methods for you.


On Wednesday, April 18, 2018 at 11:52:26 AM UTC-7, [hidden email] wrote:

I want to run test in parallel.

 

 My driver is instantiated in base constructor and url and login are done in @BeforeTest. While running parallel = 'classes', @BeforeClass is not working correctly. Please find link to demo project <a href="https://github.com/reactJestuser/DemoParallelRun/tree/master/DemoRun" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2FreactJestuser%2FDemoParallelRun%2Ftree%2Fmaster%2FDemoRun\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHc2OTPXmZgu0O379mER_W3mwR1ng&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2FreactJestuser%2FDemoParallelRun%2Ftree%2Fmaster%2FDemoRun\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHc2OTPXmZgu0O379mER_W3mwR1ng&#39;;return true;">https://github.com/reactJestuser/DemoParallelRun/tree/master/DemoRun

 

I am running 2 test in parallel, one browser opens and login credentials are entered twice while for other test only browser is instantiated, url and login details are not entered.

Also, is there any way I can use same session to run test in parallel? so that every time browser is opened, its already logged in.

 

Thanks !!

--
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="3Umdu0MpBAAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">testng-users+unsubscribe@googlegroups.com.
To post to this group, send email to
<a href="javascript:" target="_blank" gdf-obfuscated-mailto="3Umdu0MpBAAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">testng-users@....
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: Run @BeforeTest in same thread - paralle run - Selenium webdriver - testng

Krishnan Mahadevan

Scott,

 

>>> You could use ThreadLocal, but why take the roll-your-own approach when the framework provides a built-in facility designed specifically for this purpose?

 

The reason why I personally prefer a ThreadLocal variant against a ITestResult packed attribute is because:

  1. You need to ensure that your consumers don’t end up using the same attribute, else they could overwrite the webdriver instance.
  2. Since the ITestResult is also used by TestNG internally, we would need to ensure that we get rid of the webdriver attribute after usage, else we will end-up bloating the memory with all stale webdriver instances (Remember ITestResult for a @Test method is never cleaned up until TestNG exits).

 

ThreadLocal inheritantly keeps all of these confusions at bay.

 

>>> The @BeforeMethod method doesn't have access to the test result object of the @Test method. In fact, it doesn't even exist at that point.

 

Are you sure?

TestNG supports something called Native Injection and one of the things that TestNG lets you inject into a @BeforeMethod is the ITestResult object of the @Test method that is *about to be executed*

 

You can refer to the table here: http://testng.org/doc/documentation-main.html#native-dependency-injection

 

Here’s a sample that shows this in action using the latest released version of TestNG v6.14.3

 

import org.testng.Assert;
import org.testng.ITestResult;
import org.testng.Reporter;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

public class NativeInjection {
 
private static final String KEY = "key";
 
private static final String VALUE = "Krishnan";

 
@BeforeMethod
 
public void beforeMethod(ITestResult result) {
   
// Adding an assert to showcase that its indeed the "to be run @Test method's ITestResult
    // object" that is getting injected here.
   
Assert.assertEquals(result.getMethod().getMethodName(), "testMethod");
    result.setAttribute(
KEY, VALUE);
  }

 
@Test
 
public void testMethod() {
    String actualValue = Reporter.getCurrentTestResult().getAttribute(
KEY).toString();
    Assert.assertEquals(actualValue,
VALUE);
  }
}

 

 

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 Scott Babcock <[hidden email]>
Reply-To: <[hidden email]>
Date: Monday, April 30, 2018 at 8:45 AM
To: testng-users <[hidden email]>
Subject: Re: [testng-users] Re: Run @BeforeTest in same thread - paralle run - Selenium webdriver - testng

 

You could use ThreadLocal, but why take the roll-your-own approach when the framework provides a built-in facility designed specifically for this purpose?

 

As for your second option, this *is* the test properties to which I'm referring. The challenge is that each phase of test execution gets a different test result object. The @BeforeMethod method doesn't have access to the test result object of the @Test method. In fact, it doesn't even exist at that point. This is the issue that TestNG Foundation handles for you - propagating test properties from one phase to the next.

On Sunday, April 29, 2018 at 7:43:23 PM UTC-7, Krishnan Mahadevan wrote:

Scott,

There are other ways in which the driver object can be made available to a @Test method in a threadsafe manner. It needn’t be via properties always.

 

One could:

  1. Do it via ThreadLocale variables which get updated/cleanedup via IInvokedMethodListener implementations through its beforeInvocation()/afterInvocation()
  2. Do it via a @BeforeMethod and @AfterMethod wherein the config method just packs the driver object as a special attribute in the @Test method’s ITestResult object.

 

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 Scott Babcock <<a href="javascript:" target="_blank">sco...@...>
Reply-To: <
<a href="javascript:" target="_blank">testng...@...>
Date: Monday, April 30, 2018 at 8:10 AM
To: testng-users <
<a href="javascript:" target="_blank">testng...@...>
Subject: [testng-users] Re: Run @BeforeTest in same thread - paralle run - Selenium webdriver - testng

 

One other thing... You've defined the storage for your driver object as 'static' in your base class, which means you only ever have one, regardless of the number of sub-classes you define. Consequently, you'll only be able to interact with the most recently allocated driver. In the case of your demo project, the reference to the first driver will be overwritten by the second driver.

 

In TestNG, you should store values like the driver object in test properties. The TestNG Foundation library (https://github.com/Nordstrom/TestNG-Foundation) includes a feature that automatically propagates test property values from *before* method to test method to *after* method. Selenium Foundation uses this feature to propagate the driver objects it creates.

On Sunday, April 29, 2018 at 7:19:06 PM UTC-7, Scott Babcock wrote:

Your demo project confuses me. 

  • You're allocating the driver in the class constructor, which means that you'll only ever get one driver per class regardless of the number of test methods in the class.
  • You're performing navigation and login operations in a @BeforeSuite method, which is why this set of actions only happens once. The suite is the outermost level of test hierarchy in TestNG.

I think you want to allocate the driver and preform navigation/login in a @BeforeTest method instead. This certainly makes a lot more sense for most scenarios.

 

Check out the Selenium Foundation library (https://github.com/Nordstrom/Selenium-Foundation). This library enables you to build your tests with this sort of execution flow with a lot effort. Among other things, it will automatically allocate a driver and navigate to your specified initial page, and it will propagate the driver from the @BeforeTest method to the test methods for you.


On Wednesday, April 18, 2018 at 11:52:26 AM UTC-7, [hidden email] wrote:

I want to run test in parallel.

 

 My driver is instantiated in base constructor and url and login are done in @BeforeTest. While running parallel = 'classes', @BeforeClass is not working correctly. Please find link to demo project https://github.com/reactJestuser/DemoParallelRun/tree/master/DemoRun

 

I am running 2 test in parallel, one browser opens and login credentials are entered twice while for other test only browser is instantiated, url and login details are not entered.

Also, is there any way I can use same session to run test in parallel? so that every time browser is opened, its already logged in.

 

Thanks !!

--
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+unsubscribe@....
To post to this group, send email to
<a href="javascript:" target="_blank">testng-users@....
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: Run @BeforeTest in same thread - paralle run - Selenium webdriver - testng

Scott Babcock
Ah! I thought I recognized that name!

The TestNG documentation is unclear about the behavior of native injection in the @BeforeMethod method. Also, I haven't updated from TestNG 6.10 due to an issue with IInvokedMethodListener that didn't get resolved until late last year. (https://github.com/cbeust/testng/issues/1465)

I just ran a quick check of 6.14.3, and there are still issues with how this behaves. When a test gets skipped from @BeforeMethod, the management of test result object for the test method gets a bit erratic.The result stored for the skipped test in the TestListenerAdapter is not the same as the one passed into the @BeforeMethod method for the skipped test. Not sure how that happens, but it's certainly unexpected.

However, I'd rather not force users of my TestNG library to remember to inject the test result object if I have another way to handle this issue. I use InheritableThreadLocal variables for propagate attribute from one phase to the next, so I guess my approach is a hybrid. Users of my library don't need to understand the implementation details, though.

A test result object is attached to one - and only one - test execution phase. There's no danger of one test overwriting an attribute for another test. I've been using test attributes to store driver objects for years, running thousands of tests per run, and never encountered any issues related to memory usage. It's standard practice to close the driver at the end of each test, regardless of the strategy employed to store the driver object.

If you're running tests in series, the entire run occurs on a single thread. For parallel execution, however, multiple threads are employed. This makes the ThreadLocal approach a bit tricky to implement correctly.

However, each test gets its own new test result object to play with, regardless of serial/parallel execution mode. This greatly simplifies your implementation.

On Sunday, April 29, 2018 at 8:36:06 PM UTC-7, Krishnan Mahadevan wrote:

Scott,

 

>>> You could use ThreadLocal, but why take the roll-your-own approach when the framework provides a built-in facility designed specifically for this purpose?

 

The reason why I personally prefer a ThreadLocal variant against a ITestResult packed attribute is because:

  1. You need to ensure that your consumers don’t end up using the same attribute, else they could overwrite the webdriver instance.
  2. Since the ITestResult is also used by TestNG internally, we would need to ensure that we get rid of the webdriver attribute after usage, else we will end-up bloating the memory with all stale webdriver instances (Remember ITestResult for a @Test method is never cleaned up until TestNG exits).

 

ThreadLocal inheritantly keeps all of these confusions at bay.

 

>>> The @BeforeMethod method doesn't have access to the test result object of the @Test method. In fact, it doesn't even exist at that point.

 

Are you sure?

TestNG supports something called Native Injection and one of the things that TestNG lets you inject into a @BeforeMethod is the ITestResult object of the @Test method that is *about to be executed*

 

You can refer to the table here: <a href="http://testng.org/doc/documentation-main.html#native-dependency-injection" target="_blank" rel="nofollow" onmousedown="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Ftestng.org%2Fdoc%2Fdocumentation-main.html%23native-dependency-injection\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNGezhC1wUSDaui0PSu9qt8csftgTA&#39;;return true;" onclick="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Ftestng.org%2Fdoc%2Fdocumentation-main.html%23native-dependency-injection\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNGezhC1wUSDaui0PSu9qt8csftgTA&#39;;return true;">http://testng.org/doc/documentation-main.html#native-dependency-injection

 

Here’s a sample that shows this in action using the latest released version of TestNG v6.14.3

 

import org.testng.Assert;
import org.testng.ITestResult;
import org.testng.Reporter;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

public class NativeInjection {
 
private static final String KEY = "key";
 
private static final String VALUE = "Krishnan";

 
@BeforeMethod
 
public void beforeMethod(ITestResult result) {
   
// Adding an assert to showcase that its indeed the "to be run @Test method's ITestResult
    // object" that is getting injected here.
   
Assert.assertEquals(result.getMethod().getMethodName(), "testMethod");
    result.setAttribute(
KEY, VALUE);
  }

 
@Test
 
public void testMethod() {
    String actualValue = Reporter.getCurrentTestResult().getAttribute(
KEY).toString();
    Assert.assertEquals(actualValue,
VALUE);
  }
}

 

 

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="GkrjByQsBAAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">testng...@...> on behalf of Scott Babcock <<a href="javascript:" target="_blank" gdf-obfuscated-mailto="GkrjByQsBAAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">sco...@...>
Reply-To: <<a href="javascript:" target="_blank" gdf-obfuscated-mailto="GkrjByQsBAAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">testng...@...>
Date: Monday, April 30, 2018 at 8:45 AM
To: testng-users <<a href="javascript:" target="_blank" gdf-obfuscated-mailto="GkrjByQsBAAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">testng...@...>
Subject: Re: [testng-users] Re: Run @BeforeTest in same thread - paralle run - Selenium webdriver - testng

 

You could use ThreadLocal, but why take the roll-your-own approach when the framework provides a built-in facility designed specifically for this purpose?

 

As for your second option, this *is* the test properties to which I'm referring. The challenge is that each phase of test execution gets a different test result object. The @BeforeMethod method doesn't have access to the test result object of the @Test method. In fact, it doesn't even exist at that point. This is the issue that TestNG Foundation handles for you - propagating test properties from one phase to the next.

On Sunday, April 29, 2018 at 7:43:23 PM UTC-7, Krishnan Mahadevan wrote:

Scott,

There are other ways in which the driver object can be made available to a @Test method in a threadsafe manner. It needn’t be via properties always.

 

One could:

  1. Do it via ThreadLocale variables which get updated/cleanedup via IInvokedMethodListener implementations through its beforeInvocation()/afterInvocation()
  2. Do it via a @BeforeMethod and @AfterMethod wherein the config method just packs the driver object as a special attribute in the @Test method’s ITestResult object.

 

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 Scott Babcock <[hidden email]>
Reply-To: <
[hidden email]>
Date: Monday, April 30, 2018 at 8:10 AM
To: testng-users <
[hidden email]>
Subject: [testng-users] Re: Run @BeforeTest in same thread - paralle run - Selenium webdriver - testng

 

One other thing... You've defined the storage for your driver object as 'static' in your base class, which means you only ever have one, regardless of the number of sub-classes you define. Consequently, you'll only be able to interact with the most recently allocated driver. In the case of your demo project, the reference to the first driver will be overwritten by the second driver.

 

In TestNG, you should store values like the driver object in test properties. The TestNG Foundation library (<a href="https://github.com/Nordstrom/TestNG-Foundation" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2FNordstrom%2FTestNG-Foundation\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNGc8_sMCtGoijoSYGQ1qjtuyfi6aQ&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2FNordstrom%2FTestNG-Foundation\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNGc8_sMCtGoijoSYGQ1qjtuyfi6aQ&#39;;return true;">https://github.com/Nordstrom/TestNG-Foundation) includes a feature that automatically propagates test property values from *before* method to test method to *after* method. Selenium Foundation uses this feature to propagate the driver objects it creates.

On Sunday, April 29, 2018 at 7:19:06 PM UTC-7, Scott Babcock wrote:

Your demo project confuses me. 

  • You're allocating the driver in the class constructor, which means that you'll only ever get one driver per class regardless of the number of test methods in the class.
  • You're performing navigation and login operations in a @BeforeSuite method, which is why this set of actions only happens once. The suite is the outermost level of test hierarchy in TestNG.

I think you want to allocate the driver and preform navigation/login in a @BeforeTest method instead. This certainly makes a lot more sense for most scenarios.

 

Check out the Selenium Foundation library (<a href="https://github.com/Nordstrom/Selenium-Foundation" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2FNordstrom%2FSelenium-Foundation\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNGdcpQcQWvEXWh_rWtyqSaXrQc7DQ&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2FNordstrom%2FSelenium-Foundation\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNGdcpQcQWvEXWh_rWtyqSaXrQc7DQ&#39;;return true;">https://github.com/Nordstrom/Selenium-Foundation). This library enables you to build your tests with this sort of execution flow with a lot effort. Among other things, it will automatically allocate a driver and navigate to your specified initial page, and it will propagate the driver from the @BeforeTest method to the test methods for you.


On Wednesday, April 18, 2018 at 11:52:26 AM UTC-7, [hidden email] wrote:

I want to run test in parallel.

 

 My driver is instantiated in base constructor and url and login are done in @BeforeTest. While running parallel = 'classes', @BeforeClass is not working correctly. Please find link to demo project <a href="https://github.com/reactJestuser/DemoParallelRun/tree/master/DemoRun" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2FreactJestuser%2FDemoParallelRun%2Ftree%2Fmaster%2FDemoRun\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHc2OTPXmZgu0O379mER_W3mwR1ng&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2FreactJestuser%2FDemoParallelRun%2Ftree%2Fmaster%2FDemoRun\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHc2OTPXmZgu0O379mER_W3mwR1ng&#39;;return true;">https://github.com/reactJestuser/DemoParallelRun/tree/master/DemoRun

 

I am running 2 test in parallel, one browser opens and login credentials are entered twice while for other test only browser is instantiated, url and login details are not entered.

Also, is there any way I can use same session to run test in parallel? so that every time browser is opened, its already logged in.

 

Thanks !!

--
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+unsubscribe@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="GkrjByQsBAAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">testng-users+unsubscribe@googlegroups.com.
To post to this group, send email to
<a href="javascript:" target="_blank" gdf-obfuscated-mailto="GkrjByQsBAAJ" rel="nofollow" onmousedown="this.href=&#39;javascript:&#39;;return true;" onclick="this.href=&#39;javascript:&#39;;return true;">testng-users@....
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: Run @BeforeTest in same thread - paralle run - Selenium webdriver - testng

Krishnan Mahadevan
Scott,

>>>> Ah! I thought I recognized that name!

Hehehe.. glad you did :) 

>>>> Also, I haven't updated from TestNG 6.10 due to an issue with IInvokedMethodListener that didn't get resolved until late last year. (https://github.com/cbeust/testng/issues/1465)

I believe this issue was fixed. If this is still a problem, I would request you to file a new issue with a sample to reproduce this, so that we can get it fixed in the upcoming TestNG release [7.0.0]

>>>> I just ran a quick check of 6.14.3, and there are still issues with how this behaves. When a test gets skipped from @BeforeMethod, the management of test result object for the test method gets a bit erratic.The result stored for the skipped test in the TestListenerAdapter is not the same as the one passed into the @BeforeMethod method for the skipped test. Not sure how that happens, but it's certainly unexpected.

I think what you are describing here perhaps has something to do with GITHUB-1753  which I have fixed in "master" and should be available in TestNG 7.0.0. Can you please give it a quick try using TestNG 7.0.0-SNAPSHOT and see if it goes away. If not, I request you to please help file an issue and add a sample that can be used to reproduce the problem.

>>>> However, I'd rather not force users of my TestNG library to remember to inject the test result object if I have another way to handle this issue. I use InheritableThreadLocal variables for propagate attribute from one phase to the next, so I guess my approach is a hybrid. Users of my library don't need to understand the implementation details, though.

Yes InheritableThreadLocal would be better equipped since it passes the current thread's local variables copies to all the child threads that the current thread spawns. 

>>>> I've been using test attributes to store driver objects for years, running thousands of tests per run, and never encountered any issues related to memory usage. It's standard practice to close the driver at the end of each test, regardless of the strategy employed to store the driver object.

The observation wasn't meant to nitpick on what you have built as a library. I have not looked at your implementation and so it would be unfair on my part to jump to conclusions. I only intended to make it as a generic observation. Attributes attached to an ITestResult object will continue to reside in memory and will not be GC'ed until the JVM exits. So if one resorts to attaching objects that are huge in memory footprint, then one tends to run into risks of OutOfMemoryErrors. The WebDriver object even though quit() and cleaned up from WebDriver's perspective, still is an Object with states (All WebDrivers hold references to an Executor, ErrorHandler etc.,). So until the attribute has been nullified, it would always be a problem until setAttribute("key", null) is called on the corresponding ITestResult object.

I dont want to hijack this thread more than what it already has been :)

So Scott, if there are any more issues with respect to TestNG, I would request you to please help log issues and attach samples. I will get to them as quickly as I can.

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/

On Mon, Apr 30, 2018 at 11:50 AM, Scott Babcock <[hidden email]> wrote:
Ah! I thought I recognized that name!

The TestNG documentation is unclear about the behavior of native injection in the @BeforeMethod method. Also, I haven't updated from TestNG 6.10 due to an issue with IInvokedMethodListener that didn't get resolved until late last year. (https://github.com/cbeust/testng/issues/1465)

I just ran a quick check of 6.14.3, and there are still issues with how this behaves. When a test gets skipped from @BeforeMethod, the management of test result object for the test method gets a bit erratic.The result stored for the skipped test in the TestListenerAdapter is not the same as the one passed into the @BeforeMethod method for the skipped test. Not sure how that happens, but it's certainly unexpected.

However, I'd rather not force users of my TestNG library to remember to inject the test result object if I have another way to handle this issue. I use InheritableThreadLocal variables for propagate attribute from one phase to the next, so I guess my approach is a hybrid. Users of my library don't need to understand the implementation details, though.

A test result object is attached to one - and only one - test execution phase. There's no danger of one test overwriting an attribute for another test. I've been using test attributes to store driver objects for years, running thousands of tests per run, and never encountered any issues related to memory usage. It's standard practice to close the driver at the end of each test, regardless of the strategy employed to store the driver object.

If you're running tests in series, the entire run occurs on a single thread. For parallel execution, however, multiple threads are employed. This makes the ThreadLocal approach a bit tricky to implement correctly.

However, each test gets its own new test result object to play with, regardless of serial/parallel execution mode. This greatly simplifies your implementation.

On Sunday, April 29, 2018 at 8:36:06 PM UTC-7, Krishnan Mahadevan wrote:

Scott,

 

>>> You could use ThreadLocal, but why take the roll-your-own approach when the framework provides a built-in facility designed specifically for this purpose?

 

The reason why I personally prefer a ThreadLocal variant against a ITestResult packed attribute is because:

  1. You need to ensure that your consumers don’t end up using the same attribute, else they could overwrite the webdriver instance.
  2. Since the ITestResult is also used by TestNG internally, we would need to ensure that we get rid of the webdriver attribute after usage, else we will end-up bloating the memory with all stale webdriver instances (Remember ITestResult for a @Test method is never cleaned up until TestNG exits).

 

ThreadLocal inheritantly keeps all of these confusions at bay.

 

>>> The @BeforeMethod method doesn't have access to the test result object of the @Test method. In fact, it doesn't even exist at that point.

 

Are you sure?

TestNG supports something called Native Injection and one of the things that TestNG lets you inject into a @BeforeMethod is the ITestResult object of the @Test method that is *about to be executed*

 

You can refer to the table here: http://testng.org/doc/documentation-main.html#native-dependency-injection

 

Here’s a sample that shows this in action using the latest released version of TestNG v6.14.3

 

import org.testng.Assert;
import org.testng.ITestResult;
import org.testng.Reporter;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

public class NativeInjection {
 
private static final String KEY = "key";
 
private static final String VALUE = "Krishnan";

 
@BeforeMethod
 
public void beforeMethod(ITestResult result) {
   
// Adding an assert to showcase that its indeed the "to be run @Test method's ITestResult
    // object" that is getting injected here.
   
Assert.assertEquals(result.getMethod().getMethodName(), "testMethod");
    result.setAttribute(
KEY, VALUE);
  }

 
@Test
 
public void testMethod() {
    String actualValue = Reporter.getCurrentTestResult().getAttribute(
KEY).toString();
    Assert.assertEquals(actualValue,
VALUE);
  }
}

 

 

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 Scott Babcock <[hidden email]>
Reply-To: <[hidden email]>
Date: Monday, April 30, 2018 at 8:45 AM


To: testng-users <[hidden email]>
Subject: Re: [testng-users] Re: Run @BeforeTest in same thread - paralle run - Selenium webdriver - testng

 

You could use ThreadLocal, but why take the roll-your-own approach when the framework provides a built-in facility designed specifically for this purpose?

 

As for your second option, this *is* the test properties to which I'm referring. The challenge is that each phase of test execution gets a different test result object. The @BeforeMethod method doesn't have access to the test result object of the @Test method. In fact, it doesn't even exist at that point. This is the issue that TestNG Foundation handles for you - propagating test properties from one phase to the next.

On Sunday, April 29, 2018 at 7:43:23 PM UTC-7, Krishnan Mahadevan wrote:

Scott,

There are other ways in which the driver object can be made available to a @Test method in a threadsafe manner. It needn’t be via properties always.

 

One could:

  1. Do it via ThreadLocale variables which get updated/cleanedup via IInvokedMethodListener implementations through its beforeInvocation()/afterInvocation()
  2. Do it via a @BeforeMethod and @AfterMethod wherein the config method just packs the driver object as a special attribute in the @Test method’s ITestResult object.

 

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 Scott Babcock <[hidden email]>
Reply-To: <
[hidden email]>
Date: Monday, April 30, 2018 at 8:10 AM
To: testng-users <
[hidden email]>
Subject: [testng-users] Re: Run @BeforeTest in same thread - paralle run - Selenium webdriver - testng

 

One other thing... You've defined the storage for your driver object as 'static' in your base class, which means you only ever have one, regardless of the number of sub-classes you define. Consequently, you'll only be able to interact with the most recently allocated driver. In the case of your demo project, the reference to the first driver will be overwritten by the second driver.

 

In TestNG, you should store values like the driver object in test properties. The TestNG Foundation library (https://github.com/Nordstrom/TestNG-Foundation) includes a feature that automatically propagates test property values from *before* method to test method to *after* method. Selenium Foundation uses this feature to propagate the driver objects it creates.

On Sunday, April 29, 2018 at 7:19:06 PM UTC-7, Scott Babcock wrote:

Your demo project confuses me. 

  • You're allocating the driver in the class constructor, which means that you'll only ever get one driver per class regardless of the number of test methods in the class.
  • You're performing navigation and login operations in a @BeforeSuite method, which is why this set of actions only happens once. The suite is the outermost level of test hierarchy in TestNG.

I think you want to allocate the driver and preform navigation/login in a @BeforeTest method instead. This certainly makes a lot more sense for most scenarios.

 

Check out the Selenium Foundation library (https://github.com/Nordstrom/Selenium-Foundation). This library enables you to build your tests with this sort of execution flow with a lot effort. Among other things, it will automatically allocate a driver and navigate to your specified initial page, and it will propagate the driver from the @BeforeTest method to the test methods for you.


On Wednesday, April 18, 2018 at 11:52:26 AM UTC-7, [hidden email] wrote:

I want to run test in parallel.

 

 My driver is instantiated in base constructor and url and login are done in @BeforeTest. While running parallel = 'classes', @BeforeClass is not working correctly. Please find link to demo project https://github.com/reactJestuser/DemoParallelRun/tree/master/DemoRun

 

I am running 2 test in parallel, one browser opens and login credentials are entered twice while for other test only browser is instantiated, url and login details are not entered.

Also, is there any way I can use same session to run test in parallel? so that every time browser is opened, its already logged in.

 

Thanks !!

--
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+unsubscribe@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.

--
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+unsubscribe@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.

--
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.