Should I quit the browser after each Selenium based automated test? - selenium

I'm trying to make my selenium test as atomic and independent of each other as possible so I decided to quit the browser and create a new Webdriver instance after each test runs. This approach made the more sense to me and was reinforced by several threads discussing this issue.
e. g. This answer to a related question:
You are closing the webdriver after one particular test. This is a good approach but you will need to start a new webdriver for each new test that you want to run.
However, I've also come across the opinion that quitting the browser after each test is unnecessary and ineffective.
e. g. Part of this blog about Selenium:
It’s not good practice to load a browser before each test. Rather, it is much better to load a browser before all tests and then close it after all tests are executed, as this will save resources and test execution time.
As I'm pretty new to all of this, I'm struggling to choose between these two. So far the execution time of my tests is not a real concern (as I only have a handful of them) but as I begin to expand my test suite I'm worried that it might become an issue.

Answering straight, factually there is no definite rules to quit or reuse the same browser client while executing the tests using Selenium. Perhaps the decision would be based on the pre-requisites of the testcases.
If your tests are independent, it would be wise to to quit() the current Webdriver and Browser Client instance and create a new instance of the Webdriver and Browser Client after each test runs which will initiate a new and clean WebDriver / Browser Client combination as discussed in closing browser after test pass.
Albeit it would induce some overhead to spawn the new WebDriver / Browser Client combination but that may provide the much needed cushion from CPU and Memory usage as discussed in:
Limit chrome headless CPU and memory usage
Selenium using too much RAM with Firefox
Incase, the tests are not independent and the tests are based on the same session, cookies, etc parameters, reusing the same WebDriver / Browser Client makes sense.

DebanjanB has a great answer.
I am of the cloth that there is no one-sized-fits-all answer.
There is some fun balance to be had. Depending on what framework you are using, you could get fancy. I like pytest for it's unique use of fixtures.
To this end, you could do tests, or sets of tests either way depending on what you need. You could balance browser load times vs execution for what makes sense.
As an example in pytest:
conftest.py:
import pytest
from selenium import webdriver
#pytest.fixture(scope='module')
def module_browser(request):
"""Fixture lasts for an entire file of tests."""
driver = webdriver.Chrome()
def fin():
driver.quit()
request.addfinalizer(fin())
return driver
#pytest.fixture(scope='function')
def function_browser(request):
"""Fixture lasts for just a test function."""
driver = webdriver.Chrome()
def fin():
driver.quit()
request.addfinalizer(fin())
return driver
Now module_browser() lets you get a browser for a whole test module.
funtion_browser() gives you a new browser per test function.
Lets get fancy.. you have a bunch of tests that need to be logged in, and they are doing cosmetic checks on a standard account:
conftest.py continued...
#pytest.fixture(scope='module')
def logged_in_browser(request):
"""Provide a logged in browser for simple tests."""
driver = webdriver.Opera()
# Now go and log this browser in,
# so we can use the logged in state for tests.
log_in_browser(username='RedMage', password='masmune')
def fin():
driver.quit()
request.addfinalizer(fin())
return driver
This is about the same, but lets you have a browser stay open for a few tests, and it's logged in. If logging in takes say 5 seconds, and you have 30 tests that atomically check cosmetic things, you can shave a few minutes.
This flexibility will let you run some tests faster, and some tests in a more clean state. We might need some of each to run a suite and still be able to get efficiency gains on the time. There is no one-sized-fits-all answer.
Utilizing fixture in pytest lets you choose what you want for each test.. if it should be a clean browser, or if it needs to be faster.
Then in the tests we see stuff like this:
test_things.py
def test_logged_out_assets(function_browser):
driver = function_browser # just for clarity here.
driver.get('http://example.com/')
check_some_stuff(driver)
language_subdomain_list = ['www', 'es', 'de', 'ru', 'cz']
#pytest.parametrize(language_subdomain, language_subdomain_list)
def test_logged_out_assets_multlingual(module_browser, language_subdomain):
"""
Check the assets come up on each language subdomain.
This test will run for each of the subdomains as separate tests.
5 in all.
"""
driver = module_browser # for clarity in example.
url = "http://{}.example.com".format(language_subdomain)
driver.get(url)
check_some_stuff(driver)
def test_logged_in_assets(logged_in_browser):
"""
Check specific assets while logged in.
Remember, our web browser already is logged in when we get it!
"""
driver = logged_in_browser # for clarity in example.
check_some_assets(driver)
Py.test Fixtures: https://docs.pytest.org/en/latest/fixture.html

Related

How can I set maximum concurrent users during my Selenium load test? Load test opens more concurrent users in parallel than I set

