Home > database >  Cucumber SpringBoot: Retreive application.properties variables and run project via gradle cucumberCl
Cucumber SpringBoot: Retreive application.properties variables and run project via gradle cucumberCl

Time:04-28

I have been trying to solve this issue whole day, but was not able to do. So let describe it: My intent: In SpringBoot application, in src/resources/application.properties, I have defined two variables:

myDefaultBrowser=https://www.https://www.mozilla.org/en-US/
mySecondBrowser=https://www.google.com/chrome/

There is an option to use third variable, but that variable to be obtained from environment.

What I did:

Created gradle springboot project. Here is structure: ProjectStructure

I some youtube videos, and googling comes to create structure like that.

Feature files are: Chrome and Firefox

Showing firefox.feature

Feature: Test to see appproperties variable

  Scenario: Get and show firefox browser
    When firefox variable is stored into appprop show it

Step definition for firefox:(similar is for chrome)

public class FirefoxSD {

    @Autowired
    RunConfiguration runConfiguration;

    String fireFoxURI;

    @Before
    public void setUp() {
        this.fireFoxURI = runConfiguration.getDefaultBrowser();
    }

    @When("firefox variable is stored into appprop show it")
    public void showFirefoxURI() {
        baseURI = fireFoxURI;
        System.out.println("***************************************************************");
        System.out.println("This is firefox URI from application properties: "   baseURI);
        System.out.println("***************************************************************");
    }
}

Then I created runner class, firefox:

@RunWith(Cucumber.class)
@CucumberOptions(
        features = "src/test/resources/featureFiles/firefoxFF",
        glue ={"com/cucumbertest/cucumber/stepDefinitions/firefoxSD","com/cucumbertest/cucumber/cucumberConfig"},
        plugin = { "com.aventstack.extentreports.cucumber.adapter.ExtentCucumberAdapter:"},
        dryRun = false
)

public class FireFoxRunnerTest {
}

Crated three more classes: ConfigLoad:

@Component
@PropertySource({"classpath:application.properties"})
public class ConfigLoad {
}

RunConfigurations:

@Component
public class RunConfiguration {

    @Value("${myDefaultBrowser}")
    private String defaultBrowser;

    @Value("${mySecondBrowser}")
    private String secondBrowser;

    public RunConfiguration() {
    }

    public String getDefaultBrowser() {
        return defaultBrowser;
    }

    public void setDefaultBrowser(String defaultBrowser) {
        this.defaultBrowser = defaultBrowser;
    }

    public String getSecondBrowser() {
        return secondBrowser;
    }

    public void setSecondBrowser(String secondBrowser) {
        this.secondBrowser = secondBrowser;
    }
}

CucumberConfiguration:

CucumberContextConfiguration
@SpringBootTest(classes = CucumberApplication.class)
public class CucumberConfig {

}

build.gradle:

import org.gradle.api.tasks.testing.logging.TestLogEvent

plugins {
    id 'org.springframework.boot' version '2.6.7'
    id 'io.spring.dependency-management' version '1.0.11.RELEASE'
    id 'java'
}

group = 'com.cucumbertest'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '17'

repositories {
    mavenCentral()
}

configurations {
    compileOnly {
        extendsFrom annotationProcessor
    }
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'

    testImplementation group: 'org.hamcrest', name: 'hamcrest-all', version: '1.3'
    testImplementation group: 'io.rest-assured', name: 'rest-assured', version: '4.5.1'
    implementation group: 'io.cucumber', name: 'cucumber-java', version: '7.2.3'
    testImplementation group: 'io.cucumber', name: 'cucumber-junit', version: '7.2.3'
    implementation group: 'io.cucumber', name: 'cucumber-spring', version: '7.2.3'


    testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.8.2'
    testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: '5.8.2'
    testImplementation group: 'org.junit.vintage', name: 'junit-vintage-engine', version: '5.8.2'

    implementation group: 'tech.grasshopper', name: 'extentreports-cucumber7-adapter', version: '1.3.0'
    implementation group: 'io.rest-assured', name: 'xml-path', version: '4.5.1'
    implementation group: 'io.rest-assured', name: 'json-path', version: '4.5.1'
}

// cucumber

configurations {
    cucumberRuntime {
        extendsFrom testImplementation
    }
}

