Skip to content

Implementing Steps

CraigRice edited this page Aug 22, 2023 · 6 revisions

Implementing Steps

Step methods are Given, When, Then, And, But.

Each step has a title to describe it and a function that will be run.

.Given("the value five", () =>
{
    return 5;
})

A step function:

  • Can return anything to the next step. This includes anonymous types, tuples and other functions.
  • Can be an Action with no return value.
  • Runs immediately.
  • Is skipped and never run if its previous step failed or was inconclusive.
  • Fails when its function throws an exception.
  • Is inconclusive / skipped when its function throws an inconclusive exception (usually via Assert.Inconclusive).

Pipe<T>

The current state and progress of the run steps is represented by the step return value: Pipe<T>.

The above example of the Given step function returning the int 5 means the step returns a Pipe<int>.

Each time something is returned from a step Pipe<T> will take on this new type. If nothing is returned from a step because it is an Action (or Func returning Task), it will still remain of the same type.

Actions can be used after a step without altering the type:

.Given("the user name and password", () => new { UserName = "user", Password = "pass" })
.And("the user is created", userDetails =>
{
    // this action does not return anything new
    UserData.CreateUser(userDetails);
})
.When("...", userDetails => /* the step is still of the user details type */

Below the 'Then' and 'And' steps use the response instance in assert actions and don't introduce anything new:

.When("GetResponse() is called", setup => setup.GetResponse())
.Then("the response was not null", response =>
{
    Assert.NotNull(response);
})
.And("the response was successful", response =>
{
    Assert.IsTrue(response.Successful);
})

A list of step functions available:

Step Function Signatures

For Given:

Func<Unit, R>
Func<Unit, Task<R>>
Func<R>
Func<Task<R>>
Func<Unit, Task>
Func<Task>
Action<Unit>
Action

Unit is the initial empty starting value. The functions with Unit are provided to be consistent with overloads of the other steps.

For When, Then, And, But:

Func<T, R>
Func<T, Task<R>>
Func<R>
Func<Task<R>>
Func<T, Task>
Func<Task>
Action<T>
Action