Theme images by Storman. Powered by Blogger.

Software Testing

[best practices][feat1]

Recent

recentposts

Popular

Comments

recentcomments

Most Recent

Random Posts

randomposts

Facebook

page/http://facebook.com/letztest

Wednesday, March 23, 2016

Is maintenance of Selenium Scripts - a hell ???

- No comments
Most times we find ourselves scratching our heads and thinking, 'Why did it fail? It was working perfectly in the local server....'. Timeout or 'Session ID is null or Element not found' (my favorite) errors can be especially annoying when we are currently working on the most famous testing task: make all test pass. Let's analyze together how to fix this unhealthy situation.

First of all we need to redefine our task with management. Why so? Having dummy test methods is definitely not what we want to achieve (and not what managers expect from us). Our real task can be defined as:

Make your tests cover as many functionalities as possible, but avoid false results at ALL COSTS.

I emphasized 'all costs' because I want to make a point which you may find controversial:

Even the most important tests should be excluded from automated suite if they are unstable. After exclusion we need to:

a) prioritize test-fixing task (according to test importance/coverage)
b) perform manual test until automated one isn't stable

Certainly do not run test locally (and do not force programmers to do that...). This approach leads to nowhere.

I know we shouldn't, but what if we depend on other services, DBs, factors?Automated test dependencies should be verified before test execution, and if such one exists test should be ignored.

There is one thing which we often forget about. As a QAs/testers we are responsible for building trust in automated tests throughout team/company. False test results are the single most important factor which reduces (or even destroys) this trust.

Even from the most selfish perspective there is important argument against non-stable tests. Writing/maintaining tests with false results will combine you work image in the eyes of others with word 'FAILURE'. Avoid it at all costs.

Thursday, March 17, 2016

10 tips for improving the speed of selenium script execution

- No comments
As you all know Selenium WebDriver is amazing for test automation. But sometimes automation scripts are slow in general.

What do you do when the scripts are slow?

Do you accept that this is how things are?

Or try to find solutions?

Here are the top 10 tips for improving the speed of  selenium script execution.

Why Are Selenium WebDriver Scripts Slow  ?


We use the Selenium WebDriver framework for automating the functionalities of a web application.

Automation scripts are created using
  • a programming language
  • a unit testing framework
  • the Selenium WebDriver framework

When the automation script is executed, the following happen
  • the browser is started on the computer
  • the site is loaded in the browser
  • the script interacts with the site in the browser

Many factors can impact the script's speed:
  • if the computer is not fast, starting the browser is slow
  • if the internet connection is not fast, loading the site is slow
  • the site can be slow for many reasons (high number of concurrent users, slow servers)
               
10 Tips For Faster Scripts:






#1: Use Few and Fast Locators

When locating an element, start with the fast locators:

1. LOCATE ELEMENT BY ID
This works if the html element has the id attribute.
It is the fastest locator as it uses the optimized document.getElementById() JS command.


2.LOCATE ELEMENT BY NAME
This works if the element has a name attribute.

3. USE A CSS SELECTOR
It is faster than XPATH but not as flexible.

4. USE AN XPATH SELECTOR
This is the most flexible strategy for building locators.
Xpath selectors are slow as the page browser DOM is traversed for finding elements.

It is important that the script uses as few elements as possible, especially if using XPATH locators.

#2 - Use Only Explicit Waits


