BDDStack How to build Test Specs - bcgov/common-service-showcase GitHub Wiki

Specifications

In BDDStack we implement our user stories in specs or specifications. The following is a typical spec:

package specs

import pages.HomePage
import spock.lang.*

@Title("Viewer Access")

@Narrative("""
Example: As an viewer user
I want use the comfort admin application
So that I can see the submissions
""")

@Issue("<jira Ticket url>")

@Stepwise //Executes the tests sequentially

class ReviewUserSpec extends BaseSpec {

  def "As a viewer user, I want to log in into the Comfort admin application."() {
    when: "I login as Viewer"
    then: "I see the menu page."
  }

  def "As a viewer, I want review the submissions for Mines"() {
    when: "I am at the home page"
    then: "I click on Mines Admin"
  }

  def "As a viewer, I want to open a submission"() {
    when: "I am at the admin page"
    then: "I click on the first submission"
    where: 
    Var1 || Var2
    "ID-1" || "NAME1"
  }
}

As you can see the normal English user story and acceptance criteria have been 1 to 1 incorporated in the test script. Note the specific formatting of the statements.

The script will actually run. But no actual test activities will take place yet.

Specs elements

package specs Refers to the location we are keeping our specs: mandatory

import pages.HomePage You need to import any page that you require to touch

import spock.lang.* Mandatory import for you Spock directives (@)

@Title("Viewer Access") Short Title for you test, this will show up in your test report

@Narrative("""
Example: As an viewer user
I want use the comfort admin application
So that I can see the submissions
""")

Longer description will also show in your report.

@Issue("<jira Ticket url>") The Ticket url will show as a link in your report. Can be place in front of any def as well, for more granular reference.

@Stepwise Executes the tests (def) sequentially as defined, the framework needs to be told explicitly

class ReviewUserSpec extends BaseSpec { } The definition for your test class, the filename needs to be ReviewUserSpec.groovy

  def "As a viewer user, I want to log in into the Comfort admin application."() {
    when: "I login as Viewer"
    then: "I see the menu page."
  }

Definition of your test, the above will be reported as an individual test result.

  def "As a viewer, I want to open a submission"() {
    when: "I am at the admin page"
    then: "I click on the first submission"
    where: 
    Var1 || Var2
    "ID-1" || "NAME1"
  }

The where: clause allows for the definition for data driven testing. The same test will iterate through the rows and execute with the contents of each row.

Adding the test code

Once you have created the template for your user story and its tests (acceptance criteria), you can bring the page content and definition together with the activities, resulting in a fully operation test script.

package specs

import specs.traits.Login
import pages.LoginPage
import pages.HomePage
import pages.MinesAdminPage
import pages.SubmissionPage
import geb.module.FormElement

import spock.lang.*
//import org.openqa.selenium.Cookie

@Title("No admin Access")
@Narrative("""
As an viewer user
I want use the comfort admin application
So that I can see the submissions
""")
@Issue("")
@Stepwise
class ReviewUserSpec extends BaseSpec implements Login {

  def "As a viewer user, I want to to log in into the Comfort admin application."() {
    when: "I login as Viewer"
      logInAsViewerUser()
    then: 'I see the menu page."'
      at HomePage
  }
  def "As a viewer, I want review the submissions for Mines"() {
    when: "I am at the home page"
      to HomePage
    then: "I click on Mines Admin"
      waitFor { minesAdmin.click() }
      at MinesAdminPage
      sleep(3000) // Have to slightly delay the script as it otherwise will not pick up the pageTitle
      assert pageTitle.text() == "Submissions"
  }
    def "As a viewer, I to open a submission"() {
    when: "I am at the admin page"
      to MinesAdminPage
    then: "I click on the first submmision"
      waitFor { $("button",2).click() }
      at SubmissionPage
      sleep(3000) // Have to slightly delay the script as it otherwise will not pick up the pageTitle

  }
}