Alexander Kuzmenya is a Frontend Engineer at BlazeMeter. He has 3 years of experience in web development focusing on modern SPA solutions, with React being the favourite one. 

Learn JMeter in 5 Hours

Start Learning
Slack

Test Your Website Performance NOW!

arrow Please enter a URL with http(s)
Nov 04 2019

Getting started with JUnit and Blazemeter GUI functional testing

This blogpost will take you through a step-by-step guide to running a JUnit Selenium test in the BlazeMeter environment.

 

In our test we will be working with JUnit, as a tool of choice. If you feel comfortable with TestNG or other frameworks, it should be easy to rewrite your test to do that.

 

JUnit is an open source unit testing framework designed for the purpose of writing and running tests in JAVA. An important part of test-driven development, JUnit lets developers easily and automatically run and verity repeatable tests, aiding your Continuous Testing process.

 

To run a Selenium Test with JUnit you need to make sure you install:

  • JDK (Java Developer Kit. Essential tool for developing in Java)
  • Maven (Tool we need to compile and build our project)
  • JUnit (Testing framework)
  • and import openQA packages (Selenium)

 

Let’s get started.

 

The easiest way to set up a Selenium Java project is to use Maven. Maven will download the java bindings and all its dependencies, and will create the project for you, using a maven pom.xml (project configuration) file. Once you’ve done this, you can import the maven project into your preferred IDE, IntelliJ IDEA or Eclipse.

 

To use Maven, you need a pom.xml file. This can be created with a text editor. Your pom.xml file will look something like this.

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
                 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0    http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <groupId>BlazemeterSandbox</groupId>
        <artifactId>BlazemeterSandbox</artifactId>
        <version>1.0</version>
        <dependencies>
            <dependency>
                <groupId>org.seleniumhq.selenium</groupId>
                <artifactId>selenium-remote-driver</artifactId>
                <version>3.141.59</version>
            </dependency>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.12</version>
            </dependency>
        </dependencies>
</project>

 

 

In our pom.xml we specify dependencies of our Selenium remote driver and JUnit. Create this file in the folder you created for your project.

 

Here I’ve got a sample of a working Selenium test. We create an instance of WebDriver, and tell it to go on our blazedemo.com page.

 

@Before
public void setUp() throws MalformedURLException {
   driver = new WebDriver();
}

@Test
public void testBlazeDemo() {
   driver.get("http://blazedemo.com/purchase.php");
}

 

 

First of all i have to specify my API_KEY and API_SECRET credentials to have access on BlazeMeter:

 

private static final Logger LOGGER = LoggerFactory.getLogger(DemoGridTest.class);
private final static String API_KEY = "your_api_key";
private final static String API_SECRET = "your_api_secret";

 

And then specify “a.blazemeter.com” as the primary link for our WebDriver;

 

private final static String BASE = "a.blazemeter.com";
private final static String curl = String.format("https://%s/api/v4/grid/wd/hub", BASE);
private static RemoteWebDriver driver;

 

After that we write a setUp method, where later we will initialize test configuration via Desired Capabilities (such as browser name, version, test id etc.) to run it in the BlazeMeter app.

 

@BeforeClass
   public static void setUp() throws MalformedURLException {
       URL url = new URL(curl);
       DesiredCapabilities capabilities = new DesiredCapabilities();
       String reportURL = String.format("https://%s/api/v4/grid/sessions/%s/redirect/to/report", BASE, driver.getSessionId());
       openInBrowser(reportURL);
       driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
   }

 

 

Now set your desired capabilities, such as browser name, report name, session name.

 

Full list includes the following:

  • browserName - which browser the test will run on, such as Chrome or Firefox. Note: Remember to always reference the browser name in lowercase within the code.
  • browserVersion - what specific version of the browser to use, for example it can be chrome with version “69”. setCapability("browserVersion", "69");
  • blazemeter.projectId - You can define this if you want to add your test to an existing BlazeMeter project. Please not, if the ID is wrong, the test will not launch, and you'll get an error.
  • blazemeter.buildId - can be used if you want to add several sessions to a single report, for which you must create a custom buildId (random string). This ID must then be included in the following line, which must be added to each of the scripts to be executed as follows: buildId+testId/testName
  • blazemeter.testId - if you want to attach your report to an existing test, add its Test ID. If the ID is wrong, the test will not launch, and you'll get an error. (Remember: the chosen test must be a Functional GUI Test.)
  • blazemeter.testName - if you want to attach your report to an existing test, add its testName. If the name does not exist, a new test is created. If the test name exists, but it's not a Functional GUI Test, the test will not launch, and you'll get an error.
  • blazemeter.reportName - You can choose to name your report, which you’ll then be able to view in the Reports drop-down menu and on the dashboard.
  • blazemeter.sessionName - you may name the session, which will then appear in the drop-down menu in the upper-right corner of the test report.
  • blazemeter.sessionTimeout - The default value is 300 seconds. If you expect a gap between commands in your test will be more than 300 seconds, you may need to increase this value (to a maximum 1200 seconds).
  • blazemeter.locationId - you may use the Location ID (aka Location Name) of one of the available BlazeMeter locations or your own private location. Note: To see the list of available locations, create a new GUI Functional Test in the UI, upload a YAML, and review the options available that appear when you click the "Select test location" drop-down menu. Or alternatively you can check it via API https://a.blazemeter.com/api/v4/grid/locations

 

