Bdd and-testing

50
Behaviour Driven Development and thinking about testing Malcolm Tredinnick [email protected]

description

Random thinking about how to think about testing and brief introduction to behavioural (code, not psychological) testing.

Transcript of Bdd and-testing

Page 1: Bdd and-testing

Behaviour Driven Developmentand thinking about testing

Malcolm [email protected]

Page 2: Bdd and-testing

1) Testing landscape

2) A different way to think about this

3) Code

Why have I asked you here today?

Page 3: Bdd and-testing

Chapter I: The Testing Landscape

Page 4: Bdd and-testing

IntegratedIsolated

Page 5: Bdd and-testing

IntegratedIsolated

Testing unitsize?

Mocks

External serviceavailability

Running time?

Page 6: Bdd and-testing

Mocks

● Substitute for external systems & components● Need to be injected into the tests

● “Monkey patching”● Dependency injection

Page 7: Bdd and-testing

Monkey patching

import socket

def setUp(...): socket.socket = DummySocketObject ...

Page 8: Bdd and-testing

Mocks

● Substitute for external systems & components● Need to be injected into the tests

● “Monkey patching”● Dependency injection

● Need to be kept in synch with reality!

Page 9: Bdd and-testing

IntegratedIsolated

Infras truc ture

Page 10: Bdd and-testing

IntegratedIsolated

Infras truc ture

Main

tena

nce

Page 11: Bdd and-testing

Testing Strategies

Some of many...

Page 12: Bdd and-testing

Testing Strategies

● Formal verification

Page 13: Bdd and-testing

Testing Strategies

● Formal verification● Test everything you can think of

Page 14: Bdd and-testing

Testing Strategies

● Formal verification● Test everything you can think of● Anti-regression suite

No bug fix without a test

● Formal verification● Test everything you can think of● Anti-regression suite

No bug fix without a test

● Formal verification● Test everything you can think of● Anti-regression suite

No bug fix without a test

Page 15: Bdd and-testing

Testing Strategies

● Formal verification● Test everything you can think of● Anti-regression suite

● Formal verification● Test everything you can think of● Anti-regression suite

● Formal verification● Test everything you can think of● Anti-regression suite● Test driven development (TDD)

Page 16: Bdd and-testing

TDD

1.Write a (failing) test for next method or class

2.Write minimal code to make test pass

3.Rinse, wash, repeat.

Page 17: Bdd and-testing

Testing Strategies

● Formal verification● Test everything you can think of● Anti-regression suite

● Formal verification● Test everything you can think of● Anti-regression suite

● Formal verification● Test everything you can think of● Anti-regression suite● Test driven development (TDD)

“Specification, not verification”

Page 18: Bdd and-testing

Testing Strategies

● Formal verification● Test everything you can think of● Anti-regression suite

● Formal verification● Test everything you can think of● Anti-regression suite

● Formal verification● Test everything you can think of● Anti-regression suite● Test driven development (TDD)● Documentation driven development (DDD?)

Page 19: Bdd and-testing

Testing Strategies

● Formal verification● Test everything you can think of● Anti-regression suite

● Formal verification● Test everything you can think of● Anti-regression suite

● Formal verification● Test everything you can think of● Anti-regression suite● Test driven development (TDD)● Documentation driven development (DDD?)● Behaviour driven development (BDD)

Page 20: Bdd and-testing

Chapter II: A different way of thinking

Page 21: Bdd and-testing

Interlude: Creating systems...

Page 22: Bdd and-testing

Interlude: Creating systems...

Specification

Page 23: Bdd and-testing

Interlude: Creating systems...

Specification

Implementation

Testing

Page 24: Bdd and-testing

Specification

● On (e-)paper?● quick sketch● formal requirements document● mailing list discussion

● In your head?

Page 25: Bdd and-testing

Specification

● Capturing the idea is probably good● “What was I thinking smoking when...?”

Page 26: Bdd and-testing

Specification

As a [user or role],

I want [feature]

so that [something happens]

Page 27: Bdd and-testing

Specification

As a maze creator,

I want to be able to specify dimensions

so that a new maze of the given size is created.

Page 28: Bdd and-testing

BDD

What is the next most important

