title: Spring Boot With Cucumber Integration
body: <p>I have been working on a spring boot application I would like to test with cucumber (for business driven development).  I can successfully run the cucumber tests with my code, or I can boot the spring context, but I cannot seem to figure out a way to do both at once.  I have looked around, and found a few tutorials (such as <a href="https://medium.com/@bcarunmail/set-up-and-run-cucumber-tests-in-spring-boot-application-d0c149d26220" rel="nofollow noreferrer">https://medium.com/@bcarunmail/set-up-and-run-cucumber-tests-in-spring-boot-application-d0c149d26220</a>) that all seem to have this working.  I followed the same premise as them, that is, (1) having one class that loads the spring context, (2) having another class be the entry point for discovering the cucumber tests, and finally, (3) a class containing the step definitions that extends the class with the context referenced in number one.</p>
  
  <p>Here are my classes</p>
  
  <pre><code>import org.junit.ClassRule;
  import org.junit.Ignore;
  import org.junit.Test;
  import org.junit.runner.RunWith;
  import org.springframework.beans.factory.annotation.Value;
  import org.springframework.boot.test.context.SpringBootTest;
  import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
  import org.springframework.boot.test.util.TestPropertyValues;
  import org.springframework.boot.test.web.client.TestRestTemplate;
  import org.springframework.boot.web.server.LocalServerPort;
  import org.springframework.context.ApplicationContextInitializer;
  import org.springframework.context.ConfigurableApplicationContext;
  import org.springframework.test.context.ContextConfiguration;
  import org.springframework.test.context.junit4.SpringRunner;
  import org.testcontainers.containers.MySQLContainer;
  
  import com.connor.Application;
  
  /**
   * This class should take care of initializing the test container (for the database) and         populating it using the
   * sql files that run against the actual db, in the actual order they execute.  This guarantees these will run 
   * before we even use a staging region.  Once the database is created, it boots the spring context the spring context
   * and configures the environment with the db-related info from the test container.
   * 
   * When ran alone, this test successfully performs the above steps and can be used for integration tests.
   * However, when this class is extended by other classes (the glue code classes), it does not boot the spring context
   * and hence do not work for integration tests. 
   * @author connor
   *
   */
  @RunWith(SpringRunner.class)
  @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, classes = Application.class)
  @ContextConfiguration(initializers = SpringContextConfigForCukeUsage.Initializer.class)
  //@Ignore //even with this, still need a test method to compile
  public /* abstract */ class SpringContextConfigForCukeUsage { //with or without abstract, this doesn't seem to work . . .
  
  /**
   * Use with String.format to build the base url string when testing locally.
   */
  private static final String LOCAL_BASE_URL_FORMAT_STR = "%s:%d";
  
  /**
   * Create the mysql test container as a class rule.
   */
  @ClassRule
  public static MySQLContainer&lt;?&gt; mysqlDb = new MySQLContainer&lt;&gt;("mysql:latest")  //TODO may not want the latest version . . . 
  .withInitScript("schema.sql");
  
  /**
   * The base url for the tests.  By passing in here, we allow for testing actual environments, as well as integration tests with the same code.
   * If no value is passed, defaults to localhost, and will be combined with port to build base url
   */
  @Value("${BASE_URL:locahost}")
  private String baseUrl;
  
  /**
   * For getting access to the port the spring boot context is running on in subclasses
   */
  @LocalServerPort
  protected int serverPort;   
  
  //Decide whether to use rest template or test res template here
  
  /**
   * Used in subclasses to get access to the base url for testing.
   * @return
   */
  protected String getBaseUrl() {
      String baseUrlToReturn;
  
      //if it is local, append the port
      if(baseUrl != null &amp;&amp; baseUrl.contains("localhost")){
          baseUrlToReturn = String.format(LOCAL_BASE_URL_FORMAT_STR, baseUrl, serverPort);
      }
      //otherwise, return the environment variable, which will always be available on standard http(s) port
      else {
          baseUrlToReturn = baseUrl;
      }
  
      return baseUrlToReturn;
  }
  
  /**
   * This initalizer class takes care of setting the properties from the test container into environment variables.
   * This allows integration tests to be as close to real testing as possible.
   * @author connor
   *
   */
   public static class Initializer implements ApplicationContextInitializer&lt;ConfigurableApplicationContext&gt; {
  
      @Override
      public void initialize(ConfigurableApplicationContext applicationContext) {
          //add the url, username, and password to the test context before it starts
          TestPropertyValues.of(String.format("spring.datasource.url=%s", mysqlDb.getJdbcUrl()),
                  String.format("spring.datasource.username=%s", mysqlDb.getUsername()),
                  String.format("spring.datasource.password=%s", mysqlDb.getPassword()))
          .applyTo(applicationContext.getEnvironment());  
      }        
   }
  
   /**
    * This method is only here to test when running alone for debugging . . .
    */
   @Test
   public void test() {
       //just here for compilation when testing this class by itself-- will not execute if no test here
   }
  </code></pre>
  
  <p>}</p>
  
  <p>Here is the second class, the one with the entry point for the cucumber tests</p>
  
  <pre><code>import org.junit.runner.RunWith;
  
  import cucumber.api.CucumberOptions;
  import cucumber.api.junit.Cucumber;
  
  /**
   * This is the entry point for running the cucumber tests.
   * @author connor
   *
   */
  @RunWith(Cucumber.class)
  @CucumberOptions(features = "src/it/resources/AddingAssessment.feature")
  public class RunCukesIT {
      //intentionally blank -- annotations do all the work
  }
  </code></pre>
  
  <p>Finally, here is my third class containing my step definitions:</p>
  
  <pre><code>import cucumber.api.java8.En;
  
  /**
   * This class contains the glue code for the "given when then" step definitions.
   * This extends the class that bots the spring context, but it does not boot the 
   * context
   * @author connor
   *
   */
  //even with these annotations, it does not load spring boot context
  //@RunWith(SpringRunner.class)
  //@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, classes = Application.class)
  //@ContextConfiguration(initializers = SpringContextConfigForCukeUsage.Initializer.class)
  public class CukeGWT extends SpringContextConfigForCukeUsage implements En {
  
  public CukeGWT() {
      Given("we are attempting to add a test for a book", () -&gt; {
          // Write code here that turns the phrase above into concrete actions
          //throw new cucumber.api.PendingException();
          System.out.println("\n\n\n\n\n\n\n\n\n\n\n\n" + serverPort); //always 0 (because context doesn't load)
  //          
          System.out.println("Env property is " + System.getenv("local.server.port")); //this also indicates server doesn't start 
      });
  
      Given("the book has isbn {int}", (Integer int1) -&gt; {
          // Write code here that turns the phrase above into concrete actions
          //throw new cucumber.api.PendingException();
      });
  
      Given("the author of the book has first name conn", () -&gt; {
          // Write code here that turns the phrase above into concrete actions
          //throw new cucumber.api.PendingException();
      });
  
      Given("the author of the book has last name b", () -&gt; {
          // Write code here that turns the phrase above into concrete actions
          //throw new cucumber.api.PendingException();
      });
  
      Given("the book has {int} questions", (Integer int1) -&gt; {
          // Write code here that turns the phrase above into concrete actions
          //throw new cucumber.api.PendingException();
      });
  
      Given("one of the questions has incorrect answers a hen, a cat", () -&gt; {
          // Write code here that turns the phrase above into concrete actions
          //throw new cucumber.api.PendingException();
      });
  
      Given("the question has correct answer a dog", () -&gt; {
          // Write code here that turns the phrase above into concrete actions
          //throw new cucumber.api.PendingException();
      });
  
      When("the api is called", () -&gt; {
          // Write code here that turns the phrase above into concrete actions
          //throw new cucumber.api.PendingException();
      });
  
      Then("the api will return a valid response", () -&gt; {
          // Write code here that turns the phrase above into concrete actions
          //throw new cucumber.api.PendingException();
      });
  
      Then("the isbn will match", () -&gt; {
          // Write code here that turns the phrase above into concrete actions
          //throw new cucumber.api.PendingException();
      });
  
      Then("the author's first name will match", () -&gt; {
          // Write code here that turns the phrase above into concrete actions
          //throw new cucumber.api.PendingException();
      });
  
      Then("the author's last name will match", () -&gt; {
          // Write code here that turns the phrase above into concrete actions
          //throw new cucumber.api.PendingException();
      });
  
      Then("the question added above will exist", () -&gt; {
          // Write code here that turns the phrase above into concrete actions
          //throw new cucumber.api.PendingException();
      });
  
      Then("the book will be unverified", () -&gt; {
          // Write code here that turns the phrase above into concrete actions
          //throw new cucumber.api.PendingException();
      });
  
      Given("the author of the book has first name test", () -&gt; {
          // Write code here that turns the phrase above into concrete actions
          //throw new cucumber.api.PendingException();
      });
  
      Given("the author of the book has last name testing", () -&gt; {
          // Write code here that turns the phrase above into concrete actions
          //throw new cucumber.api.PendingException();
      });
  
      Given("one of the questions has incorrect answers true", () -&gt; {
          // Write code here that turns the phrase above into concrete actions
          //throw new cucumber.api.PendingException();
      });
  
      Given("the question has correct answer false", () -&gt; {
          // Write code here that turns the phrase above into concrete actions
          //throw new cucumber.api.PendingException();
      });
  
      Given("an assessment with valid data is generated", () -&gt; {
          // Write code here that turns the phrase above into concrete actions
          //throw new cucumber.api.PendingException();
      });
  
      Then("the api will return an error response", () -&gt; {
          // Write code here that turns the phrase above into concrete actions
          //throw new cucumber.api.PendingException();
      });
  
      Then("the http status code will be {int}", (Integer int1) -&gt; {
          // Write code here that turns the phrase above into concrete actions
          //throw new cucumber.api.PendingException();
      });
  
      Then("the error message will contain A test already exists for this book", () -&gt; {
          // Write code here that turns the phrase above into concrete actions
          //throw new cucumber.api.PendingException();
      });
    } 
  }
  </code></pre>
  
  <p>Here is my pom for reference of the dependencies/versions</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  </code></pre>
  
  <p>https://maven.apache.org/xsd/maven-4.0.0.xsd">
      4.0.0
      
          org.springframework.boot
          spring-boot-starter-parent
          
          2.1.3.RELEASE
          
      
      com.connor
      reading-comprehension-api
      0.0.1-SNAPSHOT
      reading-comprehension-api
      This is the containerized webservice for reading
          comprehension
      </p>
  
  <pre><code>&lt;properties&gt;
      &lt;!-- miscellaneous properties --&gt;
      &lt;docker.image.prefix&gt;connordocker&lt;/docker.image.prefix&gt;
      &lt;java.version&gt;1.8&lt;/java.version&gt;
  
      &lt;!-- get as much info as we can locally for development --&gt;
      &lt;downloadSources&gt;true&lt;/downloadSources&gt;
      &lt;downloadJavadocs&gt;true&lt;/downloadJavadocs&gt;
  
      &lt;!-- versions, please keep in alphabetical order --&gt;
      &lt;cucumber.version&gt;4.2.5&lt;/cucumber.version&gt;
      &lt;testcontainer.version&gt;1.12.4&lt;/testcontainer.version&gt;
  &lt;/properties&gt;
  
  &lt;dependencies&gt;
      &lt;!-- bring this in once database is integrated and defined in properties 
          file --&gt;
      &lt;dependency&gt;
          &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
          &lt;artifactId&gt;spring-boot-starter-data-jdbc&lt;/artifactId&gt;
      &lt;/dependency&gt;
  
      &lt;dependency&gt;
          &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
          &lt;artifactId&gt;spring-boot-starter-web&lt;/artifactId&gt;
      &lt;/dependency&gt;
  
      &lt;dependency&gt;
          &lt;groupId&gt;org.springframework&lt;/groupId&gt;
          &lt;artifactId&gt;spring-tx&lt;/artifactId&gt;
      &lt;/dependency&gt;
  
      &lt;!-- lets us connect to mysql db --&gt;
      &lt;dependency&gt;
          &lt;groupId&gt;mysql&lt;/groupId&gt;
          &lt;artifactId&gt;mysql-connector-java&lt;/artifactId&gt;
      &lt;/dependency&gt;
  
      &lt;dependency&gt;
          &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
          &lt;artifactId&gt;spring-boot-starter-test&lt;/artifactId&gt;
          &lt;scope&gt;test&lt;/scope&gt;
          &lt;exclusions&gt;
              &lt;exclusion&gt;
                  &lt;groupId&gt;org.junit.vintage&lt;/groupId&gt;
                  &lt;artifactId&gt;junit-vintage-engine&lt;/artifactId&gt;
              &lt;/exclusion&gt;
          &lt;/exclusions&gt;
      &lt;/dependency&gt;
  
      &lt;!-- lets us use test containers; must use same version as mysql test container 
          below --&gt;
      &lt;dependency&gt;
          &lt;groupId&gt;org.testcontainers&lt;/groupId&gt;
          &lt;artifactId&gt;testcontainers&lt;/artifactId&gt;
          &lt;version&gt;${testcontainer.version}&lt;/version&gt;
          &lt;scope&gt;test&lt;/scope&gt;
      &lt;/dependency&gt;
  
      &lt;!-- mysql specific test container; must use same version as testcontainers --&gt;
      &lt;dependency&gt;
          &lt;groupId&gt;org.testcontainers&lt;/groupId&gt;
          &lt;artifactId&gt;mysql&lt;/artifactId&gt;
          &lt;version&gt;${testcontainer.version}&lt;/version&gt;
          &lt;scope&gt;test&lt;/scope&gt;
      &lt;/dependency&gt;
  
      &lt;!-- the below three dependencies are required for cucumber tests --&gt;
      &lt;dependency&gt;
          &lt;groupId&gt;io.cucumber&lt;/groupId&gt;
          &lt;artifactId&gt;cucumber-java8&lt;/artifactId&gt;
          &lt;version&gt;${cucumber.version}&lt;/version&gt;
          &lt;scope&gt;test&lt;/scope&gt;
      &lt;/dependency&gt;
      &lt;dependency&gt;
          &lt;groupId&gt;io.cucumber&lt;/groupId&gt;
          &lt;artifactId&gt;cucumber-java&lt;/artifactId&gt;
          &lt;version&gt;${cucumber.version}&lt;/version&gt;
          &lt;scope&gt;test&lt;/scope&gt;
      &lt;/dependency&gt;
      &lt;dependency&gt;
          &lt;groupId&gt;io.cucumber&lt;/groupId&gt;
          &lt;artifactId&gt;cucumber-junit&lt;/artifactId&gt;
          &lt;version&gt;${cucumber.version}&lt;/version&gt;
          &lt;scope&gt;test&lt;/scope&gt;
      &lt;/dependency&gt;
  &lt;/dependencies&gt;
  
  
  
  &lt;!-- create different profiles for each ci/cd stage --&gt;
  &lt;profiles&gt;
      &lt;!-- this is ran for every commit --&gt;
      &lt;profile&gt;
          &lt;id&gt;commit-profile&lt;/id&gt;
          &lt;activation&gt;
              &lt;!-- if we make this active by default, it runs, even when we explicitly 
                  mention another profile --&gt;
              &lt;!-- active by default --&gt;
              &lt;!-- &lt;activeByDefault&gt;true&lt;/activeByDefault&gt; --&gt;
          &lt;/activation&gt;
  
          &lt;build&gt;
              &lt;!-- TODO add compile plugin, surefire plugin here --&gt;
              &lt;plugins&gt;
                  &lt;plugin&gt;
                      &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
                      &lt;artifactId&gt;maven-compiler-plugin&lt;/artifactId&gt;
                  &lt;/plugin&gt;
                  &lt;!-- inherit surefire plugin for running unit tests. Overwrite and add 
                      additional configuration to ignore our integration tests --&gt;
                  &lt;plugin&gt;
                      &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
                      &lt;artifactId&gt;maven-surefire-plugin&lt;/artifactId&gt;
                      &lt;configuration&gt;
                          &lt;!-- ignore the integration tests (named *IT) which come from src/it/java, 
                              but are placed on classpath by the build helper plugin (IT must be on test 
                              classpath to run, but we don't want them running here) --&gt;
                          &lt;excludes&gt;
                              &lt;exclude&gt;**/*IT.java&lt;/exclude&gt;
                          &lt;/excludes&gt;
                      &lt;/configuration&gt;
                  &lt;/plugin&gt;
              &lt;/plugins&gt;
          &lt;/build&gt;
      &lt;/profile&gt;
  
      &lt;!-- this is ran on the merge to master --&gt;
      &lt;profile&gt;
          &lt;id&gt;merge-to-base-branch-profile&lt;/id&gt;
          &lt;!-- active when stage is merge -Dstage=merge --&gt;
          &lt;activation&gt;
              &lt;property&gt;
                  &lt;name&gt;stage&lt;/name&gt;
                  &lt;value&gt;merge&lt;/value&gt;
              &lt;/property&gt;
          &lt;/activation&gt;
  
          &lt;!-- TODO add enforcer plugin, failsafe plugin, codehaus plugin --&gt;
      &lt;/profile&gt;
  
      &lt;!-- this is ran and triggered by a tag --&gt;
      &lt;profile&gt;
          &lt;id&gt;deploy-profile&lt;/id&gt;
          &lt;!-- active when stage is deploy -Dstage=deploy, should be triggered by 
              tag from pipeline --&gt;
          &lt;activation&gt;
              &lt;property&gt;
                  &lt;name&gt;stage&lt;/name&gt;
                  &lt;value&gt;deploy&lt;/value&gt;
              &lt;/property&gt;
          &lt;/activation&gt;
          &lt;!-- not sure if we want to (or can) trigger deployment to cloud from 
              maven, or if we can --&gt;
      &lt;/profile&gt;
  
      &lt;!-- this profile is triggered for running integration tests --&gt;
      &lt;profile&gt;
          &lt;id&gt;integration-test-profile&lt;/id&gt;
          &lt;!-- make to skip unit tests so we don't get confused --&gt;
          &lt;properties&gt;
              &lt;skipTests&gt;true&lt;/skipTests&gt;
          &lt;/properties&gt;
          &lt;build&gt;
              &lt;plugins&gt;
                  &lt;!-- this plugin adds folders to the classpath. As of right now, it 
                      takes care of adding the integration tests (and feature files) to test classpath. --&gt;
                  &lt;plugin&gt;
                      &lt;groupId&gt;org.codehaus.mojo&lt;/groupId&gt;
                      &lt;artifactId&gt;build-helper-maven-plugin&lt;/artifactId&gt;
                      &lt;executions&gt;
                          &lt;!-- this execution adds the src/it/java to test classpath --&gt;
                          &lt;execution&gt;
                              &lt;id&gt;add-integration-test-source&lt;/id&gt;
                              &lt;phase&gt;generate-test-sources&lt;/phase&gt;
                              &lt;goals&gt;
                                  &lt;goal&gt;add-test-source&lt;/goal&gt;
                              &lt;/goals&gt;
                              &lt;configuration&gt;
                                  &lt;sources&gt;
                                      &lt;source&gt;src/it/java&lt;/source&gt;
                                  &lt;/sources&gt;
                              &lt;/configuration&gt;
                          &lt;/execution&gt;
                          &lt;!-- this execution adds the src/it/resources to test classpath --&gt;
                          &lt;execution&gt;
                              &lt;id&gt;add-integration-test-resource&lt;/id&gt;
                              &lt;phase&gt;generate-test-sources&lt;/phase&gt;
                              &lt;goals&gt;
                                  &lt;goal&gt;add-test-resource&lt;/goal&gt;
                              &lt;/goals&gt;
                              &lt;configuration&gt;
                                  &lt;resources&gt;
                                      &lt;resource&gt;
                                          &lt;directory&gt;src/it/resources&lt;/directory&gt;
                                      &lt;/resource&gt;
                                  &lt;/resources&gt;
                              &lt;/configuration&gt;
                          &lt;/execution&gt;
                      &lt;/executions&gt;
                  &lt;/plugin&gt;
                  &lt;!-- this runs the integration tests --&gt;
                  &lt;!-- NOTE: I have been considering using this for e2e tests once deployment 
                      is done to staging region. This would allow us to reuse code, with the only 
                      change being the base url system property passed in. However, we still have 
                      to deal with populating the region database, and the fact we want our integration 
                      tests to be much more extensive than our e2e tests, which should be very 
                      brief --&gt;
                  &lt;plugin&gt;
                      &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
                      &lt;artifactId&gt;maven-failsafe-plugin&lt;/artifactId&gt;
                      &lt;executions&gt;
                          &lt;execution&gt;
                              &lt;id&gt;integration-tests&lt;/id&gt;
                              &lt;goals&gt;
                                  &lt;goal&gt;integration-test&lt;/goal&gt;
                                  &lt;goal&gt;verify&lt;/goal&gt;
                              &lt;/goals&gt;
                              &lt;configuration&gt;
                              &lt;!-- this is needed so we can skip unit tests here, but not integration tests (as both default to skip tests property, which we set to true to ignore unit tests) --&gt;
                              &lt;skipTests&gt;false&lt;/skipTests&gt; &lt;!-- NOTE: In future here, could configure with ${skip.failsafe.tests} or any other variable but skip tests --&gt;
                                  &lt;!-- only run integration tests, which should end in IT --&gt;
                                  &lt;includes&gt;
                                      &lt;include&gt;**/*IT.java&lt;/include&gt;
                                  &lt;/includes&gt;
                                  &lt;excludes&gt;
                                      &lt;exclude&gt;**/*Test.java&lt;/exclude&gt;
                                  &lt;/excludes&gt;
                                  &lt;!-- set the environment variable from what is passed in as a system 
                                      variable. This allows use with spring boot property injection NOTE: there 
                                      is no need to set the jdbc related info here, this comes from test container --&gt;
                                  &lt;environmentVariables&gt;
                                      &lt;!-- set the base url; if not set defaults to localhost for int 
                                          testing --&gt;
                                      &lt;BASE_URL&gt;${BASE_URL}&lt;/BASE_URL&gt;
                                  &lt;/environmentVariables&gt;
                              &lt;/configuration&gt;
                          &lt;/execution&gt;
                      &lt;/executions&gt;
                  &lt;/plugin&gt;
  
                  &lt;!-- this plugin builds a pretty(ier) html report from the results of 
                      cucumber tests. This should only be active in this profile, after int tests 
                      have ran --&gt;
                  &lt;plugin&gt;
                      &lt;groupId&gt;net.masterthought&lt;/groupId&gt;
                      &lt;artifactId&gt;maven-cucumber-reporting&lt;/artifactId&gt;
                      &lt;version&gt;2.8.0&lt;/version&gt;
                      &lt;!-- we have one execution tag per functionality exposed by the api --&gt;
                      &lt;executions&gt;
                          &lt;!-- for the add integration tests --&gt;
                          &lt;execution&gt;
                              &lt;id&gt;addCucumberReport&lt;/id&gt;
                              &lt;phase&gt;verify&lt;/phase&gt;
                              &lt;goals&gt;
                                  &lt;goal&gt;generate&lt;/goal&gt;
                              &lt;/goals&gt;
                              &lt;configuration&gt;
                                  &lt;projectName&gt;CucumberWebGui&lt;/projectName&gt;
                                  &lt;outputDirectory&gt;${project.build.directory}/cucumber-report-html/add&lt;/outputDirectory&gt;
                                  &lt;cucumberOutput&gt;${project.build.directory}/cucumber-report/addCucumber.json&lt;/cucumberOutput&gt;
                              &lt;/configuration&gt;
                          &lt;/execution&gt;
                          &lt;!-- for get integration tests --&gt;
                          &lt;execution&gt;
                              &lt;id&gt;getCucumberReport&lt;/id&gt;
                              &lt;phase&gt;verify&lt;/phase&gt;
                              &lt;goals&gt;
                                  &lt;goal&gt;generate&lt;/goal&gt;
                              &lt;/goals&gt;
                              &lt;configuration&gt;
                                  &lt;projectName&gt;CucumberWebGui&lt;/projectName&gt;
                                  &lt;outputDirectory&gt;${project.build.directory}/cucumber-report-html/get&lt;/outputDirectory&gt;
                                  &lt;cucumberOutput&gt;${project.build.directory}/cucumber-report/getCucumber.json&lt;/cucumberOutput&gt;
                              &lt;/configuration&gt;
                          &lt;/execution&gt;
                          &lt;!-- for the verify/udpate reports --&gt;
                          &lt;execution&gt;
                              &lt;id&gt;updateCucumberReport&lt;/id&gt;
                              &lt;phase&gt;verify&lt;/phase&gt;
                              &lt;goals&gt;
                                  &lt;goal&gt;generate&lt;/goal&gt;
                              &lt;/goals&gt;
                              &lt;configuration&gt;
                                  &lt;projectName&gt;CucumberWebGui&lt;/projectName&gt;
                                  &lt;outputDirectory&gt;${project.build.directory}/cucumber-report-html/update&lt;/outputDirectory&gt;
                                  &lt;cucumberOutput&gt;${project.build.directory}/cucumber-report/verifyCucumber.json&lt;/cucumberOutput&gt;
                              &lt;/configuration&gt;
                          &lt;/execution&gt;
                      &lt;/executions&gt;
                  &lt;/plugin&gt;
              &lt;/plugins&gt;
          &lt;/build&gt;
      &lt;/profile&gt;
  &lt;/profiles&gt;
  
  
  &lt;!-- NOTE: this is the build tag. Every plugin specified here will always 
      run, regardless of if a profile is selected, or if there are multiple profiles 
      selected. --&gt;
  &lt;build&gt;
      &lt;plugins&gt;
          &lt;!-- This is the default spring boot plugin that wraps as jar and allows 
              running with embedded instance --&gt;
          &lt;plugin&gt;
              &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
              &lt;artifactId&gt;spring-boot-maven-plugin&lt;/artifactId&gt;
          &lt;/plugin&gt;
  
          &lt;plugin&gt;
              &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
              &lt;artifactId&gt;maven-dependency-plugin&lt;/artifactId&gt;
              &lt;executions&gt;
                  &lt;execution&gt;
                      &lt;id&gt;unpack&lt;/id&gt;
                      &lt;phase&gt;package&lt;/phase&gt;
                      &lt;goals&gt;
                          &lt;goal&gt;unpack&lt;/goal&gt;
                      &lt;/goals&gt;
                      &lt;configuration&gt;
                          &lt;artifactItems&gt;
                              &lt;artifactItem&gt;
                                  &lt;groupId&gt;${project.groupId}&lt;/groupId&gt;
                                  &lt;artifactId&gt;${project.artifactId}&lt;/artifactId&gt;
                                  &lt;version&gt;${project.version}&lt;/version&gt;
                              &lt;/artifactItem&gt;
                          &lt;/artifactItems&gt;
                      &lt;/configuration&gt;
                  &lt;/execution&gt;
              &lt;/executions&gt;
          &lt;/plugin&gt;
  
  
  
  
  
          &lt;!-- display active profile in compile phase --&gt;
          &lt;plugin&gt;
              &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
              &lt;artifactId&gt;maven-help-plugin&lt;/artifactId&gt;
              &lt;executions&gt;
                  &lt;execution&gt;
                      &lt;id&gt;show-profiles&lt;/id&gt;
                      &lt;phase&gt;compile&lt;/phase&gt;
                      &lt;goals&gt;
                          &lt;goal&gt;active-profiles&lt;/goal&gt;
                      &lt;/goals&gt;
                  &lt;/execution&gt;
              &lt;/executions&gt;
          &lt;/plugin&gt;
      &lt;/plugins&gt;
  &lt;/build&gt;
  </code></pre>
  
  <p></p>
  
  <p>The source code for this can be found at: <a href="https://gitlab.com/connorbutch/reading-comprehension-api" rel="nofollow noreferrer">https://gitlab.com/connorbutch/reading-comprehension-api</a></p>