End-to-end tests with Spock, Geb, Unirest, and Appium (e2e-spock-geb)

Spock, Geb, Unirest, and Appium e2e testing quickstarter project

Purpose of this quickstarter

This is a Spock, Geb, Unirest, and Appium e2e testing project quickstarter with basic setup for Jenkins, SonarQube, Gradle, and Appium.

What files / architecture is generated?

.
├── Jenkinsfile
├── .pre-commit-config.yaml
├── README.md
├── sonar-project.properties
├── src
│   ├── test
│   │   └── acceptance
│   │   │   └── groovy
│   │   │   │   └── modules
│   │   │   │       └── DemoManualMenuModule.groovy
│   │   │   │   └── pages
│   │   │   │       └── DemoGebHomePage.groovy
│   │   │   │       └── DemoTheBookOfGebPage.groovy
│   │   │   │   └── specs
│   │   │   │       └── DemoGebHomePageSpec.groovy
│   │   │   │       └── DemoMobileAppSpec.groovy
│   │   │   │       └── DemoMobileGebHomePageSpec.groovy
│   │   │   └── java
│   │   │       └── DemoAcceptanceTest.java
│   │   └── installation
│   │   │   └── groovy
│   │   │   │   └── DemoInstallationSpec.groovy
│   │   │   └── java
│   │   │       └── DemoInstallationTest.java
│   │   └── integration
│   │   │   └── groovy
│   │   │   │   └── DemoIntegrationSpec.groovy
│   │   │   └── java
│   │   │       └── DemoIntegrationTest.java
│   │   └── resources
│   │   │   └── helpers
│   │   │       └── Environments.groovy
│   │   │       └── SpecHelper.groovy
│   │   │   └── application.properties
│   │   │   └── GebConfig.groovy
├── gradle
│   └── wrapper
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── build.gradle
├── gradlew
└── gradlew.bat

Gradle Support

The generated project includes a gradlew wrapper which is a portable distribution of gradle. It allows you to easily build the project without any further tool installation other than java.

Gradle Artifacts

You´ll find in the project following gradle artifacts:

  • build.gradle (build definition)

  • gradlew.bat

  • gradlew

  • gradle/wrapper/gradle-wrapper.jar

  • gradle/wrapper/gradle.properties

gradle.properties is missing. This is on purpose, because you need to define it on your own by providing your nexus configuration.

Nexus configuration in gradle.properties

You´ll need to create gradle.properties yourself and add following properties:

nexus_url=<URL_OF_YOUR_NEXUS_SERVER>
nexus_user=<YOUR_NEXUS_USERNAME>
nexus_pw=<YOUR_NEXUS_PASSWORD>

If you do not want to use Nexus at all, just define the following property:

no_nexus=true

Run gradlew -v to verify the installed version of gradle wrapper.

Environments Configuration

The environments used in the tests are defined in the build.gradle file. You can find the environments under the ext block as project properties. These environments are accessed via system properties in the Groovy classes. Here is an example of how the environments are defined:

ext {
...
    environments = [
        DESKTOP: "desktop",
        MOBILE_BROWSER: "mobile_browser",
        MOBILE_APP: "mobile_app"
    ]
}
...
tasks.withType(Test) {
    systemProperty 'environments.desktop', environments.DESKTOP
    systemProperty 'environments.mobile_browser', environments.MOBILE_BROWSER
    systemProperty 'environments.mobile_app', environments.MOBILE_APP
}

Additionally, there is a class called Environments.groovy that facilitates access to these environments from the Groovy code. The class is located in the src/test/resources/helpers directory.

package helpers

class Environments {
    // Define environment constants using system properties
    // Check the build.gradle file for the defined properties
    static final String DESKTOP = System.getProperty('environments.desktop')
    static final String MOBILE_BROWSER = System.getProperty('environments.mobile_browser')
    static final String MOBILE_APP = System.getProperty('environments.mobile_app')
}

For each environment, we have a driver configured in the GebConfig.groovy file:

	environments {

	  // Configuration for desktop environment using HtmlUnitDriver
	  "${Environments.DESKTOP}" {
	    driver = {
	      HtmlUnitDriver driver = new HtmlUnitDriver(BrowserVersion.BEST_SUPPORTED, true) {
	      ...
	      }
	    }
	  }

	  // Configuration for mobile browser environment using AndroidDriver
	  "${Environments.MOBILE_BROWSER}" {
	    driver = {
	      MutableCapabilities caps = new MutableCapabilities()
	      ...
	      MutableCapabilities sauceOptions = new MutableCapabilities()
	      ...
	      caps.setCapability("sauce:options", sauceOptions)
	      URL url = new URL("https://ondemand.eu-central-1.saucelabs.com:443/wd/hub")
	      AndroidDriver driver = new AndroidDriver(url, caps)
	      return driver
	    }
	  }

	  // Configuration for mobile app environment using IOSDriver
	  "${Environments.MOBILE_APP}" {
	    driver = {
	      MutableCapabilities caps = new MutableCapabilities()
	      ...
	      MutableCapabilities sauceOptions = new MutableCapabilities()
	      ...
	      caps.setCapability("sauce:options", sauceOptions)
	      URL url = new URL("https://ondemand.eu-central-1.saucelabs.com:443/wd/hub")
	      IOSDriver driver = new IOSDriver(url, caps)
	      return driver
	    }
	  }
	}

