EthicsComputerCourses
Join training +91 90532 10052

Agile Testing & BDD

Software Testing · Lesson 14 of 30 Intermediate 7 min read Updated

Most software teams today work in short cycles called sprints and release often. There is no long "testing phase" at the end; testing happens every day, by the whole team. Agile testing is the set of habits that makes this work, and behaviour-driven development (BDD) is a popular way to write requirements as examples that become automated tests.

In this lesson you will learn the tester's role in an agile team, the test pyramid and the agile testing quadrants, and how to write Gherkin scenarios and connect them to code.

Testing in an agile team

In agile, requirements arrive as user stories: short statements such as "As a shopper, I want free delivery on bigger orders, so that I save money when I buy more." Each story has acceptance criteria, the conditions it must meet to be accepted.

The tester's job changes from "checking at the end" to "helping build quality in from the start":

  • Refinement. Testers ask questions while stories are written: "What about exactly ₹499? What if the coupon brings the total below ₹499?"
  • Three amigos. A product owner, a developer and a tester discuss each story before coding: business, building and breaking viewpoints.
  • During the sprint. Testers test each story as soon as it is ready, pair with developers and automate regression checks.
  • Definition of done. The team agrees that a story is not done until its tests pass, its bugs are fixed and its automation is added.

This movement of testing towards the start of the work is called shift-left. Finding a gap in a story during refinement costs one conversation; finding it after release costs a hotfix.

The test pyramid

The test pyramid is a guide for balancing automated tests:

Text
    /\        UI / end-to-end: few, slow, realistic
   /  \
  /----\      Service / API / integration: some
 /      \
/--------\    Unit: many, fast, cheap

Most checks should be fast unit tests, a smaller number should test services and APIs, and only a few should drive the full user interface. A team that does the opposite, with hundreds of slow browser tests and few unit tests (sometimes called the "ice-cream cone"), gets slow, flaky pipelines.

The agile testing quadrants

The agile testing quadrants sort testing activities along two questions: does the test face the business or the technology, and does it guide development or critique the product?

Guides developmentCritiques the product
Business-facingQ2: story tests, examples, BDD scenarios, prototypesQ3: exploratory testing, usability testing, user acceptance testing
Technology-facingQ1: unit tests, component testsQ4: performance, load, security and other non-functional tests

The quadrants are not an order of work; a team uses all four in every release. They are a checklist that reminds you not to forget a whole kind of testing.

Behaviour-driven development

BDD grew out of test-driven development. The team describes each behaviour with concrete examples in a structured, plain-English language called Gherkin. The same text is a requirement the business can read, a test case a tester can follow, and an automated test a tool can run.

Gherkin
Feature: Delivery charge
  As a shopper in Pune
  I want free delivery on bigger orders
  So that I save money when I buy more

  Rule: Orders of 499 rupees or more get free delivery

    Scenario: Order above the limit
      Given my cart total is 520 rupees
      When I go to checkout
      Then the delivery charge is 0 rupees

    Scenario Outline: Orders around the limit
      Given my cart total is <total> rupees
      When I go to checkout
      Then the delivery charge is <charge> rupees

      Examples:
        | total | charge |
        | 498   | 40     |
        | 499   | 0      |

The keywords:

  • Feature: the capability, often with the user story underneath.
  • Rule: one business rule the scenarios illustrate.
  • Scenario: one concrete example.
  • Given: the starting situation. When: the action. Then: the expected outcome. And and But continue the previous kind of step.
  • Scenario Outline with Examples: the same steps run once per row, which is data-driven testing in Gherkin. Note how the examples use the boundary values 498 and 499.

How scenarios become tests

A BDD tool reads the feature file, matches each step's text against step definitions (small functions in code) and runs them in order. Here is the idea in a few lines of Python. The function under test has a boundary defect:

PythonRun it yourself
import re

feature = """
Scenario: Free delivery on bigger orders
  Given my cart total is 520 rupees
  When I go to checkout
  Then the delivery charge is 0 rupees

Scenario: Exactly 499 rupees is free
  Given my cart total is 499 rupees
  When I go to checkout
  Then the delivery charge is 0 rupees
"""

def delivery_charge(total):
    return 0 if total > 499 else 40   # defect: rule says 499 or more

STEPS = []

def step(pattern):
    def register(func):
        STEPS.append((re.compile(pattern), func))
        return func
    return register

@step(r"my cart total is (\d+) rupees")
def cart_total(ctx, amount):
    ctx["total"] = int(amount)

@step(r"I go to checkout")
def checkout(ctx):
    ctx["charge"] = delivery_charge(ctx["total"])

@step(r"the delivery charge is (\d+) rupees")
def check_charge(ctx, amount):
    assert ctx["charge"] == int(amount), f"got {ctx['charge']}"

