# Functional Automation Testing using Geb and Spock Aayush Tuladhar
# Who Am I ? * Aayush Tuladhar * Full Stack Engineer @ Promotions
# Agenda * Functional Testing * Spock Framework and Primer * Geb * Demo * Questions
## Buidling the Right Thing ![Buidling Right Thing](img/ building-right-thing.jpeg)
## Functional Testing * Testing Actual User Functionality Before User Finds Issue * Helps Identify Defects which cannot be identified by Unit Tests and Integration Tests * Important Aspect of Software Development Life Cycle * Web Application Development * Agile Development Model * Service Oriented Systems * Automation is the Key
## Spock * Testing and Specification Framework for Java and Groovy * Written in Groovy * Why Spock * Simple and Declarative Language * Supports Data Driven Tests * Mocking Framework Built In * Spock = (Specification + Mock) * IDE Support
## Writing Spock Tests * Extend `spock.lang.Specification` ``` class MyFirstSpec extends Specification { // fields // feature methods // fixture methods // helper methods } ```
### Feature Methods * Heart of the Specification * Provides description of what feature does ``` def "descriptive name"(){ //blocks } ```
### Blocks * Defined Phases within a feature method * Labels are used to define start of the block ``` setup: given: when: // Stimulus then: // Response expect: // Response cleanup: ```
### Fixture Methods * Setting up and Cleaning up Environment * All Fixture Methods are optional ``` // Run Before Every Feature Method def setup(){} // Run After Every Feature Method def cleanup(){} // Run Before the First Feature Method def setupSpec(){} // Run After the Last Feature Method def cleanupSpec(){} ```
### Just Like JUnit | Spock | Junit | |--------|-------------| |`setup` |`setUp`, @Before | |`cleanup`|`tearDown`, @After| |`setupSpec`|`@BeforeClass`| |`cleanupSpec`|`@AfterClass`|
### Helper Methods * Frequently Used Setup/Cleanup Logic * Frequently Used Validations
## Demo - Spock REST API Testing [Demo Gist](https://gist.github.com/arttuladhar/0c6ca355c2b089155029b0a8caf8bce7)
## GEB * It is not a testing Tool but a browser Automation Tool * Geb is built on top of WebDriver Browser Automation Library * First class support and integration with common testing framework and build tools
### Why GEB * Expressiveness of Groovy (BDD) * jQuery style content inspection / navigation model ``` $("#submitBtn").click(); ``` * Page Object Model * Content DSL ``` assert title == 'Hello World' ``` * Power of Web Driver * Integration Support
### Geb Configuration * `src/test/resources/GebConfig.groovy` * `driver` * `baseUrl` * `reportsDir` * `reportOnTestFailureOnly` ``` import org.openqa.selenium.chrome.ChromeDriver def final String DRIVER = 'src/test/resources/driver/chromedriver' System.setProperty('webdriver.chrome.driver', DRIVER); driver = { new ChromeDriver() } baseUrl = "http://localhost:3000/" reportsDir = new File("target/geb-reports") reportOnTestFailureOnly = true ```
### Sample Geb Functional Test * `src/test/groovy/specs/FirstSpec.groovy` ``` package specs import geb.spock.GebReportingSpec class HomePageSpec extends GebReportingSpec{ def "User Should be able to visit Digi Marketplace Homepage"(){ when: "User enters Digi Marketplace Website" go "http://digimarketplace.aayushtuladhar.com/" then: "User should be able to see top Navbar" $("a.navbar-brand").text() == "Digi Marketplace" then: "User should be able to see Digi Marketplace Jumbotrom" $("h2").text() == "Digi Marketplace" } } ```
### `go()` - Using **go** method, you can make a new URL request # Make a direct URL request go "http://www.google.com" # Go to URL relative to base URL go "signup" # Go to URL with request parameter go "signup", param1: "value1", param2: "value2"
### `$()` - Interacting with Content * `$()` function is the access point to the browser's page content. * Returns *Navigator* object analogous to a jQuery object ``` $(css_selector, index_or_range, attribute) ```
``` // CSS Selector $("h1", class: heading1) // Index and Ranges $("p", 0).text() == "Hello World" // Attribute and Text Matching $("p", attr1: "a").size() == 1 // Finding and Filtering Descendants $("div").find(".heroElement") $("div").has("elments") // Clicking Elements $("a.help").click() ``` ``` // Form Values $("input#userName").value() == "Hello World" $("input#userEmail").value("helloWorld@gmail.com") # Select Button $("form").state="MN" # Checkbox $("form").isRockStar = true ```
## Demo - Form Validation Testing [Demo Gist](https://gist.github.com/arttuladhar/0c6ca355c2b089155029b0a8caf8bce7)
### Questions