# 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)