liveBook · Manning

Blended testing

As explained in BDD in Action, Second Edition

Blended testing is a testing approach that combines interchangeable implementations of actor-facing tasks across different levels of abstraction.

Blended testing combines interchangeable task implementations across abstraction levels, allowing one scenario to use the interface best suited to each step. In an acceptance test, the web UI can demonstrate a user-facing workflow while an HTTP API prepares data or performs an equivalent operation faster. section 15.1.4 section 15.1.5

Use blended testing when:

  • A task has multiple ways to achieve the same goal, group the alternatives under one goal-oriented task and name each implementation by its route. section 15.1.4
  • A scenario needs registered data but does not test registration itself, create the account through an API rather than repeating the registration UI. section 15.1.5
  • A step must demonstrate user behavior, retain the UI implementation; use a faster backend implementation for setup or equivalent behavior that the scenario does not inspect. section 15.1.5

Registering a traveler

A UI-focused scenario can state “Given Tracy has signed up” and implement that setup with SignUp.viaApiUsing, posting traveler details to the registration endpoint and checking for status 201. A scenario that verifies registration itself can state “When Tracy signs up” and use the form-based SignUp.using task. section 15.1.5

Listing 15.5 Implementing variations of a task interacting with different interfaces
import { Answerable, QuestionAdapter, Task } from '@serenity-js/core'
import { Send, PostRequest } from '@serenity-js/rest'
import { Ensure, equals } from '@serenity-js/assertions'
 
class SignUp {
  using =(travelerDetails: QuestionAdapter<TravelerDetails>) =>
    Task.where(`#actor signs up`,
      LocateRegistrationForm(),
      FillOutRegistrationForm.using(travelerDetails),
      SubmitRegistrationForm(),
    )
 
  viaApiUsing = (travelerDetails: QuestionAdapter<TravelerDetails>) =>
    Task.where(`#actor signs up (via API)`,
      Send.a(PostRequest.to('/api/auth/register')
          .with(travelerDetails)),
      Ensure.that(LastResponse.status(), equals(201)),
    )
}

Compare the UI and API implementations of the same SignUp task, including form navigation, REST submission, and response verification. section 15.1.5

How BDD in Action, Second Edition covers it

How deep it goes
Explains task substitution, interface selection, naming conventions, step wording, and Serenity/JS implementations, stopping short of broader performance analysis.
Examples
Demonstrates registration through a form or API, direct versus home-page navigation, and API-created traveler accounts for UI scenarios.
What it assumes
Assumes automated acceptance-testing concepts and external system interfaces while teaching task substitution and cross-interface workflow design.
What you can do after
Apply it via Serenity/JS by defining interchangeable tasks that use web interactions for user behavior and REST calls for efficient setup.
How it connects
Connects task substitution, acceptance testing, web UI automation, REST APIs, GraphQL APIs, and the Screenplay Pattern.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of BDD in Action, Second Edition. The section links point to the parts of the book it draws on.