While running my load test for 1 or 5 or 10 or so concurrent users, the test runs far more users in parallel. it starts new users before the first thread finishes even though Start thread count is set to some number.
Can I avoid it by setting proper delays? If so how should the delay be set?
I also tried solving it by calling driver.quit() at the end of the test in a try catch block so threads close after exdcution but looks like it doesn't closes the threads (Chrome browser windows in this case) with errors in it.
try{
WebElement myDynamicElement3 = (new WebDriverWait(driver, 10))
.until(ExpectedConditions.presenceOfElementLocated(By.xpath("//*[text()='hello']")));
}catch(Exception e) {
throw new AssertionError("Element not found....", e);
}
driver.quit();
Please help which approach should I try and how.
Unfortunately it is not possible to provide the answer without seeing your Thread Group configuration, the way you instantiate the WebDriver, the way you're handling WebDriver instances between Thread Group iterations, etc.
In the meantime I can only recommend considering using WebDriver Sampler Plugin or at least look into its source code - this way you should learn how to properly instantiate and shut down the browser instances.
And last but not the least, using real browsers for load testing is not the best idea as modern browsers are very resource intensive, each browser instance requires full CPU core and at least 1 GB of RAM and you can simulate at least 100 virtual users using HTTP Request samplers at cost of one browser instance.

How do I clear local storage on remote webdriver session

I am running selenium on remotewebdriver that connects to browser stack to run tests on different browsers. the thing is i have three #Test in my code and at the end of each test the URL is loaded again so I land on the home page again. In Chrome, the first test passes, the second test fails as the previous selection from the first test is remembered in the local storage. Then the 3rd test passes again as the local storage is cleared. In firefox all tests are passing.
I have tried with the code i have pasted in this ticket - i have put it #AfterMethod class in my setup. it clears the local storage in all the tests except no.2 in chrome. without this code, all of the tests are failing except the first one. someone please advise and sorry if it doesn't make sense.
final RemoteExecuteMethod executeMethod = new RemoteExecuteMethod((RemoteWebDriver) driver);
final RemoteWebStorage webStorage = new RemoteWebStorage(executeMethod);
final LocalStorage storage = webStorage.getLocalStorage();
storage.removeItem("sessionState");
I am not sure how to make the code more stable. Any ideas.

Does JMeter measure server response using junit sampler?

I want to integrate some functional tests to the performance tests using JMeter. And if I use JUnit sampler and run tests with starting the browser and execute some actions in the browser(clicks, entering text), what I will get in the JMeter listener: response time including browser speed OR only time of server response without browser execution?
What I do in JMeter:
When I add JUnit sampler and open exported jar file of my test, and run it - test executes like usual web-driver test with browser start and loading UI elements, entering text and clicks. Will loading elements affect the time of the response?
JMeter will measure the time of the whole test case. If it assumes initialisation, launching browser, etc. - it will all be counted of course including the time required for the page to load / elements to render.
If you need to split your test into lesser chunks - consider migrating to WebDriver Sampler, if you choose groovy as the scripting language you will be able to re-use your existing Java code and have better control over what's going on, add sub-results for logical actions, group separate actions together using the Transaction Controller and execute tests in parallel.

Optimizing Selenium tests by bypassing UI

Is there a way to bypass UI for those actions which need to be performed before and (or) after the test? Is it possible to send simple GET or POST requests to the same test session instead of writing the script in the test?
For example, I want to write a test which checks if the record can be deleted. To do that, first of all I need to create the record. It doesn't seem to be a good choice to do it through the UI since it is not part of the test itself.
It really depends on the application under test. You probably don't want to go making SQL calls to your database to create these records, unless you really know what you're doing. Even then, it will make your test automation break when that record changes.
Perhaps your application under test provides an API which will allow you to create a target record. That would be ideal, allowing you to make an API request then all you have to do in the UI is navigate to where the "user" would delete it.
You can do pretty much everything by executing some Javascript into the page.
Here is an example send an HTTP request with a Javascript call:
from selenium import webdriver
driver = webdriver.Firefox()
driver.get("https://www.google.com")
driver.execute_script("""
var r = new XMLHttpRequest();
r.open('POST', '/search', 0);
r.setRequestHeader('Content-type','application/x-www-form-urlencoded');
r.send('q=bill+material&output=xml&client=test&site=operations&access=p');
return r.responseText;
""")
While it may be tempting to setup a test this way, I wouldn't recommend it since it will create new dependencies to the UI, increase the complexity and therefore increase the cost of maintenance of the tests.

Login only once for several test cases - Selenium, JUnit

I am using Selenium 2.X with JUnit 4.X for automation testing. There are several test cases in the test class. However the for each test cases the a new session is created.
That is for each test case,
a new browser window is opened,
login mechanism is carried out,
generic steps gets executed,
test steps gets executed,
the browser get closed.
Is there any possibility for the below mentioned?
a new browser window is opened,
login mechanism is carried out,
generic steps gets executed,
The above steps are carried out only once
all test steps (methods with #Test) gets executed,
Finally the browser gets closed?
PS: I do not want to club all the test case in a single one?
Thanks,
With every new browser session, Selenium creates a new instance of the browser test profile - so re-invoking will cause you to start afresh.
You requirement, though, appears to be more organizational.
Try working with TestNG. It enables the creation of test suites, which can be executed via a testng.xml. You should be able to script tests in different classes and then call them sequentially, without having to necessarily re-invoke the browser