A BDD testing framework integrating Gherkin-style tests with ZIO’s effect system
This page delves into advanced capabilities of zio-bdd, including integrating ZIO services, managing complex state, using ScenarioContext effectively, and leveraging custom reporters. These features enable you to write sophisticated tests for complex applications.
zio-bdd seamlessly integrates with ZIO’s dependency injection system via ZLayer. This allows you to provide services to your step definitions, making your tests modular and easy to manage.
In your ZIOSteps subclass, override the environment method to provide the required services:
override def environment: ZLayer[Any, Any, Env] =
ZLayer.make[Env](
Service1.live,
Service2.live
)
Service1 with Service2).Access services in your step definitions using ZIO.service:
When("some action is performed") {
for {
service <- ZIO.service[Service1]
result <- service.doSomething()
// ...
} yield ()
}
This approach keeps your tests clean and decoupled from service implementations.
For tests requiring intricate state management, ScenarioContext can hold complex data structures. Define a case class to represent your state and provide an implicit Schema for serialization.
case class ComplexState(users: Map[String, User], currentUser: Option[String])
implicit val schema: Schema[ComplexState] = DeriveSchema.gen[ComplexState]
Given("a user named " / string) { (name: String) =>
for {
state <- ScenarioContext.get
updatedUsers = state.users + (name -> User(name))
_ <- ScenarioContext.update(_.copy(users = updatedUsers))
} yield ()
}
ScenarioContext.update to modify the state immutably.While zio-bdd provides built-in reporters, you can create custom reporters for specialized output formats.
Extend the Reporter trait:
class CustomReporter extends Reporter {
override def report(results: List[FeatureResult]): ZIO[Any, Nothing, Unit] = {
// Custom reporting logic
ZIO.succeed(())
}
}
@Suite annotation:@Suite(reporters = Array("custom"))
object MySpec extends ZIOSteps[Env, State] {
// ...
}
"custom" to your CustomReporter instance in the test framework configuration.zio-bdd fully supports Gherkin’s Scenario Outline and Examples for data-driven testing.
Write step definitions as usual, using extractors for placeholders:
Given("a user named " / string) { (name: String) =>
// ...
}
zio-bdd automatically handles the expansion of outlines into multiple scenarios.Gherkin’s Background section runs before each scenario in a feature. Define steps for background as you would for any other step.
In your feature file:
Feature: User Management
Background:
Given a system is running
Scenario: Create user
When a user is created
Then the user exists
Define the background step:
Given("a system is running") {
// Setup system
}
TypedExtractor.zio-bdd by checking the Contribution Guide.