One of the best ways of making a script faster is by using explicit waits.
If your test scripts uses implicit waits (or delays)s,
WebDriver driver = new FirefoxDriver();
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.get(pageUrl);
WebElement element=driver.findElement(By.id(“myId"));

replace the implicit waits with explicit waits:

WebDriver driver = new FirefoxDriver();
WebDriverWait wait = new WebDriverWait(driver, 10);
driver.get(pageUrl);
WebElement element = wait.until(ExpectedConditions.
presenceOfElementLocated(By.id(“myId")));

The script performance is better with explicit waits.
Elements are accessed as soon as they are available.
No additional waiting times are needed.

#3 - Write Good Atomic Tests


ATOMIC TESTS

Each test should test a single tiny bit of functionality.
It is better to have more small scripts focused on one thing only than fewer big scripts that do too many things.
Each test has up to 20 steps.
Each test runs in under 10 seconds.
Having atomic tests is very useful in case of failures.
If any of the smaller tests fails, it is very clear where the problem is.

GOOD TESTS

Good tests are created by following a few simple rules:
1. Eliminate step duplication
2. Keep the scripts independent
3. Write just enough steps to go quickly from A to B
4. Remove steps that are not related to the final result

Good written tests are fast tests.

#4 - Use The Chrome Driver


If your test automation script needs a real browser but not a specific one,

Use the Chrome browser and the Chrome driver.

The Chrome browser is faster than IE, Firefox, Safari and Opera.
The Chrome browser driver is faster than the IE, Firefox, Safari browser drivers.


#5 - Use Headless Browser Drivers

If you don't need a real browser, headless browsers can make your script faster.
Headless browsers do not have a user interface.

The most popular headless browsers are:
1. HTML UNIT
- headless browser written in Java
- uses the RHINO engine (not used by any real browser)
- provides JS and ajax support, partial rendering capability

Example
driver = new HtmlUnitDriver();



2. PHANTOM JS
- headless browser that uses the WEBKIT layout engine (used in Chrome and Safari) for rendering web pages and Javascript Core for executing scripted tests
- uses Ghost Driver as an implementation of the WebDriver Wire Protocol


The following example shows how to create a Phantom JS Driver object.

Example:
DesiredCapabilities caps = DesiredCapabilities.phantomjs();
caps.setJavascriptEnabled(true);
caps.setCapability(“phantomjs.binary.path",
"c:\\selenium\\browserdrivers\\phantomjs.exe");
caps.setJavascriptEnabled(true);
driver = new PhantomJSDriver(caps);

#6 - Re-use The Browser Instance

A typical JUNIT class includes:
  1. setUp() method
  2. tearDown() method
  3. test scripts
The setUp() method uses the @Before annotation.
It runs before each script to create the driver object and open the browser.
The tearDown() method uses the @After annotation.
It runs after each script to destroy the driver object and close the browser.
Each test script uses its own browser instance:
setUp() –> Test Script 1 --> tearDown()
setUp() –> Test Script 2 --> tearDown()

The browser instance can be shared by all scripts when using different annotations:
  1. @BeforeClass for the setUp() method
  2. @AfterClass for the tearDown() method
In this case, the setUp() method runs before all test scripts.
The tearDown() method runs after all test scripts.
After each test script, the browser is not closed so the next script can re-use it:
setUp() --> Test Script 1 --> Test Script 2 --> tearDown()


#7 - Run Scripts In Parallel


By default, JUNIT test scripts run sequentially.
There are a few options for running them in parallel:
1. Run the scripts in parallel on the local computer
This is done by creating a Maven project in Eclipse and using the Maven Surefire plugin.
Maven Surefire allows methods or classes to be run in parallel.
It also allows the thread count to be set up.
Using Maven Surefire reduces the execution time with about 50%.

2. Use Selenium Grid
There's two reasons for using Selenium-Grid:
- to run your tests against multiple browsers, multiple versions of browser, on different operating systems.
- to reduce the time it takes for the test suite to complete
Selenium-Grid is used to speed up the execution of a test pass by using multiple machines to run tests in parallel.

3. Use Sauce Labs (selenium grid in the cloud)
It works similar with Selenium Grid,
But you don't need to set up the grid environment.
It has hundreds of combinations of browser/device/operating system available.

#8 - Use HTTP Parse Libraries


There are cases when Selenium WebDriver is not the best option for creating test scripts.
If the test script involves navigating through a lot of pages, using HTML parsing libraries like JSOUP is a better choice than Selenium WebDriver.



JSOUP is a Java library for working with real-world HTML.
It provides a simple API for extracting and manipulating data, using the DOM, CSS, and jquery-like methods.
JSOUP parses HTML to the same DOM as modern browsers do.
  • scrape and parse HTML from a URL, file, or string
  • find and extract data, using DOM traversal or CSS selectors
    0135b-cooking
  • manipulate the HTML elements, attributes, and text


How does a script using JSOUP look like?

@Test public void test1() {
Document resultsUrl = Jsoup.connect(basePageUrl).get();

Elements titles = resultsUrl.select(“span.title");


for (Element title : titles) {


Element link = title.child(0);


String detailsUrl = basePageUrl +link.attr(“href");


Document detailUrl = Jsoup.connect(detailsUrl).get();


Elements bookTitle = detailsUrl.getElementsByAttributeValue(“testid", “text_bibtitle");


if (bookTitle.size() > 0)

assertTrue(bookTitle.get(0).text().length() > 0);

Elements bookAuthor = detailUrl.getElementsByAttributeValue(“testid", “author_search");


if (bookAuthor.size() > 0)

assertTrue(bookAuthor.get(0).text().length() > 0);
}
}
}

#9 - Pre-Populate Cookies


Pre-populating site cookies can speed up scripts by avoiding additional site navigation.

Lets take the following test case:
  1. open the home page of a site
  2. execute a keyword search
  3. the results page is displayed with 10 results; language is english
  4. go to page 2 of results
  5. change the language to french; the page reloads in french
  6. change the number of results to 25; the page reloads with 25 results

For page 2, the script needs to
  • change the language through a listbox; the page reloads when a different language is selected.
  • change the number of results through another listbox; the page reloads with the new number of results


Since the page sets cookies when the results number and language change, it is easy to add cookies to the site before loading page 2.

This way, page 2 will load directly with 25 results, in french.

Code Sample:
public void addCookie(String name, String value) {

Cookie pageSize = new Cookie.Builder(name, value)

.domain(“vpl.bibliocommons.com")
.expiresOn(new Date(2016, 12, 31))
.isSecure(true)
.path(“/")
.build();

driver.manage().addCookie(pageSize);

}

@Test
public void testResult() throws InterruptedException {

//page opens in english with 10 results
driver.get(“https://vpl.bibliocommons.com/search?q=java&t=keyw...");

addCookie(“page_size", “25");
addCookie(“language", “fr-CA");

//page opens in french with 25 results
driver.get(“https://vpl.bibliocommons.com/search?page=2&q=java...");

}

#10 - Do Not Load Images


Many web pages are rich in images so they load slowly.
If the page loads slowly, the script is slow as well.
A page loads faster if no images are loaded.
Disabling images is done by setting up a new browser profile and disabling images for it in the Settings page.
In the test script, use the new browser profile when starting the browser driver:

1. In chrome type : chrome://version/
2. Using the console, navigate to the Chrome exe directory
3. type : chrome.exe –user-data-dir="your\custom\directory\path" to create your custom profile.
4. When chrome opens and asks for a new account to be created, decline
5. In Chrome, go to
Settings>
Advanced settings>
Privacy >
Content Settings >
Images >
Do Not Show Any Image
6. Close chrome. Reopen it again from the console with the same command sequence used in 3. Verify that it is not loading any images in a site
7. Now, in your code, create the capabilities for the driver using the new profile.
System.setProperty(“webdriver.chrome.driver", “C:\\Selenium\\BrowserDrivers\\chromedriver.exe");
ChromeOptions options = new ChromeOptions();
options.addArguments(“user-data-dir=C:\\Selenium\\ChromeProfile");
options.addArguments(“–start-maximized");

driver = new ChromeDriver(options);