JUnit with Selenium

 

  • blazemeter.videoEnabled - You can specify whether you want video enabled on your test report (true or false).
  • openInBrowser(reportURL) - add this line and the method as it appears in the above example if you want the script to automatically open your test report in your web browser when it runs.

 

@BeforeClass
public static void setUp() throws MalformedURLException {
   URL url = new URL(curl);
   DesiredCapabilities capabilities = new DesiredCapabilities();
   capabilities.setCapability("blazemeter.apiKey", API_KEY);
   capabilities.setCapability("blazemeter.apiSecret", API_SECRET);
   capabilities.setCapability("blazemeter.reportName", "Demo Grid test");
   capabilities.setCapability("blazemeter.sessionName", "Chrome browser test");
   capabilities.setCapability("blazemeter.projectId", "");
   capabilities.setCapability("blazemeter.testId", "");
   capabilities.setCapability("blazemeter.buildId", "randomString");
   capabilities.setCapability("blazemeter.locationId", "harbor-your_harbor_id");
   capabilities.setCapability("browserName", "chrome");
   capabilities.setCapability("browserVersion", "69");
   driver = new RemoteWebDriver(url, capabilities);
   String reportURL = String.format("https://%s/api/v4/grid/sessions/%s/redirect/to/report", BASE, driver.getSessionId());
   System.out.println("Report url: " + reportURL);
   openInBrowser(reportURL);
   driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
}

 

Now our test is ready to run. After the test has ended, you can open the report in your BlazeMeter account under the GUI Functional Test tab. As you can see in the screenshot below, you can view the commands and video of the test scenario. These are not arranged in a specific order, but rather shown as simple commands running one after another.

 

Junit with Selenium

 

Now that you’ve run the test, the next step is to add flow markers, test statuses, and test case names to the test.

 

When coding a Selenium test in Java, each class will serve as a test suite and each function within a class will serve as a test case. That means once the report is generated in BlazeMeter, a class’s name in the code will appear as a test suite name in the report. Similarly, a function’s name in the code will appear as a test case name in the report.

 

Lets separate our test in 3 parts, which later have different test cases statuses:

1)

@Test
public void testCasePassed() {
   driver.get("http://blazedemo.com");
   driver.findElementByName("toPort").click();
   Select toPort = new Select(driver.findElementByName("toPort"));
   toPort.selectByVisibleText("Berlin");
   driver.findElementByCssSelector("input.btn.btn-primary").click();
}

 

2)

 

@Test
public void testCasesFailed() {
   driver.get("http://blazedemo.com/purchase.php");
   driver.findElementById("inputName").clear();
   driver.findElementById("inputName").sendKeys("TestName");
   String text = driver.findElementById("inputName").getAttribute("value");
   // failed assertion
   assertEquals("testName", text);
}

 

3)

 

@Test
public void testCaseBroken() {
   driver.get("http://blazedemo.com/purchase.php");
   WebElement city = driver.findElement(By.id("city"));
   city.click();
   city.sendKeys("NY");
   String text = driver.findElement(By.id("city")).getAttribute("value");
   if ("NY".equals(text)) {
       throw new RuntimeException("Demo script thrown an exception.");
   }
}

 

In the following example, we will use the TestRule class (TestName, specifically) to intercept test method calls and make our TestName methods available inside each test method. Our first TestName method sets up a hash map to manage assigning our test suite and test case names, and the latter two methods set up our success, failed, and broken statuses:

 

@Rule
public final TestName bzmTestCaseReporter = new TestName() {
   @Override
   protected void starting(Description description) {
       Map<String, String> map = new HashMap<>();
       map.put("testCaseName", description.getMethodName());
       map.put("testSuiteName", description.getClassName());
       driver.executeAsyncScript("/* FLOW_MARKER test-case-start */", map);
   }
   @Override
   protected void succeeded(Description description) {
       if (driver != null) {
           Map<String, String> map = new HashMap<>();
           map.put("status", "success");
           map.put("message", "");
           driver.executeAsyncScript("/* FLOW_MARKER test-case-stop */", map);
       }
   }
   @Override
   protected void failed(Throwable e, Description description) {
       Map<String, String> map = new HashMap<>();
       if (e instanceof AssertionError) {
           map.put("status", "failed");
       } else {
           map.put("status", "broken");
       }
       map.put("message", e.getMessage());
       driver.executeAsyncScript("/* FLOW_MARKER test-case-stop */", map);
   }
};

 

