Tutorial 6: Setup Table

Goal

Use setup tables to simplify test setup.

Write the Feature Test

# file:features/tutorial06_step_setup_table.feature
Feature: Step Setup Table (tutorial06)

   Scenario: Setup Table
     Given a set of specific users:
        | name      | department  |
        | Barry     | Beer Cans   |
        | Pudey     | Silly Walks |
        | Two-Lumps | Silly Walks |
    When we count the number of people in each department
    Then we will find two people in "Silly Walks"
     But we will find one person in "Beer Cans"

Provide the Test Automation

# file:features/steps/step_tutorial06.py
# ----------------------------------------------------------------------------
# STEPS:
# ----------------------------------------------------------------------------
from behave   import given, when, then
from hamcrest import assert_that, equal_to
from testutil import NamedNumber
from company_model import CompanyModel

@given('a set of specific users')
def step_impl(context):
    model = getattr(context, "model", None)
    if not model:
        context.model = CompanyModel()
    for row in context.table:
        context.model.add_user(row["name"], deparment=row["department"])

@when('we count the number of people in each department')
def step_impl(context):
    context.model.count_persons_per_department()

@then('we will find {count} people in "{department}"')
def step_impl(context, count, department):
    count_ = NamedNumber.from_string(count)
    assert_that(count_, equal_to(context.model.get_headcount_for(department)))

@then('we will find one person in "{department}"')
def step_impl(context, department):
    assert_that(1, equal_to(context.model.get_headcount_for(department)))
# file:features/steps/testutil.py
# ----------------------------------------------------------------------------
# TEST SUPPORT:
# ----------------------------------------------------------------------------
class NamedNumber(object):
    """Map named numbers into numbers."""
    MAP = {
        "one": 1,
        "two": 2,
        "three": 3,
        "four":  4,
        "five":  5,
        "six":   6,
    }

    @classmethod
    def from_string(cls, named_number):
        name = named_number.strip().lower()
        return cls.MAP[name]

Provide the Domain Model

# file:features/steps/company_model.py
# -----------------------------------------------------------------------------
# DOMAIN-MODEL:
# -----------------------------------------------------------------------------
class Department(object):
    def __init__(self, name, members=None):
        if not members:
            members = []
        self.name = name
        self.members = members

    def add_member(self, name):
        assert name not in self.members
        self.members.append(name)

    @property
    def count(self):
        return len(self.members)

    def __len__(self):
        return self.count

class CompanyModel(object):
    def __init__(self):
        self.users = []
        self.departments = {}

    def add_user(self, name, deparment):
        assert name not in self.users
        if deparment not in self.departments:
            self.departments[deparment] = Department(deparment)
        self.departments[deparment].add_member(name)

    def count_persons_per_department(self):
        pass

    def get_headcount_for(self, department):
        return self.departments[department].count

Run the Feature Test

When you run the feature file from above:

$ behave ../features/tutorial06_step_setup_table.feature
Feature: Step Setup Table (tutorial06)   # ../features/tutorial06_step_setup_table.feature:1

  Scenario: Setup Table                                   # ../features/tutorial06_step_setup_table.feature:3
    Given a set of specific users                         # ../features/steps/step_tutorial06.py:28
      | name      | department  |
      | Barry     | Beer Cans   |
      | Pudey     | Silly Walks |
      | Two-Lumps | Silly Walks |
    When we count the number of people in each department # ../features/steps/step_tutorial06.py:36
    Then we will find two people in "Silly Walks"         # ../features/steps/step_tutorial06.py:40
    But we will find one person in "Beer Cans"            # ../features/steps/step_tutorial06.py:45

1 feature passed, 0 failed, 0 skipped
1 scenario passed, 0 failed, 0 skipped
4 steps passed, 0 failed, 0 skipped, 0 undefined
Took 0m0.000s