Spock for Integration Testing (like Rest Services) and for Functional Testing (with Selenium):
We explored about Mocking, Stubbing and Spying in Spock in our previous tutorial.
In this Full Training Tutorial Series on Spock, so far we covered, writing unit tests using the Spock framework. Unit tests, typically test a single class with all the integration points or external calls are being replaced by mock calls or stubs.
Integration tests, in contrast, test the integration points between 2 pieces. For Example, testing the contracts between 2 services, testing integration between service and database, etc.
In this tutorial, we will learn how to use Spock for Integration testing (like rest services) and for functional testing. For Example, Integrating Spock with Selenium, etc.
Here is a Video Tutorial:
Table of Contents:
Spring Spock Integration
Let’s try understanding this with an example, of how we can integrate Spock with Spring boot MVC based apps.
Although Spring, has a rich set of annotations and integrates well with JUnit, Spock adds or helps to add an easy to read BDD styled testing approach which thereby makes test specifications highly readable.
About the Application
We will use a gradle based spring boot starter application, with a rest based controller implementing an endpoint.
Required Dependencies
In addition to the spring boot dependencies, we will add the usual groovy compile dependency as well as a Spock core dependency. Another Spock based dependency is Spock-spring, which allows Spock specifications to use Spring-based annotations.
Enlisted below is the list of required dependencies:
- implementation ‘org.springframework.boot:spring-boot-starter’
- testImplementation ‘org.springframework.boot:spring-boot-starter-test’
- compile “org.codehaus.groovy:groovy-all:2.4.8”
- testCompile “org.spockframework:spock-core:1.2-groovy-2.4”
- testCompile group: ‘org.spockframework’, name: ‘spock-spring’, version: ‘1.2-groovy-2.4’
Getting Started
Let’s get started with the actual test.
In the first test, we will check whether the bean gets created for the controller class that we have added. For this, the application should get started when the test is run.
In order to achieve this, we will add @SpringBootTest annotation which ensures running the application Context before the test gets executed.
Below is the test code:
@SpringBootTest class SampleSpringSpec extends Specification { @Autowired private WebController webController def "when context is loaded then controller bean is created"() { expect: "the WebController is created" webController != null } }
In the above code, you can see that we have used @SpringBootTest annotation which ensures to start the ApplicationContext, before the test gets executed and we have also auto-wired the WebController bean as per the Spring annotations.
The test validates that the Webcontroller bean gets instantiated as a part of the application context.
Let’s see another test, where we will hit the exposed endpoint by the Web controller, and validate the response code as well as the response text through the Spring framework test classes i.e. MockMvc and MockMvcRequestBuilders.
Please refer to the test code below:
@AutoConfigureMockMvc(secure=false) @WebMvcTest() class SampleMvcSpec extends Specification{ @Autowired private MockMvc mvc def "assert response and status code for /greeting"() { expect: "status code as 200 and response string as Hello world!" mvc.perform(MockMvcRequestBuilders.get("/hello")) .andExpect(MockMvcResultMatchers.status().isOk()) .andReturn().response.contentAsString == "Hello world!" } }
Spock Selenium Integration
Here is a Video Tutorial:
Now let’s see an example of how we can integrate Selenium-based tests using Spock. These require no other specific dependency, but in general, you can use the existing ways to organize selenium tests using BDD more effectively.
In this Example, we will see a simple selenium test through ChromeWebDriver which tries to search for a keyword on google search and verify the title of the search results page.
class SeleniumSpec extends Specification { private static def WebDriver driver = new ChromeDriver() def "cleanupSpec"() { if(driver != null) { driver.close() } } def "selenium integration with spock"() { given: driver.navigate().to("https://www.google.co.in") WebElement searchBox = driver.findElement(By.cssSelector("input[name=q]")); WebElement submitSearchButton = driver.findElement(By.cssSelector("input[name=btnK]")); when: searchBox.sendKeys("India") Thread.sleep(5000) submitSearchButton.click() def title = driver.getTitle() then: title.toLowerCase()contains("india") } }
Notice how we have declared the webdriver instance for ChromeDriver and used within the spec.
Also, in a given step, we have declared/defined all the web elements that we would require for test execution.
The Spock framework can also be integrated and used with the existing Automation framework and we can just replace Java/JUnit based tests with Spock to utilize the power of declarative programming in Groovy.
Conclusion
In this tutorial, we explored the different ways of integrating Spock based tests with other frameworks and test types like Integration tests and End-2-End tests.
We saw examples of Spock integration with Spring framework and Selenium-based Integration tests. Similar to these, Spock can also be used to write tests with Rest clients for Integration testing of REST-based APIs.
Quickly prepare for a Spock Interview with your upcoming tutorial, which covers a list of the most important Spock Interview Questions!!