• Background Image

    News & Updates

December 31, 2017

The First Things You Need To Know

Selenium is really good at a specific set of things. If you know what those are and stick to them then you will be able to easily write reliable, scalable, and maintainable tests that you and your team can trust.

But before we dig in, there are a few things you’ll want to know before you write your first test.

Define a Test Strategy

A great way to increase your chances of automated web testing success is to focus your efforts by mapping out a testing strategy. The best way to do that is to answer four questions:

  1. How does your business make money (or generate value for the end-user)?
  2. How do your users use your application?
  3. What browsers are your users using?
  4. What things have broken in the application before?

After answering these, you will have a good understanding of the functionality and browsers that matter most for the application you’re testing. This will help you narrow down your initial efforts to the most important things.

From the answers you should be able to build a prioritized list (or backlog) of critical business functionality, a short list of the browsers to focus on, and include the risky parts of your application to watch out for. This prioritized list will help you make sure you’re on the right track (e.g., focusing on things that matter for the business and its users).

Pick a Programming Language

In order to work well with Selenium, you need to choose a programming language to write your acceptance tests in.

Conventional wisdom will tell you to choose the same language as what the application is written in. That way if you get stuck you can ask the developers on your team for help. But if you’re not proficient in this language (or new to development) then your progress will be slow and you’ll likely end up asking for more developer help than they have time for — hindering your automation efforts and setting you up for failure.

A great way to determine which language to go with is to answer one simple question: Who will own the automated tests?

Also, as you are considering which language to go with, consider what open source frameworks already exist for the languages you’re eyeing. Going with one can save you a lot of time and give you a host of functionality out of the box that you would otherwise have to build and maintain yourself — and it’s FREE.

You can see a list of available open source Selenium frameworks here.

Choosing a programming language for automated testing is not a decision that should be taken lightly. If you’re just starting out (or looking to port your tests) then considering and discussing these things will help position you for long term success.

Installation

  • Here are some installation instructions to help you get started quickly.

  • Here are some installation instructions to help you get started quickly.

  • There’s a great guide on “Properly Installing Python” which you can find here. It covers Mac OSX, Windows, and Ubuntu.

    NOTE: For doing proper software development in Python you’d want to consider something like Virtual Environments to effectively manage third-party dependencies. But for the needs of the examples in this book, it’s not necessary.

    Installing Third-Party Libraries

    There are over 84,000 third-party libraries (a.k.a. “packages”) available for Python through PyPI (the Python Package Index). To install packages from it you use a program called pip.

    To install them you use pip install package-name from the command-line.

    Here is a list of the packages that will be used throughout the bootcamp.

  • Here are some installation instructions to help you get started quickly.

December 30, 2017

How To Take a Screenshot on Failure with Selenium

The Problem

With browser tests it can often be challenging to track down the issue that caused a failure. By itself a failure message along with a stack trace is hardly enough to go on. Especially when you run the test again and it passes.

A Solution

A simple way to gain insight into your test failures is to capture screenshots at the moment of a failure. And it’s a quick and easy thing to add to your tests.

Let’s dig in with an example.