thing the code should do?

Page 29: Bdd and-testing

BDD

What is the next most important

thing the code should do?

Be able totest this... ... then implement it.

Page 30: Bdd and-testing

Scenario

Given that [initial context],

if and when [some event occurs]

then [ensure some outcomes]

Page 31: Bdd and-testing

Use case versus scenario

Given that [initial context],

if and when [some event occurs]

then [ensure some outcomes]

As a [user or role],

I want [feature]

so that [something happens]

Page 32: Bdd and-testing

Chapter III: Concrete code

Page 33: Bdd and-testing

Interlude: Naming things

Language helps guide our brain.

Focuses the mind.

Perhaps too exclusively.

Page 34: Bdd and-testing

Interlude: Naming things

The Sapir-Whorf Hypothesis:

“[...] the structure of a language affects the ways in

which its speakers are able to conceptualise their

world [view].”

Page 35: Bdd and-testing

Example #1: Python's unittest module

Page 36: Bdd and-testing

Test titles

class BasicFieldTests (TestCase):

def test_field_name (self):

...

def test_show_hidden_initial (self):

...

Page 37: Bdd and-testing

Test titles

class Fields (TestCase):

def should_allow_name_override (self):

...

class ChoiceFields (TestCase):

def should_permit_initial_values_in_hidden_widgets (self):

...

Page 38: Bdd and-testing

Run new test titles

Write a load_test() method to pull outall the “should” methods.

(Easy enough, but a few lines of code.)

Page 39: Bdd and-testing

Matching to scenarios

● Typically, end up creating more classes than unittests (not a bad thing; classes are “free”).● Thinking about test names helps with class names

and roles.

● Context setup is done in setUp() method.● Normal unittest assertions work fairly cleanly.

Page 40: Bdd and-testing

Example #2: Doctests

Page 41: Bdd and-testing

Narrative style testingJane created a new maze with a small (5 x 5) size.

>>> from maze import Maze>>> maze = Maze(5, 5)

Spot, her dog, did not think the new maze was the right size, but Jane was able to convince him like this:

>>> maze.x_size5>>> maze.y_size5

They found the entry and exit locations in their new maze:

>>>maze.entry_cell(0, 0, “left”)

(etc)

Page 42: Bdd and-testing

Narrative style testing

● Excellent if you are truly writing a narrative. ● Can be difficult to maintain (but not always).● Avoid if large amounts of setup required.● Use with caution. Do use. Do not abuse.

Page 43: Bdd and-testing

Example #3: Domain specific languages

Page 44: Bdd and-testing

DSL packages

● Lettuce● Freshen

Both available through PyPI

Page 45: Bdd and-testing

Freshen example

Scenario: Divide regular numbers

Given I have entered 3 into the calculator

And I have entered 2 into the calculator

When I press divide

Then the result should be 1.5 on the screen

(Code samples from Freshen documentation)

Page 46: Bdd and-testing

Backing code

from freshen import *

import calculator

@Beforedef before(unused): scc.calc = calculator.Calculator() scc.result = None

@Given("I have entered (\d+) into the calculator")def enter(num): scc.calc.push(int(num))

(Code samples from Freshen documentation)

Page 47: Bdd and-testing

Backing code

@When("I press (\w+)")def press(button): op = getattr(scc.calc, button) scc.result = op()

@Then("the result should be (.*) on the screen")def check_result(value): assert_equal(str(scc.result), value)

(Code samples from Freshen documentation)

Page 48: Bdd and-testing

Freshen templated example

Scenario Outline: Add two numbers

Given I have entered <input_1> into the calculator

And I have entered <input_2> into the calculator

When I press <button>

Then the result should be <output> on the screen

Examples:

| input_1 | input_2 | button | output |

| 20 | 30 | add | 50 |

| 2 | 5 | add | 7 |

| 0 | 40 | add | 40 |

(Code samples from Freshen documentation)

Page 49: Bdd and-testing

Conclusions(?)

● Behavioural tests are worth trying● Question the way you think from time to time● Are your tests' purpose clear to future you?

Page 50: Bdd and-testing

https://github.com/malcolmt/bdd-and-testing-talk

[email protected]@malcolmt