In the build.gradle file, there is also a filter by environment and tags:

  // Specify the tags to include/exclude for each environment
  // Please, adjust the tags according to your project needs
  useJUnitPlatform {
    switch (env) {
      case environments.DESKTOP:
        includeTags 'test_desktop'
        break
      case environments.MOBILE_BROWSER:
        includeTags 'test_mobile_browser'
        break
      case environments.MOBILE_APP:
        includeTags 'test_mobile_app'
        break
    }
  }

Sauce Labs Integration

Sauce Labs is a cloud-based platform that provides comprehensive testing solutions for web and mobile applications. It allows you to run tests on a wide range of real devices and emulators/simulators, ensuring your applications work seamlessly across different environments.

This template is prepared to work with Sauce Labs virtual devices, allowing you to perform all mobile tests on these virtual devices.

Key Features of Sauce Labs

  • Real Device Cloud: Access to thousands of real Android and iOS devices for manual and automated testing.

  • Emulators and Simulators: Cost-effective and scalable testing on virtual devices.

  • Cross-Browser Testing: Ensure compatibility across various browser and OS combinations.

  • Error Monitoring and Reporting: Capture and resolve application errors quickly with detailed insights.

  • CI/CD Integration: Seamlessly integrate with your continuous integration and delivery pipelines.

Credentials for Sauce Labs

To execute tests on Sauce Labs, you need Sauce Labs credentials. These credentials are stored in a secret called sauce-labs-user-access-key, which by default is created with "changeme" values for both username and password. Users will need to update these values with their actual Sauce Labs credentials.

In the Jenkinsfile, the credentials are retrieved as follows:

	// Use credentials for SauceLabs authentication
	// You can remove this block if you are not using SauceLabs
	withCredentials([
	  usernamePassword(credentialsId: "${context.projectId}-cd-sauce-labs-user-access-key", passwordVariable: 'SAUCE_LABS_ACCESS_KEY', usernameVariable: 'SAUCE_LABS_USERNAME'),
	]) {
    ...
	}

In the GebConfig.groovy file, these credentials are used to configure the drivers:

	// Get SauceLabs environment variables for configuring iOS device
	def sauceLabsUsername = System.getenv('SAUCE_LABS_USERNAME')
	def sauceLabsAccessKey = System.getenv('SAUCE_LABS_ACCESS_KEY')

This setup ensures that your tests can authenticate with Sauce Labs and run on the specified virtual devices.

Usage - how do you start after you provisioned this quickstarter

  • Run command gradlew test in project directory to execute the end-to-end tests via spock/geb against the demo pages and demo jUnit 5 tests.

You will see the results inside a new folder 'build' in project directory.

.
└── build
    └── test-results
        ├── acceptance-groovy-desktop
        ├── acceptance-java-desktop
        │   │── TEST-DemoAcceptanceTest.xml
        │   │── TEST-specs.DemoGebHomePageSpec.xml
        │   │── TEST-specs.DemoMobileAppSpec.xml
        │   └── TEST-specs.DemoMobileGebHomePageSpec.xml
        ├── installation-groovy-desktop
        ├── installation-java-desktop
        │   │── TEST-DemoInstallationSpec.xml
        │   └── TEST-DemoInstallationTest.xml
        ├── integration-groovy-desktop
        └── integration-java-desktop
            │── TEST-DemoIntegrationSpec.xml
            └── TEST-DemoIntegrationTest.xml

Frameworks used

This project is generated by Gradle

Customization - how do you start to configure your test

  • You can see how a Java Junit 5 test are developed showing the Demo*Test.java files.

  • You can see how a Groovy Spock/Geb test are developed showing the Demo*Spec.groovy files.

    • The url to test with Geb is configured in the property config.application.url inside application.properties

    • Inside GebConfig.groovy you could see some environments with different drivers defined and a default browser. You could configure or change them as you need.

How this quickstarter is built through jenkins

The Jenkinsfile is provisioned with this quickstarter to ease CI/CD process. In Jenkinsfile.template, there is the following stage:

  • stageTest - Run the programed e2e test with this order:

    • installation-java

    • installation-groovy

    • integration-java

    • integration-groovy

    • acceptance-java

    • acceptance-groovy

All the results are stashed and published through Jenkins jUnit publisher.

Builder agent used

This quickstarter uses the jdk Jenkins builder agent.

Known limitations

NA