How to reuse code in Spock tests

1.9k views Asked by At

I'm writing Spock + Geb based tests for web site testing. Web site is used to create offers and later various actions can be performed on them (confirm, reject, withdraw). I already created working scenario for creating an offer. But now when I came to the point that I need to implement scenarios for various combinations of actions I would like to be able to reuse "create offer" in these other scenarios. Unfortunately I'm not able to find any example or to think good way how to do it. Could someone give me any ideas about that?

By the way I need to perform actions in predefined sequence so I'm using Stepwise annotation on my specifications.

1

There are 1 answers

6
jk47 On

Single Page Actions:

It's hard to say without seeing examples of your code, but one way of doing this is to define the methods for your actions (confirm, reject, withdraw) as simple methods in your Page class:

class ActionsPage extends Page {

  static content = { 
    //Page content here
  }

  def confirm (){
    //Code to perform confirm action on the page
  }

  def reject (){
    //Code to perform reject action on the page
  }

Then in your Specification class you can do

def "Test confirm action"(){
  when: "we go to the actions pages"
  to ActionsPage

  and: "we perform a confirm action"
  confirm()

 then: "something happens"
 //Code which checks the confirmation worked 
} 

This works because Geb uses Groovy's method missing stuff to find the name of the method on the current page called "confirm ()", and will execute that code.

Multiple Page Actions:

If the actions are complicated and involve navigating to several pages, it is best to create an abstract base class for your tests which need to perform the actions:

//Not @Stepwise
abstract class BaseActionsSpec extends Specification {

  //Note: don't use Spock when/then blocks in these methods as they are not feature methods
  protected void confirm(){
    //Code to perform multi-page action
  }

  protected void reject(){
    //Code to perform multi-page action 
  }
}

Then the extending classes:

@Stepwise
class ConfirmActionSpec extends BaseActionsSpec{

      def "Test confirm action"(){
        when: "we go to the actions pages"
        to ActionsPage

        and: "we perform a confirm action"
        confirm() //calls method in super class

        then: "something happens"
       //Code which checks the confirmation worked 
    }
}