An Example


  • Let’s start by importing our requisite classes (for annotations (e.g., org.junit.After, etc.), driving the browser with Selenium (e.g., org.openqa.selenium.WebDriver, etc.), and matchers for our assertions (e.g., org.hamcrest.CoreMatchers, etc.)) and start our class with a setup method.

    // filename: Screenshot.java
    import org.junit.Before;
    import org.junit.Rule;
    import org.junit.Test;
    import org.junit.rules.TestRule;
    import org.junit.rules.TestWatcher;
    import org.junit.runner.Description;
    import org.openqa.selenium.OutputType;
    import org.openqa.selenium.TakesScreenshot;
    import org.openqa.selenium.WebDriver;
    import org.openqa.selenium.firefox.FirefoxDriver;
    import java.io.File;
    import java.io.IOException;
    import org.apache.commons.io.FileUtils;
    import static org.hamcrest.CoreMatchers.*;
    import static org.hamcrest.MatcherAssert.assertThat;
    
    public class Screenshot {
    WebDriver driver;
    
    @Before
    public void setUp() throws Exception {
    driver = new FirefoxDriver();
    }
    // ...
    

    We still need to handle our teardown. But in order to get the timing right withscreenshots on failure we’ll need to break from the norm of a simple @After annotation. For this we’ll look to a JUnit Rule, specifically the TestWatcher.

    // filename: Screenshot.java
    // ...
        @Rule
        public TestRule watcher = new TestWatcher() {
            @Override
            protected void failed(Throwable throwable, Description description) {
                File scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
                try {
                    FileUtils.copyFile(scrFile,
                            new File("failshot_"
                                    + description.getClassName()
                                    + "_" + description.getMethodName()
                                    + ".png"));
                } catch (IOException exception) {
                    exception.printStackTrace();
                }
            }
    
            @Override
            protected void finished(Description description) {
                driver.quit();
            }
        };
    

    With a TestWatcher we easily gain access to a test after it’s failed (e.g., in the failed method) and when the test completes regardless of it’s outcome (e.g., the finished method). So for our teardown we issue driver.quit(); in finished. And when there’s a failure we capture ascreenshot and write it to disk (in the current working directory) in failed.

    There are numerous ways to make the filename unique (e.g., unique ID, timestamp, etc.). The simplest way to get started is with the test class name and the test method name, which we’ve done.

    Now let’s wire up our test with a forced failure.

    // filename: Screenshot.java
    // ...
        @Test
        public void OnError() {
            driver.get("http://the-internet.herokuapp.com");
            assertThat(false, is(true));
        }
    
    }
    

    Expected Behavior

    When you save this file and run it (mvn clean test from the command-line) here is what will happen:

    • Open the browser
    • Visit the page
    • Fail
    • Capture a screenshot in the current working directory with the name failshot_Screenshot_OnError.png
    • Close the browser

  • Let’s start by including our requisite classes for our test framework (e.g., NUnit.Framework), driving the browser with Selenium (e.g., OpenQA.Selenium, etc.), accessing C#’s image functionality (e.g., System.Drawing.Imaging), and start our class off with some setup and teardown methods.

    // filename: Screenshot.cs
    using NUnit.Framework;
    using NUnit.Framework.Interfaces;
    using OpenQA.Selenium;
    using OpenQA.Selenium.Firefox;
    using System.Drawing.Imaging;
    
    public class Screenshot
    {
        IWebDriver Driver;
    
        [SetUp]
        public void SetUp()
        {
            Driver = new FirefoxDriver();
        }
    
        [TearDown]
        public void TearDown()
        {
            if (TestContext.CurrentContext.Result.Outcome.Status.Equals(TestStatus.Failed))
                TakeScreenshot();
    
            Driver.Quit();
        }
    // ...
    

    Notice in the teardown we have a conditional statement before we call Driver.Quit();. It’s checking to see if the test failed, if it has then it will take a screenshot. Right now the method we’re referencing isn’t declared. Let’s add it now.

    There are numerous ways to make the filename unique for the screenshot(e.g., unique ID, timestamp, etc.). The simplest way to get started is with the full test name (e.g., test class name and test method name), which we’ve done. We also specified the save location on disk using a string literal (e.g., @"C:\Temp"), feel free to change it to suit your needs.

    The rest is a simple matter of casting the Driver as an ITakeScreenshot object and calling GetScreenshot().SaveAsFile(specifying the save location and image format — which is PNG in this case).

    Now let’s wire up our test with a forced failure.

    // filename: Screenshot.cs
    // ...
        private void TakeScreenshot()
        {
            string SaveLocation = @"C:\Temp\" +
                                   "failshot_" +
                                   TestContext.CurrentContext.Test.FullName +
                                   ".png";
            ITakesScreenshot ScreenshotDriver = (ITakesScreenshot) Driver;
            ScreenshotDriver.GetScreenshot().SaveAsFile(SaveLocation, ImageFormat.Png);
        }
    // ...
    

    There are numerous ways to make the filename unique for the screenshot(e.g., unique ID, timestamp, etc.). The simplest way to get started is with the full test name (e.g., test class name and test method name), which we’ve done. We also specified the save location on disk using a string literal (e.g., @"C:\Temp"), feel free to change it to suit your needs.

    The rest is a simple matter of casting the Driver as an ITakeScreenshot object and calling GetScreenshot().SaveAsFile(specifying the save location and image format — which is PNG in this case).

    Now let’s wire up our test with a forced failure.

    
    // filename: Screenshot.cs
    // ...
    [Test]
    public void ScreenShotOnFailure()
    {
    Driver.Navigate().GoToUrl("http://the-internet.herokuapp.com");
    Assert.That(false.Equals(true));
    }
    }
    

    Expected Behavior

    When you save this file and run it (nunit3-console.exe .\Screenshot.sln from the command-line) here is what will happen:

    • Open the browser
    • Visit the page
    • Test Fails
    • Selenium Captures a screenshot in C:\Temp with the name failshot_Screenshot.ScreenShotOnFailure.png
    • Close the browser

  • Let’s start by importing our requisite libraries (import unittest for our test framework, from selenium import webdriver to drive the browser, and import sys to determine when there’s a test failure), declare our test class, and wire up some test setUp and tearDown methods.

    # filename: screenshot.py
    import sys
    import unittest
    from selenium import webdriver
    
    
    class ScreenShotOnFailure(unittest.TestCase):
    
        def setUp(self):
            self.driver = webdriver.Firefox()
    
        def tearDown(self):
            if sys.exc_info()[0]:
                self.driver.save_screenshot("failshot_%s.png" % self._testMethodName)
            self.driver.quit()
    # ...
    

    In tearDown we check to see if sys.exc_info()[0] exists. If it does, then there’s been a test failure and we capture a screenshot through the help of Selenium‘s .save_screenshot method. .save_screenshot accepts a filename as a string (e.g., 'failshot.png'). To make the filename unique we use the test method name (e.g., self._testMethodName). When this command executes it will save an image file to the local system in the current working directory.

    Now to wire up a test which will fail.

    # filename: screenshot.py
    # ...
        def test_example_1(self):
            driver = self.driver
            driver.get('http://the-internet.herokuapp.com')
            assert driver.title == 'blah blah blah'
    
    if __name__ == "__main__":
        unittest.main()
    

    Expected Behavior

    When we save this file and run it (python screenshot.py from the command-line) here is what will happen:

    • Open the browser
    • Load the homepage of the-internet
    • Check the text of the page header and fail
    • Output a failure message in the terminal
    • Capture a screenshot in the current working directory
    • Close the browser

 

December 28, 2017

Hello world!

Welcome to WordPress. This is your first post. Edit or delete it, then start writing!