4 minute read

Background

Recently I started a contract where I was asked to build a maintainable automation framework using Sbt, Scala, cucumber and webDriver for a web application based on the Play framework. Although I have lots of experience of web based projects using Ruby, Cucumber and webDriver, I’ve never used (or even thought of using) Scala.

After a few days of pain I got there in the end and I have now fully integrated cucumber into my project. I found it very difficult to find any recent online resources, blogs etc that would help with this set up. If your looking to set this up yourself, then hopefully you will find this example useful, and read on…

Prerequisite

IntelliJ IDEA Comminuity Edition is great as a tool to support automated test development. It supports Scala and offers a scala-cucumber plugin, enabling us to write our cucumber feature files using the Gerkin syntax (Given, When, Then, And, But), as well as providing syntax and error highlighting for feature files and step definitions.

IntelliJ Setup

  • Open InteliJ:

  • Select Configure:

  • Select Plugins:

  • Select Browse Repositories…, enter “cucumber into the search field:

Install the Cucumber for Scala plugin and restart InteliJ.

Creating your first sclala project

Once you have installed the required plugins, open InteliJ.

  • Select “Create New Project”
  • Select “Scala, and SBT”
  • Click next

If you do not have these options you may need to install the sbt plugin.

  • Name your project, for example my_first_cucumber_test
  • Select “Finish”

InteliJ will open and create all of the required files and folders for us, including the build.sbt:

Now we have the project set up, we can go ahead and delete anything that we don’t need, Go to the src/test directory and delete any java directories, keeping the scala directories.

Project set up

Open the build.sbt folder. When prompted with the following message, select “Enable auto- import”.

Next, add dependencies for scalatest, cucumber, junit, and selenium-webdriver to your build.sbt file.

name := "my_first_cucumber_test"
 
version := "1.0"
 
libraryDependencies ++= Seq(
  "org.scalatest" % "scalatest_2.11" % "2.2.0" % "test",
  "org.scala-lang" % "scala-library" % "2.11.1",
  "info.cukes" % "cucumber-scala_2.11" % "1.1.8",
  "info.cukes" % "cucumber-junit" % "1.1.8",
  "info.cukes" % "cucumber-picocontainer" % "1.1.8",
  "junit" % "junit" % "4.11" % "test",
  "com.novocode" % "junit-interface" % "0.10" % "test",
  "org.seleniumhq.selenium" % "selenium-java" % "2.42.2")

Once dependencies are installed we’re ready to create our first feature file.

Writing Features

Features are written in a plain text format named Gerkin. Feature files live in the src/test/resources directory. Navigate to resources directory, right click and select “new directory” and create a features folder.

Now we have our features folder we can go ahead and create our first feature file. Right click, select “new file” and give it a name ending in .feature, like the following:

  Feature: My First cucumber feature
 
  As a tester,
  I would like to utilize cucumber,
  So that I can create BDD style selenium-webdriver tests.
 
  Scenario: Google search, using selenium
    Given I have navigated to google
    When I search for "selenium"
    Then the page title should be selenium - Google Search

Now you have created your first Feature, well done! Now lets write some code…

Step Definitions

Navigate to the test/scala directory, right click and create a new package called stepdefs.

Now we must create a cucumber runner class in order to execute our tests and generate our step definitions. Right click on the step definition package and select new “Scala class” and add the following:

package stepdefs
 
import cucumber.api.junit.Cucumber
import cucumber.api.junit.Cucumber.Options
import org.junit.runner.RunWith
 
@RunWith(classOf[Cucumber])
@Options(
  features = Array("src/test/resources/features"),
  glue = Array("stepdefs"),
  format = Array("pretty", "html:target/cucumber-report"),
  tags = Array("@wip")
)
class RunCucumber {
}

As the first scenario is “work in progress”, go ahead and tag your first scenario as @wip so it can be picked up when executing the cucumber runner that we just created.

Execute the tests

Go to the cucumber runner file that we created, right click and select “Run Cucumber”

The scenario will now be executed, however as there are no step definitions the scenario cannot be ran, it will execute and spit out the empty step definitions:

For some reason I get java and scala step definitions. Ignore them, we only need the scala ones (obviously):

Now create new scala class within the stepdefs package:

Now we can simply copy/paste our new step definitions, and add required plugins. Step definitions must extend Scala DSL with EN. Like the following:

package stepdefs
 
import cucumber.api.PendingException
import cucumber.api.scala.{ScalaDsl, EN}
import org.scalatest.Matchers
 
class MyFirstCucumberTest extends ScalaDsl with EN with Matchers {
 
  Given("""^I have navigated to google$"""){ () =>
    //// Write code here that turns the phrase above into concrete actions
    throw new PendingException()
  }
 
  When("""^I search for "(.*?)"$"""){ (arg0:String) =>
    //// Write code here that turns the phrase above into concrete actions
    throw new PendingException()
  }
 
  Then("""^the page title should be selenium - Google Search$"""){ () =>
    //// Write code here that turns the phrase above into concrete actions
    throw new PendingException()
  }
 
}

Simply fill in the in the pending step definitions with selenium commands, something the following:

package stepdefs
 
import java.util.concurrent.TimeUnit
 
import cucumber.api.scala.{ScalaDsl, EN}
import org.openqa.selenium.By
import org.openqa.selenium.firefox.FirefoxDriver
import org.scalatest.Matchers
 
class MyFirstCucumberTest extends ScalaDsl with EN with Matchers{
 
  val driver = new FirefoxDriver()
  driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS)
 
  Given("""^I have navigated to google$"""){ () =>
    driver.navigate().to("http://www.google.com")
  }
 
  When("""^I search for "(.*?)"$"""){ (searchTerm:String) =>
    driver.findElement(By.id("gbqfq")).sendKeys(searchTerm)
    driver.findElement(By.id("gbqfb")).click();
  }
 
  Then("""^the page title should be "(.*?)"$"""){ (title:String) =>
    driver.getTitle.shouldEqual(title)
  }
 
}

It is also possible to execute our tests via command line: sbt ‘test-only stepdefs.RunCucumber’

Summary

What I’ve covered here is a very basic guide to getting started, however hopefully it is enough to get you started. If not, ask, I’m happy to help where possible.

Now we’re up and running the next step is to increase maintainability by abstracting the selenium driver, and build our page objects.

As usual, all example code can be found at my GitHub, here.