EffectStep

An EffectStep can be understood as the following function ScenarioContext => IO[Either[CornichonError, Session]].

This means that an EffectStep runs a side effect and populates the Session with potential result values or returns an error.

A Session is a Map-like object used to propagate state throughout a scenario. It is used to resolve placeholders and save the result computations for later assertions.

Here is the simplest EffectStep possible:

When I EffectStep(title = "do nothing", effect = scenarioContext => IO.pure(Right(scenarioContext.session)))

or using a factory helper when dealing with computations that do not fit the EffectStep type.

When I EffectStep.fromSync(title = "do nothing", effect = scenarioContext => scenarioContext.session)
When I EffectStep.fromSyncE(title = "do nothing", effect = scenarioContext => Right(scenarioContext.session))

Let's try to save a value into the Session

When I EffectStep.fromSync(title = "estimate PI", effect = scenarioContext => scenarioContext.session.addValueUnsafe("result", piComputation()))

The test engine is responsible for controlling the execution of the side effect function and for reporting any error.

The EffectStep uses cats-effect IO under the hood. It is also possible to import the cats EffectStep explicitly:

import com.github.agourlay.cornichon.steps.cats.EffectStep

EffectStep using the HTTP service

Sometimes you want to perform HTTP calls inside an EffectStep, this is where the http service comes in handy.

In order to illustrate its usage let's take the following example, you would like to write a custom step like:

def feature = Feature("Customer endpoint") {

  Scenario("create customer") {

    When I create_customer

    Then assert status.is(201)

  }
}

Most of the time you will create your own trait containing your custom steps and declare a self-type on CornichonFeature to be able to access the http service.

It exposes a method requestEffectIO turning an HttpRequest into an asynchronous effect.

trait MySteps {
  this: CornichonFeature =>

  def create_customer = EffectStep(
    title = "create new customer",
    effect = http.requestEffectIO(
      request = HttpRequest.post("/customer").withBody("someJson"),
      expectedStatus = Some(201),
      extractor = RootExtractor("customer")
    )
  )
}

The built-in HTTP steps available on the DSL are actually built on top of the http service which means that you benefit from all the existing infrastructure to: