This is an example Cucumber-JVM project.
- Uses Kotlin step definitions
- Packages tests into executable jar file
- Uses Guice dependency injection
The feature file (Example.feature
):
Feature: Example feature
@ExampleFeature
Scenario: Example scenario
Given this pre condition
And this pre condition
When I do this
And I do that
Then I can verify that
And I can also verify that
The step definitions (ExampleSteps.kt
). This contains the implementation of the steps.
class ExampleSteps @Inject constructor(private val testContext: TestContext) : En {
private val log = LoggerFactory.getLogger(ExampleSteps::class.java)
init {
configureSteps()
}
private fun configureSteps() {
Before { scenario: Scenario -> log.info("Before scenario : " + scenario.name) }
After { scenario: Scenario -> log.info("After scenario : " + scenario.name) }
Given("^this pre condition$") { testContext.put("some-key", "some-value") }
When("^I do this$") { }
When("^I do that$") { }
Then("^I can verify that$") { assert(testContext["some-key"] == "some-value") }
Then("^I can also verify that$") {
}
}
}
The Injector source used to create the injector (i.e a Guice dependency injection context in this example)
class ExampleInjectorSource : InjectorSource {
override fun getInjector(): Injector {
return Guice.createInjector(Stage.PRODUCTION, CucumberModules.createScenarioModule(), ExampleTestModule())
}
}
The Guice module used to bind dependencies injected in the step definitions
internal class ExampleTestModule : AbstractModule() {
override fun configure() {
bind(TestContext::class.java)
}
}
The TestContext. A simple key-value pair storage injected in the steps.
class TestContext {
private val context: ThreadLocal<MutableMap<String, Any>> = ThreadLocal.withInitial { mutableMapOf<String, Any>() }
fun put(key: String, value: Any) {
context.get()[key] = value
}
operator fun get(key: String): Any? {
return context.get()[key]
}
}
A JUnit based test runner. This can be called from the IDE or using Maven exec plugin.
@RunWith(Cucumber::class)
@CucumberOptions(features = ["classpath:features/Example.feature"],
tags = "not @Wip", glue = ["classpath:steps"], plugin = ["pretty", "html:target/cucumber/html"])
class ExampleFeatureTest
Using executable jar file:
mvn clean package
java -jar target/cucumber-jvm-kotlin-example.jar --plugin pretty --plugin html:cucumber/html --plugin json:cucumber/json/cucumber.json --glue steps classpath:features --tags ~@Wip
Using Maven exec plugin:
mvn exec:java -Dcucumber.options="--plugin pretty --plugin html:cucumber/html --plugin json:cucumber/json/cucumber.json --glue steps classpath:features --tags ~@Wip --tags @ExampleFeature"
Using JUnit test runner:
mvn test -Dtest=ExampleFeatureTest
Using Docker:
Dockerfile
FROM jecklgamis/openjdk-8-jre:latest
MAINTAINER Jerrico Gamis <jecklgamis@gmail.com>
RUN mkdir -m 0755 -p /cucumber-jvm-kotlin-example
COPY target/cucumber-jvm-kotlin-example.jar /cucumber-jvm-kotlin-example
COPY docker-entrypoint.sh /cucumber-jvm-kotlin-example
CMD ["/cucumber-jvm-kotlin-example/docker-entrypoint.sh"]
Build Docker image (see build-docker-image.sh
)
IMAGE_NAME=jecklgamis/cucumber-jvm-kotlin-example
IMAGE_TAG=latest
docker build -t ${IMAGE_NAME}:${IMAGE_TAG} .
Run Docker image (see run-all-tests-using-docker.sh
)
IMAGE_NAME=jecklgamis/cucumber-jvm-kotlin-example
IMAGE_TAG=latest
JAVA_OPTS=${JAVA_OPTS:-""}
ARGS=${ARGS:-"--plugin pretty --plugin html:cucumber/html --plugin json:cucumber/json/cucumber.json --glue steps classpath:features --tags @ExampleFeature"}
docker run -e "JAVA_OPTS=${JAVA_OPTS}" -e "ARGS=${ARGS}" ${IMAGE_NAME}:${IMAGE_TAG}
In Intellij, you can also run the scenario directly from the feature file. Ensure you have the Cucumber Java plugin installed.