Sam Pegler
Tech Leadership
Worked at BritX1 and Ki2 prior to moving back to Brit, experience in Python and SRE.
Here to talk about Behvaiour Driven Development (BDD) and how it can help us.
What is TDD?
How does BDD3 differ from TDD?
So what is the BDD core loop?
BDD is about building the right thing, not really about how it’s built.
Does that mean you don’t have to use TDD?
What do behavioural tests look like?
Feature: Google Searching
Scenario: Search from the search bar
Given a web browser is at the Google home page
When the user enters "panda" into the search bar
Then links related to "panda" are shown on the results page
Expanding behaviours should be done by adding more scenarios, not increasing the footprint of the test.
Feature: Google Searching
Scenario: Search from the search bar
Given a web browser is at the Google home page
When the user enters "panda" into the search bar
Then links related to "panda" are shown on the results page
Scenario: Image search
Given Google search results for "panda" are shown
When the user clicks on the "Images" link at the top of the results page
Then images related to "panda" are shown on the results page
BDD aligns development and product with a contract, the feature file.
Behavioural scenarios can be shared with not just product, but almost any stakeholder.
What toolchain is best to use in Python?
behave
or pytest-bdd
behave is full behavioural testing framework AND runner.
Feature: Showing off behave
Scenario: Run a simple test
Given we have behave installed
When we implement 5 tests
Then behave will test them for us!
from behave import given, when, then, step
@given('we have behave installed')
def step_impl(context):
pass
@when('we implement {number:d} tests')
def step_impl(context, number):
assert number > 1 or number == 0
context.tests_count = number
@then('behave will test them for us!')
def step_impl(context):
assert context.failed is False
assert context.tests_count >= 0
% behave
Feature: Showing off behave
Scenario: Run a simple test
Given we have behave installed
When we implement 5 tests
Then behave will test them for us!
1 feature passed, 0 failed, 0 skipped
1 scenario passed, 0 failed, 0 skipped
3 steps passed, 0 failed, 0 skipped, 0 undefined
Reporting tools can ingest the json reporting into azure pipelines.
pytest-bdd is a plugin for pytest that includes fixtures for running behavioural tests
Feature: Showing off pytest-bdd
Scenario: Run a simple test
Given we have pytest-bdd installed
When we implement 5 tests
Then pytest will test them for us!
from pytest_bdd import scenarios, parsers, given, when, then
scenarios("pytest-bdd.scenario")
@given('we have pytest-bdd installed')
def pytest_bdd_is_installed():
pass
@when(
parsers.parse("we implement {number:d} tests"), target_fixture="number_of_tests"
)
def number_of_tests(number: int):
assert number > 1 or number == 0
return number
@then('pytest-bdd will test them for us!')
def step_impl(number_of_tests: int):
assert number_of_tests >= 0
% poetry run pytest -vv --gherkin-terminal-reporter tests
========================================== test session starts ==========================================
platform darwin -- Python 3.13.0, pytest-8.3.3, pluggy-1.5.0 -- /Users/sampegler/Library/Caches/pypoetry/virtualenvs/test-8DRKBHXr-py3.13/bin/python
cachedir: .pytest_cache
rootdir: /private/tmp/test
configfile: pyproject.toml
plugins: bdd-7.3.0
collected 1 item
tests/test_bdd.py::test_run_a_simple_test <- ../../../Users/sampegler/Library/Caches/pypoetry/virtualenvs/test-8DRKBHXr-py3.13/lib/python3.13/site-packages/pytest_bdd/scenario.py
Feature: Showing off pytest-bdd
Scenario: Run a simple test
Given we have pytest-bdd installed
When we implement 5 tests
Then pytest-bdd will test them for us!
PASSED
=========================================== 1 passed in 0.00s ===========================================
The same reporting tools used for behave can also be used here.
Marks can be placed directly in scenario files and then picked up by pytest.
@bdd
Feature: Google Searching
@search
Scenario: Search from the search bar
Given a web browser is at the Google home page
When the user enters "panda" into the search bar
Then links related to "panda" are shown on the results page
@search @images
Scenario: Image search
Given Google search results for "panda" are shown
When the user clicks on the "Images" link at the top of the results page
Then images related to "panda" are shown on the results page
pytest -m 'bdd and images'
would only run the second scenario.
When it comes to making a choice pytest-bdd
has already been used in Brit so is heavily recommended.
Feature: Scenario outlines
Scenario Outline: Outlined given, when, then
Given there are <start> cucumbers
When I eat <eat> cucumbers
Then I should have <left> cucumbers
Examples:
| start | eat | left |
| 12 | 5 | 7 |
| 2 | 2 | 0 |
Like pytest.mark.parametrize
in pytest, we can paramaterise with pytest-bdd. The Scenario Outline
keyword explains to the parser that this scenario is to be run multiple times with the example data.
Scenario: Correct non-zero number of books found by author
Given I have the following books in the store
| title | author |
| The Devil in the White City | Erik Larson |
| The Lion, the Witch and the Wardrobe | C.S. Lewis |
| In the Garden of Beasts | Erik Larson |
When I search for books by author Erik Larson
Then I find 2 books
Data tables4 are passed inserted into a pytest fixture named datatable
and can be accessed as any other fixture. This could be then used in a @given
decorated step to pre-populate the DB.
When to use BDD?
When not to use BDD?
Scenario: Ki Cargo only Brit new business policy 100% in the EU
Given a completed PBQA
And the syndicate '1618' is on risk
And the number of references is '1'
And the 'policy_reference' field is 'GP705S21A000'
And the 'journey' field is 'BRIT_NEW_BUSINESS'
And the 'class_of_business' field is 'CARGO'
And the 'eea' field is '100'
When I generate a reference
Then it should complete successfully
And the number of references should be '1'
And the references for syndicate '1618' should be ['GP705S21A000']
Follow on tutorials
Worked on a tool called Otto which was used in Binding and Endorsements for Ki. Some of this work ended up as the Sovreign project at Brit. ↩︎
Worked on portfolio management and observability & monitoring. ↩︎
Specification by example is a good book on BDD. ↩︎
You’ll want to use the latest pre release version of pytest-bdd for this, it should land on main in the next couple of weeks. ↩︎