Search code examples
javaspring-bootconfigurationcucumber

Unable to read the application.yml from cucumber test


I have a cucumber test :

@RunWith(CucumberWithSerenity.class)
@UsePersistantStepLibraries
@CucumberOptions(
        features = "src/integrationTest/resources/features/",
        glue = {"com/myorg/proj/integrationtest/stepdefinitions"},
        plugin = {"pretty", "summary"}
)
public class integrationTestRunner extends ParentClassWithAllMethods {


}

This is test is not defined inside the test folder , but as a seprate folder (as source set, and some one else had created this structure).

The gradle configuration for the sourceset (where the test is ) is as below:

sourceSets {
    integrationTest {
        java {
            compileClasspath += main.output + test.output
            runtimeClasspath += main.output + test.output
            srcDir file('src/integrationTest/java')
        }
        resources.srcDir file('src/integrationTest/resources')
    }
}

// Dependencies for integrationTest
dependencies {
    integrationTestCompileOnly 'org.projectlombok:lombok:1.18.12'
    integrationTestAnnotationProcessor 'org.projectlombok:lombok:1.18.12'
    integrationTestCompile group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.4.2'
    integrationTestImplementation 'net.serenity-bdd:serenity-core:2.2.13'
    integrationTestImplementation 'net.serenity-bdd:serenity-cucumber5:2.2.5'
    integrationTestImplementation 'net.serenity-bdd:serenity-rest-assured:2.2.13'
    integrationTestImplementation 'org.assertj:assertj-core:3.8.0'
    integrationTestImplementation 'org.slf4j:slf4j-simple:1.7.7'

}

task integrationTest(type: Test) {
    doFirst {
        systemProperty 'param1', 
        System.getProperty('param1')
        param1 = System.getProperty('param1')
        if (param1 == null)
          throw new GradleException("Parameter not passed ./gradlew -DParam<VALUE> ")
    }
    testClassesDirs = sourceSets.integrationTest.output.classesDirs
    classpath = sourceSets.integrationTest.runtimeClasspath
    outputs.upToDateWhen { false }
    finalizedBy aggregate
}

Looking at the gradle file, there 3 things going on ,

  1. There is a source set defined as integrationTest
  2. The compileCLassPath , runTimeClassPath, srcDir has been defined for the same
  3. Even the resources.srcDir is also being set (where I have application ymls)

I have create application.yml, application-integrationTest.yml inside the resources folder, but still unable to read any proporties using @Value.

Ex:

public class ParentClassWithAllMethods {

  @Value("${custom.parameter}")
  private String customParameter;

  public ResponseOptions<Response> getMethod() {

        String debugVal = customParameter;
  }
.....
}

When , running the test, I was expecting to get the value defined in my yml file, but its null.

YML file looks like this,

custom: parameter: https://something.com

Why am I not able to read the application configuration? It's always null !!


Solution

  • Your test class is not starting Spring, that is why you get null. Have a look here https://www.baeldung.com/cucumber-spring-integration, it shows how to connect Spring and Cucumber in JUnit tests.

    The test class would then have annotations for Spring and Cucumber like this:

    @CucumberContextConfiguration
    @SpringBootTest
    public class SpringIntegrationTest {
       // executeGet implementation
    }