1

Is there a easy way in Geb/Spock to ensure a login happens before all functional tests?

For instance my login test looks like

def "login"() {
        when:
            to Login
        and:
            login(username,password)
        then:
            at Dashboard
        where:
            username   | password
            "X"        | "X"
    }

This is quite alot of code to put into each other test.

IanWatson
  • 1,649
  • 2
  • 27
  • 49
  • Perhaps http://stackoverflow.com/questions/13575972/determine-order-of-execution-of-spock-tests is the answer. Basically runs tests in order... but still doesn't seem the ideal solution. – IanWatson Feb 20 '15 at 22:39
  • Depending on test order is often not a good idea. It may lead to test bleed and strange interdependencies where failure in one test may cause failure in another seemingly independent test. Suites that dependent on implicit state setup by tests are brittle and hard to reason about and maintain. – erdi Feb 22 '15 at 15:03

2 Answers2

2

Create an abstract base spec which all of your specs that require logging in can extend:

abstract class LoginBaseSpec extends GebReportingSpec{

  def setupSpec(){
    when:
      to Login

    and:
      login(username, password)

    then:
      at Dashboard  
  }

This setupSpec() method in the super spec will be executed before anything in the extending specs.

jk47
  • 755
  • 4
  • 10
  • Please note that labels are only treated in a special way by Spock if they are used in feature (test) methods and are ignored when used in fixture (setup, cleanup) methods. – erdi Feb 22 '15 at 15:06
1

Putting the common login code in a setup() method of a base spec class as proposed by jk47 is one way to go about it.

Another one, which doesn't tie you to a specific inheritance structure, is to use a JUnit rule which are supported by Spock out of the box.

Community
  • 1
  • 1
erdi
  • 6,944
  • 18
  • 28
  • Hi @erdi, is there any way to keep the driver state in the JUnit rule? For example, suppose I have 3 specs for page A, B, and C. If I put a JUnit rule which does the login on each spec, I will have to login three times. Is it possible to avoid this and login just once? It'd be possible through the use of a boolean static variable which would indicate if you have already logged in before or not, but is there any other more "Gebish" way of doing this? – João Silva Mar 18 '15 at 15:12
  • 1
    Keeping some state is always a bad idea - it will lead to interdependencies between your tests and you don't want to do that. You could in theory configure Geb not clear cookies between tests but that's asking for trouble in my view. What I tend to do is to have a separate spec for testing logging journey and then introduce a backdoor for getting a login cookie without having to go to any page, something similar to what I describe [here](http://blog.proxerd.pl/article/using-remote-control-plugin-to-log-in-into-a-grails-application-with-spring-security-backed-authentication). – erdi Mar 18 '15 at 15:48