task cucumberCli() {
    dependsOn assemble, testClasses
    doLast {
        javaexec {
            main = "io.cucumber.core.cli.Main"
            classpath = configurations.cucumberRuntime   sourceSets.main.output   sourceSets.test.output
            args = [
                    '--plugin', 'pretty',
                    '--plugin', 'com.aventstack.extentreports.cucumber.adapter.ExtentCucumberAdapter:',
                    '--glue', 'com/digitalautomationsolution/dascucumber/stepDefinitions',
                    'src/test/resources/featureFiles'
            ]
        }
    }
}

test {
    useJUnitPlatform()

    testLogging {
        events TestLogEvent.FAILED, TestLogEvent.PASSED, TestLogEvent.SKIPPED
    }

    systemProperties(project.gradle.startParameter.systemPropertiesArgs)
}

When I run ChromeRunnerTest and FirefoxRunnerTest, first one then other, test are run just fine, but when I run tests via gradle with: gradle cucumberCli I am receiving this error:

SEVERE: Exception while executing pickle
java.util.concurrent.ExecutionException: io.cucumber.core.backend.CucumberBackendException: Please annotate a glue class with some context configuration.

For example:

   @CucumberContextConfiguration
   @SpringBootTest(classes = TestConfig.class)
   public class CucumberSpringConfiguration { }
Or: 

   @CucumberContextConfiguration
   @ContextConfiguration( ... )
   public class CucumberSpringConfiguration { }
    at java.base/java.util.concurrent.FutureTask.report(FutureTask.java:122)
    at java.base/java.util.concurrent.FutureTask.get(FutureTask.java:191)
    at io.cucumber.core.runtime.Runtime.runFeatures(Runtime.java:117)
    at io.cucumber.core.runtime.Runtime.lambda$run$0(Runtime.java:82)
    at io.cucumber.core.runtime.Runtime.execute(Runtime.java:94)
    at io.cucumber.core.runtime.Runtime.run(Runtime.java:80)
    at io.cucumber.core.cli.Main.run(Main.java:87)
    at io.cucumber.core.cli.Main.main(Main.java:30)
Caused by: io.cucumber.core.backend.CucumberBackendException: Please annotate a glue class with some context configuration.

I have tried to annotate classes with @SpringBootTest (stepDef classes also) but receiving this error.

Here is code on git: Github code

What I am doing wrong or what I have missed in my implementation?

Best regards, Jovan.

CodePudding user response:

Cucumber uses the @CucumberContextConfiguration annotated class to determine which class to use to configure the spring application context.

This class must be on the glue path.

In FireFoxRunnerTest you have two such paths:

glue ={
  "com/cucumbertest/cucumber/stepDefinitions/firefoxSD",
  "com/cucumbertest/cucumber/cucumberConfig"
},

However in the task cucumberCLI you run Cucumber with a single glue argument:

'--glue', 'com/digitalautomationsolution/dascucumber/stepDefinitions',

Look carefully at the differences.

CodePudding user response:

Solution for others: In my firefox runner (and chrome runner) I have these lines:

    @RunWith(Cucumber.class)
    @CucumberOptions(
            features = "src/test/resources/featureFiles/firefoxFF",
            glue ={"com/cucumbertest/cucumber/stepDefinitions/firefoxSD","com/cucumbertest/cucumber/cucumberConfig"},
            plugin = { "com.aventstack.extentreports.cucumber.adapter.ExtentCucumberAdapter:"},
            dryRun = false
    )
    
    public class FireFoxRunnerTest {
}

In glue part I'm pointing where my firefoxSD (firefox step definition class is (also same for chrome)). I also added path to class where I have annotations:

@CucumberContextConfiguration
@SpringBootTest

quote M.P. Korsanje

Cucumber uses the @CucumberContextConfiguration annotated class to determine which class to use to configure the spring application context.

In gradle build I have added just one glue path:

'--glue', 'com/cucumbertest/cucumber/stepDefinitions'

but missed to add another line:

'--glue', 'com/cucumbertest/cucumber/cucumberConfig'

In this way, gradle was not able to find all required thing to run my app (tests). When I have added this second line in grade, test worked out. Working code is on the Github.

Best regards, Jovan

  • Related