That way, we would be able to see if test cases is broken or failed accordingly in our test report. Statuses will be changed if we have the following exception:

 

Junit test with Selenium in BlazeMeter

 

In the resulting report, a "Pass" status will appear in green in the report, a "Fail” status will appear in red, and a “Broken” status will appear in orange.

 

Having a report with flow markers is more informative and later can be represented in stats overall with other reports information.

 

The full code of class can be found below:

 

Full code of class can be found below:
import org.junit.*;
import org.junit.rules.TestName;
import org.junit.runner.Description;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.ui.Select;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import static org.junit.Assert.*;

public class DemoGridTest {
   private static final Logger LOGGER = LoggerFactory.getLogger(DemoGridTest.class);
   private final static String API_KEY = "";
   private final static String API_SECRET = "";
   private final static String BASE = "a.blazemeter.com";
   private final static String curl = String.format("https://%s/api/v4/grid/wd/hub", BASE);
   private static RemoteWebDriver driver;

   @Rule
   public final TestName bzmTestCaseReporter = new TestName() {
       @Override
       protected void starting(Description description) {
           Map<String, String> map = new HashMap<>();
           map.put("testCaseName", description.getMethodName());
           map.put("testSuiteName", description.getClassName());
           driver.executeAsyncScript("/* FLOW_MARKER test-case-start */", map);
       }
       @Override
       protected void succeeded(Description description) {
           if (driver != null) {
               Map<String, String> map = new HashMap<>();
               map.put("status", "success");
               map.put("message", "");
               driver.executeAsyncScript("/* FLOW_MARKER test-case-stop */", map);
           }
       }
       @Override
       protected void failed(Throwable e, Description description) {
           Map<String, String> map = new HashMap<>();
           if (e instanceof AssertionError) {
               map.put("status", "failed");
           } else {
               map.put("status", "broken");
           }
           map.put("message", e.getMessage());
           driver.executeAsyncScript("/* FLOW_MARKER test-case-stop */", map);
       }
   };
   @BeforeClass
   public static void setUp() throws MalformedURLException {
       URL url = new URL(curl);
       DesiredCapabilities capabilities = new DesiredCapabilities();
       capabilities.setCapability("blazemeter.apiKey", API_KEY);
       capabilities.setCapability("blazemeter.apiSecret", API_SECRET);
       capabilities.setCapability("blazemeter.reportName", "Demo Grid test");
       capabilities.setCapability("blazemeter.sessionName", "Chrome browser test");
       capabilities.setCapability("browserName", "chrome");
       capabilities.setCapability("browserVersion", "69");
       driver = new RemoteWebDriver(url, capabilities);
       String reportURL = String.format("https://%s/api/v4/grid/sessions/%s/redirect/to/report", BASE, driver.getSessionId());
       System.out.println("Report url: " + reportURL);
       openInBrowser(reportURL);
       driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
   }
   public static void openInBrowser(String string) {
       if (java.awt.Desktop.isDesktopSupported()) {
           try {
               java.awt.Desktop.getDesktop().browse(new URI(string));
           } catch (Exception ex) {
               LOGGER.warn("Failed to open in browser", ex);
           }
       }
   }
   @AfterClass
   public static void tearDown() {
       if (driver != null) {
           driver.quit();
       }
   }
   @Test
   public void testCasePassed() {
       driver.get("http://blazedemo.com");
       driver.findElementByName("toPort").click();
       Select toPort = new Select(driver.findElementByName("toPort"));
       toPort.selectByVisibleText("Berlin");
       driver.findElementByCssSelector("input.btn.btn-primary").click();
   }
  

 @Test
   public void testCasesFailed() {
       driver.get("http://blazedemo.com/purchase.php");
       driver.findElementById("inputName").clear();
       driver.findElementById("inputName").sendKeys("TestName");
       String text = driver.findElementById("inputName").getAttribute("value");
       // failed assertion
       assertEquals("testName", text);
   }
   @Test
   public void testCaseBroken() {
       driver.get("http://blazedemo.com/purchase.php");
       WebElement city = driver.findElement(By.id("city"));
       city.click();
       city.sendKeys("NY");
       String text = driver.findElement(By.id("city")).getAttribute("value");
       if ("NY".equals(text)) {
           throw new RuntimeException("Demo script thrown an exception.");
       }
   }
}

 

To get started with running your GUI Functional Testing in BlazeMeter, set up your account here, or request a demo for you and your team.

 

 

     
arrow Please enter a URL with http(s)

Interested in writing for our Blog?Send us a pitch!