def run(text):
    ctx = {}
    for line in text.strip().splitlines():
        line = line.strip()
        if not line:
            continue
        if line.startswith("Scenario:"):
            ctx = {}
            print(line)
            continue
        keyword, _, rest = line.partition(" ")
        for pattern, func in STEPS:
            match = pattern.fullmatch(rest)
            if match:
                try:
                    func(ctx, *match.groups())
                    print(f"  passed  {line}")
                except AssertionError as error:
                    print(f"  FAILED  {line} ({error})")
                break
        else:
            print(f"  UNDEFINED  {line}")

run(feature)
Output
Scenario: Free delivery on bigger orders
  passed  Given my cart total is 520 rupees
  passed  When I go to checkout
  passed  Then the delivery charge is 0 rupees
Scenario: Exactly 499 rupees is free
  passed  Given my cart total is 499 rupees
  passed  When I go to checkout
  FAILED  Then the delivery charge is 0 rupees (got 40)

The @step(...) lines are decorators: each one registers the function below it with a text pattern. The numbers captured by (\d+) are passed to the function. A step with no matching definition is reported as undefined, which is how real tools tell you which glue code is still missing.

Real tools: behave, pytest-bdd and Cucumber

In Python, behave (version 1.3 at the time of writing) and pytest-bdd are the common choices. In JavaScript and Java, Cucumber is the best known. With behave, the feature file goes in a features folder and step definitions in features/steps:

Python
# features/steps/delivery_steps.py
from behave import given, when, then


def delivery_charge(total):
    return 0 if total >= 499 else 40


@given("my cart total is {total:d} rupees")
def step_cart_total(context, total):
    context.total = total


@when("I go to checkout")
def step_checkout(context):
    context.charge = delivery_charge(context.total)


@then("the delivery charge is {charge:d} rupees")
def step_check_charge(context, charge):
    assert context.charge == charge, f"expected {charge}, got {context.charge}"

{total:d} captures a whole number, and context is an object behave shares between the steps of one scenario. Install with python -m pip install behave and run behave in the project folder. Each step is printed with the file and line of its definition, and the run ends with a summary like this:

Output
1 feature passed, 0 failed, 0 skipped
1 rule passed, 0 failed, 0 skipped
3 scenarios passed, 0 failed, 0 skipped
9 steps passed, 0 failed, 0 skipped

Common mistakes

  • Writing UI clicks in Gherkin. "When I click the button with id btn-23" describes the screen, not the behaviour. Write "When I go to checkout"; the step definition handles the clicks.
  • BDD without conversation. Feature files written alone by a tester after coding lose the main benefit: shared understanding before coding.
  • Huge scenarios. Keep each scenario to one behaviour, usually 3 to 7 steps.
  • An upside-down pyramid. Do not test calculations through the browser when a unit test can check them in milliseconds.

Key points

  • In agile teams testing happens continuously and testers help shape stories from the start (shift-left).
  • The test pyramid recommends many unit tests, fewer service tests and few UI tests.
  • The agile testing quadrants remind teams to cover business-facing and technology-facing tests that both guide and critique.
  • BDD describes behaviour with concrete Gherkin examples using Given, When and Then.
  • Step definitions connect each Gherkin step to code; behave, pytest-bdd and Cucumber run them.

Exercise

Write a Gherkin feature for this rule from a movie ticket app in Kochi: "Students get 20% off tickets on weekdays, but not on weekends." Include a Scenario Outline with an Examples table covering a student on a weekday, a student on a weekend and a non-student on a weekday, for a ₹250 ticket.

Show solution
Gherkin
Feature: Student discount
  As a student in Kochi
  I want cheaper tickets on weekdays
  So that I can watch more films

  Rule: Students get 20% off on weekdays only

    Scenario Outline: Ticket price by customer type and day
      Given a ticket costs 250 rupees
      And I am a <customer>
      When I book a ticket for <day>
      Then I pay <price> rupees

      Examples:
        | customer    | day      | price |
        | student     | Tuesday  | 200   |
        | student     | Saturday | 250   |
        | non-student | Tuesday  | 250   |

Each row is one example of the rule. The table makes it easy for the product owner to spot a missing case, such as a public holiday that falls on a weekday, and add a row before any code is written.

Quick Quiz

1. Which Gherkin keyword describes the action the user takes?

2. What does the test pyramid recommend?

3. Exploratory testing and user acceptance testing sit in which agile testing quadrant?

4. What connects a Gherkin step to code in behave?

Learn Software Testing with a mentor

Free lessons get you started. Our Software Testing training adds real projects and code reviews from working developers.

  • Project-based learning
  • Mentor code reviews
  • Free counselling call