Writing End-to-End Tests With Spock Framework – Configuration (Spring Boot Edition)
After we have finished this lesson, we:
- Understand how we can start our Spring Boot application before our end-to-end tests are run.
- Know how we can configure our end-to-end tests by using a custom test execution listener.
- Can initialize our database into a known state before a feature method is run.
This lesson assumes that:
- You can run your end-to-end tests by using either Maven or Gradle
- You are familiar with Selenium WebDriver
- You can configure your end-to-end tests when you are using JUnit
- You are familiar with Spock Framework
Important note:
You must finish the lessons: Configuring Our End-to-End Tests – Spring Boot and Initializing Our Database With the @Sql Annotation before you continue this lesson. These lessons describe how you can start your Spring Boot application, create a custom TestExecutionListener
that configures Selenium WebDriver, and iniatialize your database into a known state by using the @Sql
annotation.
Because I don’t want to repeat myself, this lesson doesn’t provide a comprehensive description of these techniques. The goal of this lesson is to simply demonstrate how you can use these techniques when you are writing end-to-end tests with Spock framework.
Watch the Lesson
The text version of this lesson is given the following:
Configuring Our End-to-End Tests
We can configure our end-to-end tests by following these steps:
First, we have to create a new specification class and ensure that its feature methods are run when we run our end-to-end tests. After we have created a new specification class, its source code looks as follows:
import org.junit.experimental.categories.Category import spock.lang.Specification @Category(EndToEndTest.class) class ExampleSpec extends Specification { }
Second, we have to load the application context of our Spring Boot application. After we have done this, the source code of our specification class looks as follows:
import org.junit.experimental.categories.Category import org.springframework.boot.test.context.SpringBootTest import spock.lang.Specification @SpringBootTest(classes = TaskTrackerApplication.class) @Category(EndToEndTest.class) class ExampleSpec extends Specification { }
Third, we have to ensure that our Spring Boot application is started when its application context is loaded. Also, we must remember to specify the port that is listened by the started Spring Boot application. Because our example uses the default port (8080), we don’t have to make any other changes to our configuration.
After we have made the required changes to our specification class, its source code looks as follows:
import org.junit.experimental.categories.Category import org.springframework.boot.test.context.SpringBootTest import org.springframework.boot.test.context.SpringBootTest.WebEnvironment import spock.lang.Specification @SpringBootTest(classes = TaskTrackerApplication.class, webEnvironment = WebEnvironment.DEFINED_PORT ) @Category(EndToEndTest.class) class ExampleSpec extends Specification { }
Fourth, we have to specify the Spring profile that is used when the feature methods of our specification class are run (endToEndTest). After we have done this, the source code of our specification class looks as follows:
import org.junit.experimental.categories.Category import org.springframework.boot.test.context.SpringBootTest import org.springframework.boot.test.context.SpringBootTest.WebEnvironment import org.springframework.test.context.ActiveProfiles import spock.lang.Specification @SpringBootTest(classes = TaskTrackerApplication.class, webEnvironment = WebEnvironment.DEFINED_PORT ) @ActiveProfiles(Profiles.END_TO_END_TEST) @Category(EndToEndTest.class) class ExampleSpec extends Specification { }
Fifth, we have to configure Selenium WebDriver by using the custom TestExecutionListener
that we created in the lesson: Configuring Our End-to-End Tests – Spring Boot. We can do this by following these steps:
- Annotate our specification class with the
@SeleniumTest
annotation and ensure that the type of the createdWebDriver
object isChromeDriver
. - Add a
WebDriver
field to our specification class and ensure that the createdWebDriver
object is injected into that field.
After we have configured Selenium WebDriver, the source code of our specification class looks as follows:
import org.junit.experimental.categories.Category import org.openqa.selenium.WebDriver import org.openqa.selenium.chrome.ChromeDriver import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.context.SpringBootTest import org.springframework.boot.test.context.SpringBootTest.WebEnvironment import org.springframework.test.context.ActiveProfiles import spock.lang.Specification @SpringBootTest(classes = TaskTrackerApplication.class, webEnvironment = WebEnvironment.DEFINED_PORT ) @SeleniumTest(driver = ChromeDriver.class) @ActiveProfiles(Profiles.END_TO_END_TEST) @Category(EndToEndTest.class) class ExampleSpec extends Specification { @Autowired WebDriver browser }
Sixth, we have ensure that the existing data is deleted from the database after a feature method has been run. After we have made the required changes to our specification class, its source code looks as follows:
import org.junit.experimental.categories.Category import org.openqa.selenium.WebDriver import org.openqa.selenium.chrome.ChromeDriver import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.context.SpringBootTest import org.springframework.boot.test.context.SpringBootTest.WebEnvironment import org.springframework.test.context.ActiveProfiles import org.springframework.test.context.jdbc.Sql import spock.lang.Specification import static org.springframework.test.context.jdbc.Sql.ExecutionPhase.AFTER_TEST_METHOD @SpringBootTest(classes = TaskTrackerApplication.class, webEnvironment = WebEnvironment.DEFINED_PORT ) @SeleniumTest(driver = ChromeDriver.class) @Sql( value = 'classpath:/com/testwithspring/master/cleandb.sql', executionPhase = AFTER_TEST_METHOD ) @ActiveProfiles(Profiles.END_TO_END_TEST) @Category(EndToEndTest.class) class ExampleSpec extends Specification { @Autowired WebDriver browser }
Seventh, we have to initialize our database into a known state before a feature method is run. We can do this by following these steps:
- Insert the user data into our database.
- Insert the task data into our database.
After we have made the required changes to our specification class, its source code looks as follows:
import org.junit.experimental.categories.Category import org.openqa.selenium.WebDriver import org.openqa.selenium.chrome.ChromeDriver import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.context.SpringBootTest import org.springframework.boot.test.context.SpringBootTest.WebEnvironment import org.springframework.test.context.ActiveProfiles import org.springframework.test.context.jdbc.Sql import spock.lang.Specification import static org.springframework.test.context.jdbc.Sql.ExecutionPhase.AFTER_TEST_METHOD @SpringBootTest(classes = TaskTrackerApplication.class, webEnvironment = WebEnvironment.DEFINED_PORT ) @SeleniumTest(driver = ChromeDriver.class) @Sql(value = [ 'classpath:/com/testwithspring/master/users.sql', 'classpath:/com/testwithspring/master/tasks.sql' ]) @Sql( value = 'classpath:/com/testwithspring/master/cleandb.sql', executionPhase = AFTER_TEST_METHOD ) @ActiveProfiles(Profiles.END_TO_END_TEST) @Category(EndToEndTest.class) class ExampleSpec extends Specification { @Autowired WebDriver browser }
We can now configure our end-to-end tests when we are using Spock Framework. Also, this configuration allows us to configure the state of the WebDriver
object before a feature method is run and clear the state of the WebDriver
object after a feature method has been run. For example, we can implement a setup()
method that logs a user in and write a cleanup()
method that logs the user out.
Let’s summarize what we learned from this lesson.
Summary
This lesson has taught us four things:
- We can start our Spring Boot application by setting the value of the
@SpringBootTest
annotation’swebEnvironment
attribute toWebEnvironment.DEFINED_PORT
. - Our custom
TestExecutionListener
creates a newWebDriver
object and injects the created object into a Spock specification. - We can initialize the state of the
WebDriver
object in thesetup()
method and clean its state in thecleanup()
method. - We can initialize our database into a known state by annotating our specification class with the required
@Sql
annotations.
Previous LessonNext Lesson