liveBook · Manning

Reuse

As explained in BDD in Action, Second Edition

Code reuse is the practice of applying existing software code in multiple contexts instead of duplicating its implementation.

Code reuse applies existing automation logic in multiple business flows instead of repeating low-level interactions. Reusable tasks can combine navigation, form entry, and other tasks into readable, composable operations. section 12.9.2

Effective reuse in test automation follows several practical patterns:

  • Hide repeated navigation behind a task such as toTheLoginPage(), so tests express intent rather than page mechanics. section 12.9.2
  • Combine navigation, credential entry, and submission into a Login.usingCredentials() task that higher-level tests can call directly. section 12.9.2
  • Separate default test data from scenario-specific overrides, keeping feature files readable while supporting negative cases. section 15.1.6
  • Use dynamic task arguments when actor-specific data comes from a notepad, and merge partial overrides only where a scenario requires them. section 15.1.6

Reusable sign-up flow

A SignUp task can accept traveler details and reuse the same registration sequence across scenarios. A normal scenario uses generated actor data, while a duplicate-email scenario overrides only the email with smiths@example.org, preserving the shared flow and making the business rule prominent. section 15.1.6

public class Login {
    public static Performable usingCredentials(String username, 
                                               String password) {
      return Task.where("{0} logs in as " + username,
                Navigate.toTheLoginPage(),
                SendKeys.of(username).into("#email"),
                SendKeys.of(password).into("#password"),
                Click.on("#login-button")
      );
    }
  }

Shows a reusable login task composed from navigation, credential entry, and button interaction. section 12.9.2

import { Actor, Question } from '@serenity-js/core'
import { When, DataTable } from '@cucumber/cucumber'
 
When('{actor} tries to sign up using:', (actor: Actor, data: DataTable) =>
    actor.attemptsTo(
        SignUp.using(
            Question.fromObject<TravelerDetails>(
                notes<TravelerNotes>().get('travelerDetails'),
                data.rowsHash() as Partial<TravelerDetails>,
            )
        )
    ));

Shows how a scenario-specific partial data set can be merged with an actor's default traveler details. section 15.1.6

How BDD in Action, Second Edition covers it

How deep it goes
Explains task composition, actor data injection, asynchronous adapters, and partial overrides, stopping short of general software architecture.
Examples
Demonstrates reusable login and navigation tasks alongside sign-up scenarios using generated traveler details and duplicate-email overrides.
What it assumes
Assumes familiarity with actors, tasks, interactions, Cucumber steps, and basic static data before introducing dynamic task arguments.
What you can do after
Apply reuse via Screenplay tasks and Serenity/JS data abstractions to build shorter, clearer, and more maintainable test scenarios.
How it connects
Connects reusable tasks with Screenplay Pattern, actors, interactions, Cucumber scenarios, test data, and business flows.

Also explained in

Compare how 6 books explain reuse →

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.