SlideShare ist ein Scribd-Unternehmen logo
1 von 191
Downloaden Sie, um offline zu lesen
Dave Farley
http://www.davefarley.net
@davefarley77
http://www.continuous-delivery.co.uk
(C)opyright Dave Farley 2015
Acceptance Testing for
Continuous Delivery
http://www.continuous-delivery.co.uk
(C)opyright Dave Farley 2017
The Role of Acceptance Testing
Local Dev. Env.
Source
Repository
(C)opyright Dave Farley 2017
The Role of Acceptance Testing
Artifact
Repository
Local Dev. Env.
Deployment Pipeline
Commit
Production Env.
Deployment
App.
Commit
Acceptance
Manual
Perf1
Perf2
Staged
Production
Source
Repository
Acceptance
Component
Performance
System
Performance
Staging Env.
Deployment
App.
Manual Test Env.
Deployment
App.
(C)opyright Dave Farley 2017
The Role of Acceptance Testing
Artifact
Repository
Local Dev. Env.
Deployment Pipeline
Commit
Production Env.
Deployment
App.
Commit
Acceptance
Manual
Perf1
Perf2
Staged
Production
Source
Repository
Acceptance
Component
Performance
System
Performance
Staging Env.
Deployment
App.
Manual Test Env.
Deployment
App.
Staging Env.
Deployment
App.
Manual Test Env.
Deployment
App.
Component
Performance
System
Performance
Acceptance
(C)opyright Dave Farley 2017
The Role of Acceptance Testing
Artifact
Repository
Local Dev. Env.
Deployment Pipeline
Commit
Production Env.
Deployment
App.
Commit
Acceptance
Manual
Perf1
Perf2
Staged
Production
Source
Repository
Acceptance
Component
Performance
System
Performance
Staging Env.
Deployment
App.
Manual Test Env.
Deployment
App.
Staging Env.
Deployment
App.
Manual Test Env.
Deployment
App.
Component
Performance
System
Performance
Acceptance
What is Acceptance Testing?
Asserts that the code does what the users want.
What is Acceptance Testing?
An automated “definition of done”
What is Acceptance Testing?
Asserts that the code works in a “production-like”
test environment.
What is Acceptance Testing?
A test of the deployment and configuration of a
whole system.
What is Acceptance Testing?
Provides timely feedback on stories - closes a
feedback loop.
What is Acceptance Testing?
Acceptance Testing, ATDD, BDD, Specification by
Example, Executable Specifications.
(C)opyright Dave Farley 2017
What is Acceptance Testing?
A Good Acceptance Test is:
An Executable Specification of
the Behaviour of the System
(C)opyright Dave Farley 2017
What is Acceptance Testing?
Unit Test CodeIdea
Executable
spec.
Build Release
(C)opyright Dave Farley 2017
What is Acceptance Testing?
Unit Test CodeIdea
Executable
spec.
Build Release
(C)opyright Dave Farley 2017
What is Acceptance Testing?
Unit Test CodeIdea
Executable
spec.
Build Release
(C)opyright Dave Farley 2017
The Problem:
There is often a disconnect between what users
want of a system and what the software delivers.
(C)opyright Dave Farley 2017
The Problem:
There is often a disconnect between what users
want of a system and what the software delivers.
(C)opyright Dave Farley 2017
The Problem:
Identifying user-need and designing a solution
are two VERY difficult problems
Let’s Try to NOT solve both
at the same time!
(C)opyright Dave Farley 2017
The Problem:
Identifying user-need and designing a solution
are two VERY difficult problems
Let’s Try to NOT solve both
at the same time!
(C)opyright Dave Farley 2017
The Problem:
In Most Orgs, Functional Testing is Manual
(C)opyright Dave Farley 2017
The Problem:
In Most Orgs, Functional Testing is Manual
(C)opyright Dave Farley 2017
The Problem:
In Most Orgs, Functional Testing is Manual
(C)opyright Dave Farley 2017
The Problem:
In Most Orgs, Functional Testing is Manual
Slow, Low-Quality,
Expensive, Unreliable,
Error Prone,
Fragile,
Results Hard to Understand,
…
(C)opyright Dave Farley 2017
The Problem:
Automated Functional Tests Often Tightly-
Coupled To SUT
(C)opyright Dave Farley 2017
The Problem:
Automated Functional Tests Often Tightly-
Coupled To SUT
(C)opyright Dave Farley 2017
The Problem:
Automated Functional Tests Often Tightly-
Coupled To SUT
Slow to Develop,
Low-Quality, Expensive,
Unreliable,
Error Prone,
Fragile,
…
(C)opyright Dave Farley 2017
The Problem:
So if there is a disconnect, how can we bridge
that gap?
(C)opyright Dave Farley 2017
The Problem:
So if there is a disconnect, how can we bridge
that gap?
(C)opyright Dave Farley 2017
The Solution:
Establish a common shared language for
expressing a user’s need
(C)opyright Dave Farley 2017
The Solution:
Establish a common shared language for
expressing a user’s need
(C)opyright Dave Farley 2017
Technique:
Always capture any requirement from the
perspective of “an external user of the system”
(C)opyright Dave Farley 2017
Technique:
Always capture any requirement from the
perspective of “an external user of the system”
(C)opyright Dave Farley 2017
Technique:
Avoid ANY reference to HOW the system works
(C)opyright Dave Farley 2017
Technique:
Avoid ANY reference to HOW the system works
(C)opyright Dave Farley 2017
Technique:
Focus on WHAT the user wants of the system
(C)opyright Dave Farley 2017
Technique:
Focus on WHAT the user wants of the system
(C)opyright Dave Farley 2017
Technique:
Link Executable Specs to User Stories
(C)opyright Dave Farley 2017
Technique:
Link Executable Specs to User Stories
(C)opyright Dave Farley 2017
123 Some Story S
As a user I want some behaviour
so that I can achieve some benefit
Acceptance
Criteria
Story Templates
▪ A result that will indicate that the benefit is achieved
▪ Another result to confirm the benefit
(C)opyright Dave Farley 2017
123 Some Story S
As a user I want some behaviour
so that I can achieve some benefit
Acceptance
Criteria
Story Templates
▪ A result that will indicate that the benefit is achieved
▪ Another result to confirm the benefit
Test Case 1a..n
(C)opyright Dave Farley 2017
123 Some Story S
As a user I want some behaviour
so that I can achieve some benefit
Acceptance
Criteria
Story Templates
▪ A result that will indicate that the benefit is achieved
▪ Another result to confirm the benefit
Test Case 1a..n
Test Case 2a..n
(C)opyright Dave Farley 2017
Technique:
Make the Team’s “Definition of Done” = Minimum
of 1 Acceptance Test for each Acceptance
Criteria
(C)opyright Dave Farley 2017
Technique:
Make the Team’s “Definition of Done” = Minimum
of 1 Acceptance Test for each Acceptance
Criteria
(C)opyright Dave Farley 2017
Technique:
Imagine the least technical person, who
understands the problem domain, reading the
spec - It should make sense to them!
(C)opyright Dave Farley 2017
Technique:
Imagine the least technical person, who
understands the problem domain, reading the
spec - It should make sense to them!
(C)opyright Dave Farley 2017
Technique:
Avoid “Technical Stories”, Always find the
fundamental User need
(C)opyright Dave Farley 2017
Technique:
Avoid “Technical Stories”, Always find the
fundamental User need
(C)opyright Dave Farley 2017
Technique:
Make each story, each specification as small as
possible
(C)opyright Dave Farley 2017
Technique:
Make each story, each specification as small as
possible
Small is Good!
(C)opyright Dave Farley 2015
So What’s So Hard?
• Tests break when the SUT changes (Particularly UI)
• This is a problem of design, the tests are too
tightly-coupled to the SUT!
• The history is littered with poor implementations:
• UI Record-and-playback Systems
• Record-and-playback of production data
• Dumps of production data to test systems
• Nasty automated testing products.
(C)opyright Dave Farley 2015
So What’s So Hard?
• Tests break when the SUT changes (Particularly UI)
• This is a problem of design, the tests are too
tightly-coupled to the SUT!
• The history is littered with poor implementations:
• UI Record-and-playback Systems
• Record-and-playback of production data
• Dumps of production data to test systems
• Nasty automated testing products.
Anti-Pattern!
Anti-Pattern!
Anti-Pattern!
Anti-Pattern!
(C)opyright Dave Farley 2015
Who Owns the Tests?
• Anyone can write a test
• Developers are the people that will break tests
• Therefore Developers own the responsibility to
keep them working
• Separate Testing/QA team owning automated
tests
(C)opyright Dave Farley 2015
Who Owns the Tests?
• Anyone can write a test
• Developers are the people that will break tests
• Therefore Developers own the responsibility to
keep them working
• Separate Testing/QA team owning automated
tests Anti-Pattern!
(C)opyright Dave Farley 2015
Who Owns the Tests?
Developers Own
Acceptance Tests!
(C)opyright Dave Farley 2015
Properties of Good Acceptance Tests
• “What” not “How”
• Isolated from other tests
• Repeatable
• Uses the language of the problem domain
• Tests ANY change
• Efficient
(C)opyright Dave Farley 2015
Properties of Good Acceptance Tests
• “What” not “How”
• Isolated from other tests
• Repeatable
• Uses the language of the problem domain
• Tests ANY change
• Efficient
(C)opyright Dave Farley 2015
Public API FIX API
Trade
Reporting
Gateway
…
“What” not “How”
API Traders
Clearing
Destination
Other
external
end-points
Market
Makers
UI
Traders
(C)opyright Dave Farley 2015
Public API FIX API
Trade
Reporting
Gateway
…
“What” not “How”
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
(C)opyright Dave Farley 2015
Public API FIX API
Trade
Reporting
Gateway
…FIX API
“What” not “How”
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
(C)opyright Dave Farley 2015
Public API FIX API
Trade
Reporting
Gateway
…
“What” not “How”
API Traders
Clearing
Destination
Other
external
end-points
Market
Makers
UI
Traders
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
(C)opyright Dave Farley 2015
Public API FIX API
Trade
Reporting
Gateway
…
“What” not “How”
FIX API
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
API
External
Stubs
FIX-APIUI FIX-APIFIX-API
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
(C)opyright Dave Farley 2015
Public API FIX API
Trade
Reporting
Gateway
…
“What” not “How”
FIX API
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
API
External
Stubs
FIX-APIUI FIX-API
(C)opyright Dave Farley 2015
Public API FIX API
Trade
Reporting
Gateway
…
“What” not “How”
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
Test
Case
API
External
Stubs
FIX-APIUI FIX-API
(C)opyright Dave Farley 2015
Public API FIX API
Trade
Reporting
Gateway
…
“What” not “How”
API
External
Stubs
FIX-APIUI FIX-API
Test infrastructure common to all acceptance tests
(C)opyright Dave Farley 2015
“What” not “How” - Separate Deployment from Testing
• Every Test should control its start conditions,
and so should start and init the app.
• Acceptance Test deployment should be a
rehearsal for Production Release
• This separation of concerns provides an
opportunity for optimisation
• Parallel tests in a shared environment
• Lower test start-up overhead
(C)opyright Dave Farley 2015
“What” not “How” - Separate Deployment from Testing
• Every Test should control its start conditions,
and so should start and init the app.
• Acceptance Test deployment should be a
rehearsal for Production Release
• This separation of concerns provides an
opportunity for optimisation
• Parallel tests in a shared environment
• Lower test start-up overhead
Anti-Pattern!
(C)opyright Dave Farley 2015
Properties of Good Acceptance Tests
• “What” not “How”
• Isolated from other tests
• Repeatable
• Uses the language of the problem domain
• Tests ANY change
• Efficient
(C)opyright Dave Farley 2015
Properties of Good Acceptance Tests
• “What” not “How”
• Isolated from other tests
• Repeatable
• Uses the language of the problem domain
• Tests ANY change
• Efficient
(C)opyright Dave Farley 2015
Test Isolation
• Any form of testing is about evaluating
something in controlled circumstances
• Isolation works on multiple levels
• Isolating the System under test
• Isolating test cases from each other
• Isolating test cases from themselves (temporal isolation)
• Isolation is a vital part of your Test Strategy
(C)opyright Dave Farley 2015
Test Isolation - Isolating the System Under Test
(C)opyright Dave Farley 2015
Test Isolation - Isolating the System Under Test
External System
‘A’
External System
‘C’
System Under Test
‘B’
(C)opyright Dave Farley 2015
Test Isolation - Isolating the System Under Test
External System
‘A’
External System
‘C’
System Under Test
‘B’
(C)opyright Dave Farley 2015
Test Isolation - Isolating the System Under Test
External System
‘A’
External System
‘C’
System Under Test
‘B’
(C)opyright Dave Farley 2015
Test Isolation - Isolating the System Under Test
External System
‘A’
External System
‘C’
System Under Test
‘B’
?
(C)opyright Dave Farley 2015
Test Isolation - Isolating the System Under Test
External System
‘A’
External System
‘C’
System Under Test
‘B’Anti-Pattern!
(C)opyright Dave Farley 2015
Test Isolation - Isolating the System Under Test
System Under Test
‘B’
Test Cases
Verifiable
Output
(C)opyright Dave Farley 2015
Test Isolation - Validating The Interfaces
(C)opyright Dave Farley 2015
Test Isolation - Validating The Interfaces
External System
‘A’
External System
‘C’
System Under Test
‘B’
(C)opyright Dave Farley 2015
Test Isolation - Validating The Interfaces
External System
‘A’
External System
‘C’
System Under Test
‘B’
(C)opyright Dave Farley 2015
Test Isolation - Validating The Interfaces
External System
‘A’
External System
‘C’
Test Cases
Verifiable
Output
System Under Test
‘B’
Test Cases
Verifiable
Output
Test Cases
Verifiable
Output
(C)opyright Dave Farley 2015
Test Isolation - Validating The Interfaces
External System
‘A’
External System
‘C’
Test Cases
Verifiable
Output
System Under Test
‘B’
Test Cases
Verifiable
Output
Test Cases Verifiable
Output
(C)opyright Dave Farley 2015
Test Isolation - Isolating Test Cases
(Assuming multi-user systems…)
• Tests should be efficient - We want to run LOTS!
• What we really want is to deploy once, and run LOTS of
tests
• So we must avoid ANY dependencies between tests…
• Use natural functional isolation e.g.
• If testing Amazon, create a new account and a new book/product for
every test-case
• If testing eBay create a new account and a new auction for every test-
case
• If testing GitHub, create a new account and a new repository for every
test-case
• …
(C)opyright Dave Farley 2015
• We want repeatable results
• If I run my test-case twice it should work both
times
Test Isolation - Temporal Isolation
(C)opyright Dave Farley 2015
• We want repeatable results
• If I run my test-case twice it should work both
times
Test Isolation - Temporal Isolation
def test_should_place_an_order(self):
self.store.createBook(“Continuous Delivery”);
order = self.store.placeOrder(book=“Continuous Delivery")
self.store.assertOrderPlaced(order)
(C)opyright Dave Farley 2015
• We want repeatable results
• If I run my test-case twice it should work both
times
Test Isolation - Temporal Isolation
def test_should_place_an_order(self):
self.store.createBook(“Continuous Delivery”);
order = self.store.placeOrder(book=“Continuous Delivery")
self.store.assertOrderPlaced(order)
(C)opyright Dave Farley 2015
• We want repeatable results
• If I run my test-case twice it should work both
times
Test Isolation - Temporal Isolation
def test_should_place_an_order(self):
self.store.createBook(“Continuous Delivery”);
order = self.store.placeOrder(book=“Continuous Delivery")
self.store.assertOrderPlaced(order)
(C)opyright Dave Farley 2015
• We want repeatable results
• If I run my test-case twice it should work both
times
Test Isolation - Temporal Isolation
def test_should_place_an_order(self):
self.store.createBook(“Continuous Delivery”);
order = self.store.placeOrder(book=“Continuous Delivery")
self.store.assertOrderPlaced(order)
Continuous Delivery
(C)opyright Dave Farley 2015
• We want repeatable results
• If I run my test-case twice it should work both
times
Test Isolation - Temporal Isolation
def test_should_place_an_order(self):
self.store.createBook(“Continuous Delivery”);
order = self.store.placeOrder(book=“Continuous Delivery")
self.store.assertOrderPlaced(order)
Continuous Delivery
(C)opyright Dave Farley 2015
• We want repeatable results
• If I run my test-case twice it should work both
times
Test Isolation - Temporal Isolation
def test_should_place_an_order(self):
self.store.createBook(“Continuous Delivery”);
order = self.store.placeOrder(book=“Continuous Delivery")
self.store.assertOrderPlaced(order)
Continuous Delivery1234
(C)opyright Dave Farley 2015
• We want repeatable results
• If I run my test-case twice it should work both
times
Test Isolation - Temporal Isolation
def test_should_place_an_order(self):
self.store.createBook(“Continuous Delivery”);
order = self.store.placeOrder(book=“Continuous Delivery")
self.store.assertOrderPlaced(order)
Continuous Delivery1234
Continuous Delivery6789
(C)opyright Dave Farley 2015
• We want repeatable results
• If I run my test-case twice it should work both
times
Test Isolation - Temporal Isolation
def test_should_place_an_order(self):
self.store.createBook(“Continuous Delivery”);
order = self.store.placeOrder(book=“Continuous Delivery")
self.store.assertOrderPlaced(order)
Continuous Delivery1234
Continuous Delivery6789
• Alias your functional isolation entities
• In your test case create account ‘Dave’ in reality the in the
test infrastructure ask the application to create account
‘Dave2938472398472’ and alias.
(C)opyright Dave Farley 2015
Properties of Good Acceptance Tests
• “What” not “How”
• Isolated from other tests
• Repeatable
• Uses the language of the problem domain
• Tests ANY change
• Efficient
(C)opyright Dave Farley 2015
Properties of Good Acceptance Tests
• “What” not “How”
• Isolated from other tests
• Repeatable
• Uses the language of the problem domain
• Tests ANY change
• Efficient
(C)opyright Dave Farley 2015
Repeatability - Test Doubles
External System
(C)opyright Dave Farley 2015
Repeatability - Test Doubles
External System
Local Interface
to External System
(C)opyright Dave Farley 2015
Repeatability - Test Doubles
External System
Local Interface
to External System
Communications
to External System
(C)opyright Dave Farley 2015
Repeatability - Test Doubles
External System
Local Interface
to External System
Communications
to External System
TestStub
Simulating External
System
Local Interface
to External System
(C)opyright Dave Farley 2015
Repeatability - Test Doubles
External System
Local Interface
to External System
Communications
to External System
TestStub
Simulating External
System
Local Interface
to External System
Production
Test
Environm
ent
kjhaskjhdkjhkjh askjhl lkjasl dkjas lkajl ajsd
lkjalskjlakjsdlkajsld j
lkajsdlkajsldkj
lkjlakjsldkjlka laskj ljl akjl kajsldijupoqwiuepoq dlkjl iu
lkajsodiuqpwouoi la
]laksjdiuqoiwuoijds
oijasodiaosidjuoiasud
kjhaskjhdkjhkjh askjhl lkjasl dkjas lkajl ajsd
lkjalskjlakjsdlkajsld j
lkajsdlkajsldkj
lkjlakjsldkjlka laskj ljl akjl kajsldijupoqwiuepoq dlkjl iu
lkajsodiuqpwouoi la
]laksjdiuqoiwuoijds
oijasodiaosidjuoiasud
Configuration
(C)opyright Dave Farley 2015
Test Doubles As Part of Test Infrastructure
TestStub
Simulating External
System
Local Interface
to External System
(C)opyright Dave Farley 2015
Test Doubles As Part of Test Infrastructure
TestStub
Simulating External
System
Local Interface
to External System
(C)opyright Dave Farley 2015
Test Doubles As Part of Test Infrastructure
TestStub
Simulating External
System
Local Interface
to External System
Public Interface
(C)opyright Dave Farley 2015
Test Doubles As Part of Test Infrastructure
TestStub
Simulating External
System
Local Interface
to External System
Public Interface
(C)opyright Dave Farley 2015
Test Doubles As Part of Test Infrastructure
TestStub
Simulating External
System
Local Interface
to External System
Test Infrastructure
Test
Case
Test
Case
Test
Case
Test
Case
Test Infrastructure
Back-Channel
Public Interface
System
UnderTest
(C)opyright Dave Farley 2015
Properties of Good Acceptance Tests
• “What” not “How”
• Isolated from other tests
• Repeatable
• Uses the language of the problem domain
• Tests ANY change
• Efficient
(C)opyright Dave Farley 2015
Properties of Good Acceptance Tests
• “What” not “How”
• Isolated from other tests
• Repeatable
• Uses the language of the problem domain
• Tests ANY change
• Efficient
(C)opyright Dave Farley 2015
Language of the Problem Domain - DSL
• A Simple ‘DSL’ Solves many of our problems
• Ease of TestCase creation
• Readability
• Ease of Maintenance
• Separation of “What” from “How”
• Test Isolation
• The Chance to abstract complex set-up and scenarios
• …
(C)opyright Dave Farley 2015
Language of the Problem Domain - DSL
• A Simple ‘DSL’ Solves many of our problems
• Ease of TestCase creation
• Readability
• Ease of Maintenance
• Separation of “What” from “How”
• Test Isolation
• The Chance to abstract complex set-up and scenarios
• …
BDD
Behaviour Driven Development
(C)opyright Dave Farley 2015
Language of the Problem Domain - External DSL
ThoughtWorks’ TWIST
|eg.Division|
|numerator|denominator|quotient?|
|10 |2 |5 |
|12.6 |3 |4.2 |
|100 |4 |33 |
FITnesse
Narrative:
In order to communicate effectively to the business some functionality
As a development team
I want to use Behaviour-Driven Development
Lifecycle:
Before:
Given a step that is executed before each scenario
After:
Outcome: ANY
Given a step that is executed after each scenario regardless of outcome
Outcome: SUCCESS
Given a step that is executed after each successful scenario
Outcome: FAILURE
Given a step that is executed after each failed scenario
Scenario: A scenario is a collection of executable steps of different type
Given step represents a precondition to an event
When step represents the occurrence of the event
Then step represents the outcome of the event
Examples:
|precondition|be-captured|
|abc|be captured |
|xyz|not be captured|
JBehave
Cucumber - Gherkin
(C)opyright Dave Farley 2015
Language of the Problem Domain - Internal DSL
EasyB - Groovy
given "an invalid zip code", {
invalidzipcode = "221o1"
}
and "given the zipcodevalidator is initialized", {
zipvalidate = new ZipCodeValidator()
}
when "validate is invoked with the invalid zip code", {
value = zipvalidate.validate(invalidzipcode)
}
then "the validator instance should return false", {
value.shouldBe false
}
My Homebrew - Java
@Channel(fixApi, dealTicket, publicApi)
@Test
public void shouldSuccessfullyPlaceAnImmediateOrCancelBuyMarketOrder()
{
trading.placeOrder("instrument", "side: buy", “price: 123.45”, "quantity: 4", "goodUntil: Immediate”);
trading.waitForExecutionReport("executionType: Fill", "orderStatus: Filled",
"side: buy", "quantity: 4", "matched: 4", "remaining: 0",
"executionPrice: 123.45", "executionQuantity: 4");
}
My Homebrew - Pythonfrom acceptance_test_dsl.acc_test_dsl import AccTestDsl
class PlaceOrderTest(AccTestDsl):
def setUp(self):
AccTestDsl.setUp(self)
self.add_channel("TRADING")
self.add_end_point("MQ")
def test_should_successfully_place_market_order(self):
order = self.trading.placeOrder(symbol="ZVZZT",
orderType="Market",
qty=300, TimeInForce='IOC')
self.trading.assertOrderPlaced(order)
(C)opyright Dave Farley 2015
Language of the Problem Domain - DSL
@Test
public void shouldSupportPlacingValidBuyAndSellLimitOrders()
{
trading.selectDealTicket("instrument");
trading.dealTicket.placeOrder("type: limit", ”bid: 4@10”);
trading.dealTicket.checkFeedbackMessage("You have successfully sent a limit order to buy 4.00 contracts at 10.0");
trading.dealTicket.dismissFeedbackMessage();
trading.dealTicket.placeOrder("type: limit", ”ask: 4@9”);
trading.dealTicket.checkFeedbackMessage("You have successfully sent a limit order to sell 4.00 contracts at 9.0");
}
(C)opyright Dave Farley 2015
Language of the Problem Domain - DSL
@Test
public void shouldSupportPlacingValidBuyAndSellLimitOrders()
{
trading.selectDealTicket("instrument");
trading.dealTicket.placeOrder("type: limit", ”bid: 4@10”);
trading.dealTicket.checkFeedbackMessage("You have successfully sent a limit order to buy 4.00 contracts at 10.0");
trading.dealTicket.dismissFeedbackMessage();
trading.dealTicket.placeOrder("type: limit", ”ask: 4@9”);
trading.dealTicket.checkFeedbackMessage("You have successfully sent a limit order to sell 4.00 contracts at 9.0");
}
@Test
public void shouldSuccessfullyPlaceAnImmediateOrCancelBuyMarketOrder()
{
fixAPIMarketMaker.placeMassOrder("instrument", "ask: 11@52", "ask: 10@51", "ask: 10@50", "bid: 10@49");
fixAPI.placeOrder("instrument", "side: buy", "quantity: 4", "goodUntil: Immediate", "allowUnmatched: true");
fixAPI.waitForExecutionReport("executionType: Fill", "orderStatus: Filled",
"side: buy", "quantity: 4", "matched: 4", "remaining: 0",
"executionPrice: 50", "executionQuantity: 4");
}
(C)opyright Dave Farley 2015
Language of the Problem Domain - DSL
@Test
public void shouldSupportPlacingValidBuyAndSellLimitOrders()
{
trading.selectDealTicket("instrument");
trading.dealTicket.placeOrder("type: limit", ”bid: 4@10”);
trading.dealTicket.checkFeedbackMessage("You have successfully sent a limit order to buy 4.00 contracts at 10.0");
trading.dealTicket.dismissFeedbackMessage();
trading.dealTicket.placeOrder("type: limit", ”ask: 4@9”);
trading.dealTicket.checkFeedbackMessage("You have successfully sent a limit order to sell 4.00 contracts at 9.0");
}
@Test
public void shouldSuccessfullyPlaceAnImmediateOrCancelBuyMarketOrder()
{
fixAPIMarketMaker.placeMassOrder("instrument", "ask: 11@52", "ask: 10@51", "ask: 10@50", "bid: 10@49");
fixAPI.placeOrder("instrument", "side: buy", "quantity: 4", "goodUntil: Immediate", "allowUnmatched: true");
fixAPI.waitForExecutionReport("executionType: Fill", "orderStatus: Filled",
"side: buy", "quantity: 4", "matched: 4", "remaining: 0",
"executionPrice: 50", "executionQuantity: 4");
}
@Before
public void beforeEveryTest()
{
adminAPI.createInstrument("name: instrument");
registrationAPI.createUser("user");
registrationAPI.createUser("marketMaker", "accountType: MARKET_MAKER");
tradingUI.loginAsLive("user");
}
(C)opyright Dave Farley 2015
Language of the Problem Domain - DSL
public void placeOrder(final String... args)
{
final DslParams params =
new DslParams(args,
new OptionalParam("type").setDefault("Limit").setAllowedValues("limit", "market", "StopMarket
new OptionalParam("side").setDefault("Buy").setAllowedValues("buy", "sell"),
new OptionalParam("price"),
new OptionalParam("triggerPrice"),
new OptionalParam("quantity"),
new OptionalParam("stopProfitOffset"),
new OptionalParam("stopLossOffset"),
new OptionalParam("confirmFeedback").setDefault("true"));
getDealTicketPageDriver().placeOrder(params.value("type"),
params.value("side"),
params.value("price"),
params.value("triggerPrice"),
params.value("quantity"),
params.value("stopProfitOffset"),
params.value("stopLossOffset"));
if (params.valueAsBoolean("confirmFeedback"))
{
getDealTicketPageDriver().clickOrderFeedbackConfirmationButton();
}
LOGGER.debug("placeOrder(" + Arrays.deepToString(args) + ")");
}
(C)opyright Dave Farley 2015
Language of the Problem Domain - DSL
public void placeOrder(final String... args)
{
final DslParams params = new DslParams(args,
new RequiredParam("instrument"),
new OptionalParam("clientOrderId"),
new OptionalParam("order"),
new OptionalParam("side").setAllowedValues("buy", "sell"),
new OptionalParam("orderType").setAllowedValues("market", "limit"),
new OptionalParam("price"),
new OptionalParam("bid"),
new OptionalParam("ask"),
new OptionalParam("symbol").setDefault("BARC"),
new OptionalParam("quantity"),
new OptionalParam("goodUntil").setAllowedValues("Immediate", "Cancelled").setDefault("Cancelled"),
new OptionalParam("allowUnmatched").setAllowedValues("true", "false").setDefault("true"),
new OptionalParam("possibleResend").setAllowedValues("true", "false").setDefault("false"),
new OptionalParam("unauthorised").setAllowedValues("true"),
new OptionalParam("brokeredAccountId"),
new OptionalParam("msgSeqNum"),
new OptionalParam("orderCapacity").setAllowedValues("AGENCY", "PRINCIPAL", "").setDefault("PRINCIPA
new OptionalParam("accountType").setAllowedValues("CUSTOMER", "HOUSE", "").setDefault("HOUSE"),
new OptionalParam("accountClearingReference"),
new OptionalParam("expectedOrderRejectionStatus").setAllowedValues("TOO_LATE_TO_ENTER",
"BROKER_EXCHANGE_OPTION",
"UNKNOWN_SYMBOL",
"DUPLICATE_ORDER"),
new OptionalParam("expectedOrderRejectionReason").setAllowedValues("INSUFFICIENT_LIQUIDITY",
"INSTRUMENT_NOT_OPEN",
"INSTRUMENT_DOES_NOT_EXIST",
"DUPLICATE_ORDER",
"QUANTITY_NOT_VALID",
"PRICE_NOT_VALID",
"INVALID_ORDER_INSTRUCTION",
"OUTSIDE_VOLATILITY_BAND",
"INVALID_INSTRUMENT_SYMBOL",
"ACCESS_DENIED",
"INSTRUMENT_SUSPENDED"),
new OptionalParam("expectedSessionRejectionReason").setAllowedValues("INVALID_TAG_NUMBER",
“REQUIRED_TAG_MISSING",
…
(C)opyright Dave Farley 2015
Language of the Problem Domain - DSL
@Test
public void shouldSupportPlacingValidBuyAndSellLimitOrders()
{
tradingUI.showDealTicket("instrument");
tradingUI.dealTicket.placeOrder("type: limit", ”bid: 4@10”);
tradingUI.dealTicket.checkFeedbackMessage("You have successfully sent a limit order to buy 4.00 contracts at
tradingUI.dealTicket.dismissFeedbackMessage();
tradingUI.dealTicket.placeOrder("type: limit", ”ask: 4@9”);
tradingUI.dealTicket.checkFeedbackMessage("You have successfully sent a limit order to sell 4.00 contracts at
}
@Test
public void shouldSuccessfullyPlaceAnImmediateOrCancelBuyMarketOrder()
{
fixAPIMarketMaker.placeMassOrder("instrument", "ask: 11@52", "ask: 10@51", "ask: 10@50", "bid: 10@49");
fixAPI.placeOrder("instrument", "side: buy", "quantity: 4", "goodUntil: Immediate", "allowUnmatched: true");
fixAPI.waitForExecutionReport("executionType: Fill", "orderStatus: Filled",
"side: buy", "quantity: 4", "matched: 4", "remaining: 0",
"executionPrice: 50", "executionQuantity: 4");
}
(C)opyright Dave Farley 2015
Language of the Problem Domain - DSL
@Test
public void shouldSupportPlacingValidBuyAndSellLimitOrders()
{
tradingUI.showDealTicket("instrument");
tradingUI.dealTicket.placeOrder("type: limit", ”bid: 4@10”);
tradingUI.dealTicket.checkFeedbackMessage("You have successfully sent a limit order to buy 4.00 contracts at
tradingUI.dealTicket.dismissFeedbackMessage();
tradingUI.dealTicket.placeOrder("type: limit", ”ask: 4@9”);
tradingUI.dealTicket.checkFeedbackMessage("You have successfully sent a limit order to sell 4.00 contracts at
}
@Test
public void shouldSuccessfullyPlaceAnImmediateOrCancelBuyMarketOrder()
{
fixAPIMarketMaker.placeMassOrder("instrument", "ask: 11@52", "ask: 10@51", "ask: 10@50", "bid: 10@49");
fixAPI.placeOrder("instrument", "side: buy", "quantity: 4", "goodUntil: Immediate", "allowUnmatched: true");
fixAPI.waitForExecutionReport("executionType: Fill", "orderStatus: Filled",
"side: buy", "quantity: 4", "matched: 4", "remaining: 0",
"executionPrice: 50", "executionQuantity: 4");
}
(C)opyright Dave Farley 2015
Language of the Problem Domain - DSL
@Channel(fixApi, dealTicket, publicApi)
@Test
public void shouldSuccessfullyPlaceAnImmediateOrCancelBuyMarketOrder()
{
trading.placeOrder("instrument", "side: buy", “price: 123.45”, "quantity: 4", "goodUntil: Immediate”);
trading.waitForExecutionReport("executionType: Fill", "orderStatus: Filled",
"side: buy", "quantity: 4", "matched: 4", "remaining: 0",
"executionPrice: 123.45", "executionQuantity: 4");
}
(C)opyright Dave Farley 2015
Language of the Problem Domain - DSL
@Channel(fixApi, dealTicket, publicApi)
@Test
public void shouldSuccessfullyPlaceAnImmediateOrCancelBuyMarketOrder()
{
trading.placeOrder("instrument", "side: buy", “price: 123.45”, "quantity: 4", "goodUntil: Immediate”);
trading.waitForExecutionReport("executionType: Fill", "orderStatus: Filled",
"side: buy", "quantity: 4", "matched: 4", "remaining: 0",
"executionPrice: 123.45", "executionQuantity: 4");
}
(C)opyright Dave Farley 2015
Language of the Problem Domain - Evolving a DSL
• Write the test case first
• Whoever would normally write the case specifies the
language to express the idea
• Get a Developer to implement the DSL to
support the new test case
• It’s OK for the Dev to refine the language to make it
cleaner, more general - but keep it simple!
• Devs should keeping pushing the DSL to be clean of ANY
understanding of the “How”
• Think of this as designing a language. Have some rules
about what should be in and what should not.
(C)opyright Dave Farley 2015
DSL- Four Layer Structure
(C)opyright Dave Farley 2015
DSL- Four Layer Structure
Test Case
(Executable
Specification)
Test Case
(Executable
Specification)
Test Case
(Executable
Specification)
Test Case
(Executable
Specification)
(C)opyright Dave Farley 2015
DSL- Four Layer Structure
Domain Specific Language
Test Case
(Executable
Specification)
Test Case
(Executable
Specification)
Test Case
(Executable
Specification)
Test Case
(Executable
Specification)
(C)opyright Dave Farley 2015
DSL- Four Layer Structure
Domain Specific Language
Test Case
(Executable
Specification)
Test Case
(Executable
Specification)
Test Case
(Executable
Specification)
Test Case
(Executable
Specification)
Protocol
Driver
(e.g. UI)
Protocol
Driver
(e.g. API)
External
System Stub
External
System Stub
(C)opyright Dave Farley 2015
DSL- Four Layer Structure
Domain Specific Language
Test Case
(Executable
Specification)
Test Case
(Executable
Specification)
Test Case
(Executable
Specification)
Test Case
(Executable
Specification)
Protocol
Driver
(e.g. UI)
System Under Test
Protocol
Driver
(e.g. API)
External
System Stub
External
System Stub
(C)opyright Dave Farley 2015
Properties of Good Acceptance Tests
• “What” not “How”
• Isolated from other tests
• Repeatable
• Uses the language of the problem domain
• Tests ANY change
• Efficient
(C)opyright Dave Farley 2015
Properties of Good Acceptance Tests
• “What” not “How”
• Isolated from other tests
• Repeatable
• Uses the language of the problem domain
• Tests ANY change
• Efficient
(C)opyright Dave Farley 2015
Testing with Time
• Test Cases should be deterministic
• Time is a problem for determinism - There are
two options:
• Ignore time
• Control time
(C)opyright Dave Farley 2015
Testing With Time - Ignore Time
Mechanism
Filter out time-based values in your test
infrastructure so that they are ignored
Pros:
• Simple!
Cons:
• Can miss errors
• Prevents any hope of testing complex time-based
scenarios
(C)opyright Dave Farley 2015
Mechanism
Treat Time as an external dependency, like an
external system - and Fake it!
Pros:
• Very Flexible!
• Can simulate any time-based scenario, with time under the
control of the test case.
Cons:
• Slightly more complex infrastructure
Testing With Time - Controlling Time
(C)opyright Dave Farley 2015
Testing With Time - Controlling Time
@Test
public void shouldBeOverdueAfterOneMonth()
{
book = library.borrowBook(“Continuous Delivery”);
assertFalse(book.isOverdue());
time.travel(“+1 week”);
assertFalse(book.isOverdue());
time.travel(“+4 weeks”);
assertTrue(book.isOverdue());
}
(C)opyright Dave Farley 2015
Testing With Time - Controlling Time
@Test
public void shouldBeOverdueAfterOneMonth()
{
book = library.borrowBook(“Continuous Delivery”);
assertFalse(book.isOverdue());
time.travel(“+1 week”);
assertFalse(book.isOverdue());
time.travel(“+4 weeks”);
assertTrue(book.isOverdue());
}
(C)opyright Dave Farley 2015
Testing With Time - Controlling Time
(C)opyright Dave Farley 2015
Testing With Time - Controlling Time
Test Infrastructure
Test
Case
Test
Case
Test
Case
Test
Case
System
UnderTest
public void someTimeDependentMethod()
{
time = System.getTime();
}
System
UnderTest
(C)opyright Dave Farley 2015
Testing With Time - Controlling Time
Test Infrastructure
Test
Case
Test
Case
Test
Case
Test
Case
System
UnderTest
include Clock;
public void someTimeDependentMethod()
{
time = Clock.getTime();
}
System
UnderTest
(C)opyright Dave Farley 2015
Testing With Time - Controlling Time
Test Infrastructure
Test
Case
Test
Case
Test
Case
Test
Case
System
UnderTest
include Clock;
public void someTimeDependentMethod()
{
time = Clock.getTime();
}
public class Clock {
public static clock = new SystemClock();
public static void setTime(long newTime) {
clock.setTime(newTime);
}
public static long getTime() {
return clock.getTime();
}
System
UnderTest
(C)opyright Dave Farley 2015
Testing With Time - Controlling Time
Test Infrastructure
Test
Case
Test
Case
Test
Case
Test
Case
System
UnderTest
include Clock;
public void someTimeDependentMethod()
{
time = Clock.getTime();
}
public void onInit() {
// Remote Call - back-channel
systemUnderTest.setClock(new TestClock());
}
public void time-travel(String time) {
long newTime = parseTime(time);
// Remote Call - back-channel
systemUnderTest.setTime(newTime);
}
Test Infrastructure
Back-Channel
public class Clock {
public static clock = new SystemClock();
public static void setTime(long newTime) {
clock.setTime(newTime);
}
public static long getTime() {
return clock.getTime();
}
System
UnderTest
(C)opyright Dave Farley 2015
Test Environment Types
• Some Tests need special treatment.
• Tag Tests with properties and allocate them
dynamically:
(C)opyright Dave Farley 2015
Test Environment Types
• Some Tests need special treatment.
• Tag Tests with properties and allocate them
dynamically:
@TimeTravel
@Test
public void shouldDoSomethingThatNeedsFakeTime()
…
@Destructive
@Test
public void shouldDoSomethingThatKillsPartOfTheSystem()
…
@FPGA(version=1.3)
@Test
public void shouldDoSomethingThatRequiresSpecificHardware()
…
(C)opyright Dave Farley 2015
Test Environment Types
• Some Tests need special treatment.
• Tag Tests with properties and allocate them
dynamically:
@TimeTravel
@Test
public void shouldDoSomethingThatNeedsFakeTime()
…
@Destructive
@Test
public void shouldDoSomethingThatKillsPartOfTheSystem()
…
@FPGA(version=1.3)
@Test
public void shouldDoSomethingThatRequiresSpecificHardware()
…
(C)opyright Dave Farley 2015
Test Environment Types
(C)opyright Dave Farley 2015
Test Environment Types
(C)opyright Dave Farley 2015
Properties of Good Acceptance Tests
• “What” not “How”
• Isolated from other tests
• Repeatable
• Uses the language of the problem domain
• Tests ANY change
• Efficient
(C)opyright Dave Farley 2015
Properties of Good Acceptance Tests
• “What” not “How”
• Isolated from other tests
• Repeatable
• Uses the language of the problem domain
• Tests ANY change
• Efficient
(C)opyright Dave Farley 2015
Production-like Test Environments
(C)opyright Dave Farley 2015
Production-like Test Environments
(C)opyright Dave Farley 2015
Production-like Test Environments
(C)opyright Dave Farley 2015
Production-like Test Environments
(C)opyright Dave Farley 2015
Production-like Test Environments
(C)opyright Dave Farley 2015
Production-like Test Environments
(C)opyright Dave Farley 2015
Production-like Test Environments
(C)opyright Dave Farley 2015
Make Test Cases Internally Synchronous
(C)opyright Dave Farley 2015
Make Test Cases Internally Synchronous
• Look for a “Concluding Event” listen for that in
your DSL to report an async call as complete
•
(C)opyright Dave Farley 2015
Make Test Cases Internally Synchronous
Example DSL level Implementation…
public String placeOrder(String params…)
{
orderSent = sendAsyncPlaceOrderMessage(parseOrderParams(params));
return waitForOrderConfirmedOrFailOnTimeOut(orderSent);
}
• Look for a “Concluding Event” listen for that in
your DSL to report an async call as complete
•
(C)opyright Dave Farley 2015
Make Test Cases Internally Synchronous
Example DSL level Implementation…
public String placeOrder(String params…)
{
orderSent = sendAsyncPlaceOrderMessage(parseOrderParams(params));
return waitForOrderConfirmedOrFailOnTimeOut(orderSent);
}
• Look for a “Concluding Event” listen for that in
your DSL to report an async call as complete
•
(C)opyright Dave Farley 2015
Make Test Cases Internally Synchronous
• Look for a “Concluding Event” listen for that in
your DSL to report an async call as complete
• If you really have to, implement a 

“poll-and-timeout” mechanism in your test-
infrastructure
• Never, Never, Never, put a “wait(xx)” and expect
your tests to be (a) Reliable or (b) Efficient!
• Look for a “Concluding Event” listen for that in
your DSL to report an async call as complete
•
(C)opyright Dave Farley 2015
Make Test Cases Internally Synchronous
• Look for a “Concluding Event” listen for that in
your DSL to report an async call as complete
• If you really have to, implement a 

“poll-and-timeout” mechanism in your test-
infrastructure
• Never, Never, Never, put a “wait(xx)” and expect
your tests to be (a) Reliable or (b) Efficient!
• Look for a “Concluding Event” listen for that in
your DSL to report an async call as complete
•
Anti-Pattern!
(C)opyright Dave Farley 2015
Scaling-Up
Artifact
Repository
Deployment Pipeline
Acceptance
Commit
Component
Performance
System
Performance
Staging Env.
Deployment
App.
Production Env.
Deployment
App.
Source
Repository
Manual Test Env.
Deployment
App.
(C)opyright Dave Farley 2015
Scaling-Up
Artifact
Repository
Deployment Pipeline
Acceptance
Commit
Component
Performance
System
Performance
Staging Env.
Deployment
App.
Production Env.
Deployment
App.
Source
Repository
Manual Test Env.
Deployment
App.
Deployment Pipeline
Commit
Manual Test Env.
Deployment
App.
Artifact
Repository
Acceptance Acceptance Test
Environment
(C)opyright Dave Farley 2015
Scaling-Up
Artifact
Repository
Deployment Pipeline
Acceptance
Commit
Component
Performance
System
Performance
Staging Env.
Deployment
App.
Production Env.
Deployment
App.
Source
Repository
Manual Test Env.
Deployment
App.
Deployment Pipeline
Commit
Manual Test Env.
Deployment
App.
Artifact
Repository
Acceptance Acceptance Test
Environment
AA
(C)opyright Dave Farley 2015
Scaling-Up
Artifact
Repository
Deployment Pipeline
Acceptance
Commit
Component
Performance
System
Performance
Staging Env.
Deployment
App.
Production Env.
Deployment
App.
Source
Repository
Manual Test Env.
Deployment
App.
Deployment Pipeline
Commit
Manual Test Env.
Deployment
App.
Artifact
Repository
Acceptance Acceptance Test
Environment
A
A
(C)opyright Dave Farley 2015
Scaling-Up
Artifact
Repository
Deployment Pipeline
Acceptance
Commit
Component
Performance
System
Performance
Staging Env.
Deployment
App.
Production Env.
Deployment
App.
Source
Repository
Manual Test Env.
Deployment
App.
Deployment Pipeline
Commit
Manual Test Env.
Deployment
App.
Artifact
Repository
Acceptance Acceptance Test
Environment
Test Host
Test Host
Test Host
Test Host
Test Host
A
A
(C)opyright Dave Farley 2015
Scaling-Up
Artifact
Repository
Deployment Pipeline
Acceptance
Commit
Component
Performance
System
Performance
Staging Env.
Deployment
App.
Production Env.
Deployment
App.
Source
Repository
Manual Test Env.
Deployment
App.
Deployment Pipeline
Commit
Manual Test Env.
Deployment
App.
Artifact
Repository
Acceptance
Acceptance
Acceptance Test
Environment
Test Host
Test Host
Test Host
Test Host
Test Host
AA
(C)opyright Dave Farley 2015
Data - SUT State
• One More Desirable Property…
• We should be able to run our tests anywhere

• Ideally we want SUT to be an a fairly ‘Neutral’
State
• Data Defining SUT State Falls into 3 categories:
• Transactional Data
• Reference Data
• Configuration Data
(C)opyright Dave Farley 2015
Data - SUT State
• One More Desirable Property…
• We should be able to run our tests anywhere

• Ideally we want SUT to be an a fairly ‘Neutral’
State
• Data Defining SUT State Falls into 3 categories:
• Transactional Data
• Reference Data
• Configuration Data
Use Prod
Data
Generate
in Scope of
Test
Use
Versioned
Test Data
(C)opyright Dave Farley 2015
Data - SUT State
• One More Desirable Property…
• We should be able to run our tests anywhere

• Ideally we want SUT to be an a fairly ‘Neutral’
State
• Data Defining SUT State Falls into 3 categories:
• Transactional Data
• Reference Data
• Configuration Data
Use Prod
Data
Generate
in Scope of
Test
Use
Versioned
Test Data
(C)opyright Dave Farley 2015
Data - SUT State
• One More Desirable Property…
• We should be able to run our tests anywhere

• Ideally we want SUT to be an a fairly ‘Neutral’
State
• Data Defining SUT State Falls into 3 categories:
• Transactional Data
• Reference Data
• Configuration Data
Use Prod
Data
Generate
in Scope of
Test
Use
Versioned
Test Data
(C)opyright Dave Farley 2015
Data - SUT State
• One More Desirable Property…
• We should be able to run our tests anywhere

• Ideally we want SUT to be an a fairly ‘Neutral’
State
• Data Defining SUT State Falls into 3 categories:
• Transactional Data
• Reference Data
• Configuration Data
Use Prod
Data
Generate
in Scope of
Test
Use
Versioned
Test Data
(C)opyright Dave Farley 2015
Anti-Patterns in Acceptance Testing
(C)opyright Dave Farley 2015
Anti-Patterns in Acceptance Testing
• Don’t use UI Record-and-playback Systems
(C)opyright Dave Farley 2015
Anti-Patterns in Acceptance Testing
• Don’t use UI Record-and-playback Systems
• Don’t Record-and-playback production data. This has a role, but it is NOT
Acceptance Testing
(C)opyright Dave Farley 2015
Anti-Patterns in Acceptance Testing
• Don’t use UI Record-and-playback Systems
• Don’t Record-and-playback production data. This has a role, but it is NOT
Acceptance Testing
• Don’t dump production data to your test systems, instead define the absolute
minimum data that you need
(C)opyright Dave Farley 2015
Anti-Patterns in Acceptance Testing
• Don’t use UI Record-and-playback Systems
• Don’t Record-and-playback production data. This has a role, but it is NOT
Acceptance Testing
• Don’t dump production data to your test systems, instead define the absolute
minimum data that you need
• Don’t assume Nasty Automated Testing Products(tm) will do what you need. Be very
sceptical about them. Start with YOUR strategy and evaluate tools against that.
(C)opyright Dave Farley 2015
Anti-Patterns in Acceptance Testing
• Don’t use UI Record-and-playback Systems
• Don’t Record-and-playback production data. This has a role, but it is NOT
Acceptance Testing
• Don’t dump production data to your test systems, instead define the absolute
minimum data that you need
• Don’t assume Nasty Automated Testing Products(tm) will do what you need. Be very
sceptical about them. Start with YOUR strategy and evaluate tools against that.
• Don’t have a separate Testing/QA team! Quality is down to everyone - Developers
own Acceptance Tests!!!
(C)opyright Dave Farley 2015
Anti-Patterns in Acceptance Testing
• Don’t use UI Record-and-playback Systems
• Don’t Record-and-playback production data. This has a role, but it is NOT
Acceptance Testing
• Don’t dump production data to your test systems, instead define the absolute
minimum data that you need
• Don’t assume Nasty Automated Testing Products(tm) will do what you need. Be very
sceptical about them. Start with YOUR strategy and evaluate tools against that.
• Don’t have a separate Testing/QA team! Quality is down to everyone - Developers
own Acceptance Tests!!!
• Don’t let every Test start and init the app. Optimise for Cycle-Time, be efficient in
your use of test environments.
(C)opyright Dave Farley 2015
Anti-Patterns in Acceptance Testing
• Don’t use UI Record-and-playback Systems
• Don’t Record-and-playback production data. This has a role, but it is NOT
Acceptance Testing
• Don’t dump production data to your test systems, instead define the absolute
minimum data that you need
• Don’t assume Nasty Automated Testing Products(tm) will do what you need. Be very
sceptical about them. Start with YOUR strategy and evaluate tools against that.
• Don’t have a separate Testing/QA team! Quality is down to everyone - Developers
own Acceptance Tests!!!
• Don’t let every Test start and init the app. Optimise for Cycle-Time, be efficient in
your use of test environments.
• Don’t include Systems outside of your control in your Acceptance Test Scope
(C)opyright Dave Farley 2015
Anti-Patterns in Acceptance Testing
• Don’t use UI Record-and-playback Systems
• Don’t Record-and-playback production data. This has a role, but it is NOT
Acceptance Testing
• Don’t dump production data to your test systems, instead define the absolute
minimum data that you need
• Don’t assume Nasty Automated Testing Products(tm) will do what you need. Be very
sceptical about them. Start with YOUR strategy and evaluate tools against that.
• Don’t have a separate Testing/QA team! Quality is down to everyone - Developers
own Acceptance Tests!!!
• Don’t let every Test start and init the app. Optimise for Cycle-Time, be efficient in
your use of test environments.
• Don’t include Systems outside of your control in your Acceptance Test Scope
• Don’t Put ‘wait()’ instructions in your tests hoping it will solve intermittency
(C)opyright Dave Farley 2015
Tricks for Success
(C)opyright Dave Farley 2015
Tricks for Success
• Do Ensure That Developers Own the Tests
(C)opyright Dave Farley 2015
Tricks for Success
• Do Ensure That Developers Own the Tests
• Do Focus Your Tests on “What” not “How”
(C)opyright Dave Farley 2015
Tricks for Success
• Do Ensure That Developers Own the Tests
• Do Focus Your Tests on “What” not “How”
• Do Think of Your Tests as “Executable Specifications”
(C)opyright Dave Farley 2015
Tricks for Success
• Do Ensure That Developers Own the Tests
• Do Focus Your Tests on “What” not “How”
• Do Think of Your Tests as “Executable Specifications”
• Do Make Acceptance Testing Part of your “Definition of Done”
(C)opyright Dave Farley 2015
Tricks for Success
• Do Ensure That Developers Own the Tests
• Do Focus Your Tests on “What” not “How”
• Do Think of Your Tests as “Executable Specifications”
• Do Make Acceptance Testing Part of your “Definition of Done”
• Do Keep Tests Isolated from one-another
(C)opyright Dave Farley 2015
Tricks for Success
• Do Ensure That Developers Own the Tests
• Do Focus Your Tests on “What” not “How”
• Do Think of Your Tests as “Executable Specifications”
• Do Make Acceptance Testing Part of your “Definition of Done”
• Do Keep Tests Isolated from one-another
• Do Keep Your Tests Repeatable
(C)opyright Dave Farley 2015
Tricks for Success
• Do Ensure That Developers Own the Tests
• Do Focus Your Tests on “What” not “How”
• Do Think of Your Tests as “Executable Specifications”
• Do Make Acceptance Testing Part of your “Definition of Done”
• Do Keep Tests Isolated from one-another
• Do Keep Your Tests Repeatable
• Do Use the Language of the Problem Domain - Do try the DSL approach, whatever
your tech.
(C)opyright Dave Farley 2015
Tricks for Success
• Do Ensure That Developers Own the Tests
• Do Focus Your Tests on “What” not “How”
• Do Think of Your Tests as “Executable Specifications”
• Do Make Acceptance Testing Part of your “Definition of Done”
• Do Keep Tests Isolated from one-another
• Do Keep Your Tests Repeatable
• Do Use the Language of the Problem Domain - Do try the DSL approach, whatever
your tech.
• Do Stub External Systems
(C)opyright Dave Farley 2015
Tricks for Success
• Do Ensure That Developers Own the Tests
• Do Focus Your Tests on “What” not “How”
• Do Think of Your Tests as “Executable Specifications”
• Do Make Acceptance Testing Part of your “Definition of Done”
• Do Keep Tests Isolated from one-another
• Do Keep Your Tests Repeatable
• Do Use the Language of the Problem Domain - Do try the DSL approach, whatever
your tech.
• Do Stub External Systems
• Do Test in “Production-Like” Environments
(C)opyright Dave Farley 2015
Tricks for Success
• Do Ensure That Developers Own the Tests
• Do Focus Your Tests on “What” not “How”
• Do Think of Your Tests as “Executable Specifications”
• Do Make Acceptance Testing Part of your “Definition of Done”
• Do Keep Tests Isolated from one-another
• Do Keep Your Tests Repeatable
• Do Use the Language of the Problem Domain - Do try the DSL approach, whatever
your tech.
• Do Stub External Systems
• Do Test in “Production-Like” Environments
• Do Make Instructions Appear Synchronous at the Level of the Test Case
(C)opyright Dave Farley 2015
Tricks for Success
• Do Ensure That Developers Own the Tests
• Do Focus Your Tests on “What” not “How”
• Do Think of Your Tests as “Executable Specifications”
• Do Make Acceptance Testing Part of your “Definition of Done”
• Do Keep Tests Isolated from one-another
• Do Keep Your Tests Repeatable
• Do Use the Language of the Problem Domain - Do try the DSL approach, whatever
your tech.
• Do Stub External Systems
• Do Test in “Production-Like” Environments
• Do Make Instructions Appear Synchronous at the Level of the Test Case
• Do Test for ANY change
(C)opyright Dave Farley 2015
Tricks for Success
• Do Ensure That Developers Own the Tests
• Do Focus Your Tests on “What” not “How”
• Do Think of Your Tests as “Executable Specifications”
• Do Make Acceptance Testing Part of your “Definition of Done”
• Do Keep Tests Isolated from one-another
• Do Keep Your Tests Repeatable
• Do Use the Language of the Problem Domain - Do try the DSL approach, whatever
your tech.
• Do Stub External Systems
• Do Test in “Production-Like” Environments
• Do Make Instructions Appear Synchronous at the Level of the Test Case
• Do Test for ANY change
• Do Keep your Tests Efficient
(C)opyright Dave Farley 2015
Further Exploration
• http://en.wikipedia.org/wiki/Behavior-driven_development
• http://www.thoughtworks.com/insights/blog/specification-example
• https://cukes.info/
• http://jbehave.org/
• http://www.agiledata.org/essays/databaseTesting.html
• http://www.red-gate.com/
• http://www.dbmaestro.com/
• https://www.youtube.com/watch?v=pw_RBblVny4
(C)opyright Dave Farley 2015
Q&A
http://www.continuous-delivery.co.uk
Dave Farley
http://www.davefarley.net
@davefarley77

Weitere ähnliche Inhalte

Was ist angesagt?

Building resilient scheduling in distributed systems with Spring
Building resilient scheduling in distributed systems with SpringBuilding resilient scheduling in distributed systems with Spring
Building resilient scheduling in distributed systems with SpringMarek Jeszka
 
잘 키운 모노리스 하나 열 마이크로서비스 안 부럽다
잘 키운 모노리스 하나 열 마이크로서비스 안 부럽다잘 키운 모노리스 하나 열 마이크로서비스 안 부럽다
잘 키운 모노리스 하나 열 마이크로서비스 안 부럽다Arawn Park
 
Hexagonal architecture with Spring Boot
Hexagonal architecture with Spring BootHexagonal architecture with Spring Boot
Hexagonal architecture with Spring BootMikalai Alimenkou
 
A Rails performance guidebook: from 0 to 1B requests/day
A Rails performance guidebook: from 0 to 1B requests/dayA Rails performance guidebook: from 0 to 1B requests/day
A Rails performance guidebook: from 0 to 1B requests/dayCristian González
 
Handling Redis failover with ZooKeeper
Handling Redis failover with ZooKeeperHandling Redis failover with ZooKeeper
Handling Redis failover with ZooKeeperryanlecompte
 
My first 90 days with ClickHouse.pdf
My first 90 days with ClickHouse.pdfMy first 90 days with ClickHouse.pdf
My first 90 days with ClickHouse.pdfAlkin Tezuysal
 
Indexes: The neglected performance all rounder
Indexes: The neglected performance all rounderIndexes: The neglected performance all rounder
Indexes: The neglected performance all rounderMarkus Winand
 
Kafka Retry and DLQ
Kafka Retry and DLQKafka Retry and DLQ
Kafka Retry and DLQGeorge Teo
 
twMVC#44 讓我們用 k6 來進行壓測吧
twMVC#44 讓我們用 k6 來進行壓測吧twMVC#44 讓我們用 k6 來進行壓測吧
twMVC#44 讓我們用 k6 來進行壓測吧twMVC
 
Kafka streams windowing behind the curtain
Kafka streams windowing behind the curtain Kafka streams windowing behind the curtain
Kafka streams windowing behind the curtain confluent
 
Compliance as Code with terraform-compliance
Compliance as Code with terraform-complianceCompliance as Code with terraform-compliance
Compliance as Code with terraform-complianceEmre Erkunt
 
Microservices Workshop - Craft Conference
Microservices Workshop - Craft ConferenceMicroservices Workshop - Craft Conference
Microservices Workshop - Craft ConferenceAdrian Cockcroft
 
ClickHouse in Real Life. Case Studies and Best Practices, by Alexander Zaitsev
ClickHouse in Real Life. Case Studies and Best Practices, by Alexander ZaitsevClickHouse in Real Life. Case Studies and Best Practices, by Alexander Zaitsev
ClickHouse in Real Life. Case Studies and Best Practices, by Alexander ZaitsevAltinity Ltd
 
Database migrations with Flyway and Liquibase
Database migrations with Flyway and LiquibaseDatabase migrations with Flyway and Liquibase
Database migrations with Flyway and LiquibaseLars Östling
 
Eventing Things - A Netflix Original! (Nitin Sharma, Netflix) Kafka Summit SF...
Eventing Things - A Netflix Original! (Nitin Sharma, Netflix) Kafka Summit SF...Eventing Things - A Netflix Original! (Nitin Sharma, Netflix) Kafka Summit SF...
Eventing Things - A Netflix Original! (Nitin Sharma, Netflix) Kafka Summit SF...confluent
 

Was ist angesagt? (20)

Building resilient scheduling in distributed systems with Spring
Building resilient scheduling in distributed systems with SpringBuilding resilient scheduling in distributed systems with Spring
Building resilient scheduling in distributed systems with Spring
 
잘 키운 모노리스 하나 열 마이크로서비스 안 부럽다
잘 키운 모노리스 하나 열 마이크로서비스 안 부럽다잘 키운 모노리스 하나 열 마이크로서비스 안 부럽다
잘 키운 모노리스 하나 열 마이크로서비스 안 부럽다
 
Hexagonal architecture with Spring Boot
Hexagonal architecture with Spring BootHexagonal architecture with Spring Boot
Hexagonal architecture with Spring Boot
 
A Rails performance guidebook: from 0 to 1B requests/day
A Rails performance guidebook: from 0 to 1B requests/dayA Rails performance guidebook: from 0 to 1B requests/day
A Rails performance guidebook: from 0 to 1B requests/day
 
Handling Redis failover with ZooKeeper
Handling Redis failover with ZooKeeperHandling Redis failover with ZooKeeper
Handling Redis failover with ZooKeeper
 
Event storming recipes
Event storming recipesEvent storming recipes
Event storming recipes
 
My first 90 days with ClickHouse.pdf
My first 90 days with ClickHouse.pdfMy first 90 days with ClickHouse.pdf
My first 90 days with ClickHouse.pdf
 
Indexes: The neglected performance all rounder
Indexes: The neglected performance all rounderIndexes: The neglected performance all rounder
Indexes: The neglected performance all rounder
 
Kafka Retry and DLQ
Kafka Retry and DLQKafka Retry and DLQ
Kafka Retry and DLQ
 
Hexagonal And Beyond
Hexagonal And BeyondHexagonal And Beyond
Hexagonal And Beyond
 
twMVC#44 讓我們用 k6 來進行壓測吧
twMVC#44 讓我們用 k6 來進行壓測吧twMVC#44 讓我們用 k6 來進行壓測吧
twMVC#44 讓我們用 k6 來進行壓測吧
 
Kafka streams windowing behind the curtain
Kafka streams windowing behind the curtain Kafka streams windowing behind the curtain
Kafka streams windowing behind the curtain
 
Cloud arch patterns
Cloud arch patternsCloud arch patterns
Cloud arch patterns
 
Compliance as Code with terraform-compliance
Compliance as Code with terraform-complianceCompliance as Code with terraform-compliance
Compliance as Code with terraform-compliance
 
Transactions redefined
Transactions redefinedTransactions redefined
Transactions redefined
 
Recursive Query Throwdown
Recursive Query ThrowdownRecursive Query Throwdown
Recursive Query Throwdown
 
Microservices Workshop - Craft Conference
Microservices Workshop - Craft ConferenceMicroservices Workshop - Craft Conference
Microservices Workshop - Craft Conference
 
ClickHouse in Real Life. Case Studies and Best Practices, by Alexander Zaitsev
ClickHouse in Real Life. Case Studies and Best Practices, by Alexander ZaitsevClickHouse in Real Life. Case Studies and Best Practices, by Alexander Zaitsev
ClickHouse in Real Life. Case Studies and Best Practices, by Alexander Zaitsev
 
Database migrations with Flyway and Liquibase
Database migrations with Flyway and LiquibaseDatabase migrations with Flyway and Liquibase
Database migrations with Flyway and Liquibase
 
Eventing Things - A Netflix Original! (Nitin Sharma, Netflix) Kafka Summit SF...
Eventing Things - A Netflix Original! (Nitin Sharma, Netflix) Kafka Summit SF...Eventing Things - A Netflix Original! (Nitin Sharma, Netflix) Kafka Summit SF...
Eventing Things - A Netflix Original! (Nitin Sharma, Netflix) Kafka Summit SF...
 

Ähnlich wie Acceptance Testing for Continuous Delivery by Dave Farley at #AgileIndia2019

Dave Farley - Taking Back “Software Engineering” - Codemotion Amsterdam 2019
Dave Farley - Taking Back “Software Engineering” - Codemotion Amsterdam 2019Dave Farley - Taking Back “Software Engineering” - Codemotion Amsterdam 2019
Dave Farley - Taking Back “Software Engineering” - Codemotion Amsterdam 2019Codemotion
 
DevDay 2016: Dave Farley - Acceptance testing for continuous delivery
DevDay 2016: Dave Farley - Acceptance testing for continuous deliveryDevDay 2016: Dave Farley - Acceptance testing for continuous delivery
DevDay 2016: Dave Farley - Acceptance testing for continuous deliveryDevDay Dresden
 
Acceptance testfurureinmind
Acceptance testfurureinmindAcceptance testfurureinmind
Acceptance testfurureinmindLeanDog
 
Why the h# should I use Appium with React Native
Why the h# should I use Appium with React NativeWhy the h# should I use Appium with React Native
Why the h# should I use Appium with React NativeWim Selles
 
Achieving Continuous Delivery with Puppet
Achieving Continuous Delivery with PuppetAchieving Continuous Delivery with Puppet
Achieving Continuous Delivery with PuppetDevoteam Revolve
 
Puppet Camp Paris 2014: Achieving Continuous Delivery and DevOps with Puppet
Puppet Camp Paris 2014: Achieving Continuous Delivery and DevOps with Puppet Puppet Camp Paris 2014: Achieving Continuous Delivery and DevOps with Puppet
Puppet Camp Paris 2014: Achieving Continuous Delivery and DevOps with Puppet Puppet
 
James Whittaker - Pursuing Quality-You Won't Get There - EuroSTAR 2011
James Whittaker - Pursuing Quality-You Won't Get There - EuroSTAR 2011James Whittaker - Pursuing Quality-You Won't Get There - EuroSTAR 2011
James Whittaker - Pursuing Quality-You Won't Get There - EuroSTAR 2011TEST Huddle
 
[Webinar] Test First, Fail Fast - Simplifying the Tester's Transition to DevOps
[Webinar] Test First, Fail Fast - Simplifying the Tester's Transition to DevOps[Webinar] Test First, Fail Fast - Simplifying the Tester's Transition to DevOps
[Webinar] Test First, Fail Fast - Simplifying the Tester's Transition to DevOpsKMS Technology
 
The DevOps Dance - Shift Left, Shift Right - Get It Right
The DevOps Dance - Shift Left, Shift Right - Get It RightThe DevOps Dance - Shift Left, Shift Right - Get It Right
The DevOps Dance - Shift Left, Shift Right - Get It RightInflectra
 
From Config Management Sucks to #cfgmgmtlove
From Config Management Sucks to #cfgmgmtlove From Config Management Sucks to #cfgmgmtlove
From Config Management Sucks to #cfgmgmtlove Kris Buytaert
 
Automated Database Deployment at SQL Rally
Automated Database Deployment at SQL RallyAutomated Database Deployment at SQL Rally
Automated Database Deployment at SQL RallyGrant Fritchey
 
Continuous delivery is more than dev ops
Continuous delivery is more than dev opsContinuous delivery is more than dev ops
Continuous delivery is more than dev opsAgile Montréal
 
Keeping Your DevOps Transformation From Crushing Your Ops Capacity
Keeping Your DevOps Transformation From Crushing Your Ops Capacity Keeping Your DevOps Transformation From Crushing Your Ops Capacity
Keeping Your DevOps Transformation From Crushing Your Ops Capacity Rundeck
 
Vladimir Primakov - Qa management in big agile teams
Vladimir Primakov - Qa management in big agile teamsVladimir Primakov - Qa management in big agile teams
Vladimir Primakov - Qa management in big agile teamsIevgenii Katsan
 
Continuous Delivery of (y)our infrastructure.
Continuous Delivery of (y)our infrastructure.Continuous Delivery of (y)our infrastructure.
Continuous Delivery of (y)our infrastructure.Kris Buytaert
 

Ähnlich wie Acceptance Testing for Continuous Delivery by Dave Farley at #AgileIndia2019 (20)

Dave Farley - Taking Back “Software Engineering” - Codemotion Amsterdam 2019
Dave Farley - Taking Back “Software Engineering” - Codemotion Amsterdam 2019Dave Farley - Taking Back “Software Engineering” - Codemotion Amsterdam 2019
Dave Farley - Taking Back “Software Engineering” - Codemotion Amsterdam 2019
 
DevDay 2016: Dave Farley - Acceptance testing for continuous delivery
DevDay 2016: Dave Farley - Acceptance testing for continuous deliveryDevDay 2016: Dave Farley - Acceptance testing for continuous delivery
DevDay 2016: Dave Farley - Acceptance testing for continuous delivery
 
Acceptance testfurureinmind
Acceptance testfurureinmindAcceptance testfurureinmind
Acceptance testfurureinmind
 
Why the h# should I use Appium with React Native
Why the h# should I use Appium with React NativeWhy the h# should I use Appium with React Native
Why the h# should I use Appium with React Native
 
Achieving Continuous Delivery with Puppet
Achieving Continuous Delivery with PuppetAchieving Continuous Delivery with Puppet
Achieving Continuous Delivery with Puppet
 
Puppet Camp Paris 2014: Achieving Continuous Delivery and DevOps with Puppet
Puppet Camp Paris 2014: Achieving Continuous Delivery and DevOps with Puppet Puppet Camp Paris 2014: Achieving Continuous Delivery and DevOps with Puppet
Puppet Camp Paris 2014: Achieving Continuous Delivery and DevOps with Puppet
 
James Whittaker - Pursuing Quality-You Won't Get There - EuroSTAR 2011
James Whittaker - Pursuing Quality-You Won't Get There - EuroSTAR 2011James Whittaker - Pursuing Quality-You Won't Get There - EuroSTAR 2011
James Whittaker - Pursuing Quality-You Won't Get There - EuroSTAR 2011
 
Tec314
Tec314Tec314
Tec314
 
Testing smells
Testing smellsTesting smells
Testing smells
 
[Webinar] Test First, Fail Fast - Simplifying the Tester's Transition to DevOps
[Webinar] Test First, Fail Fast - Simplifying the Tester's Transition to DevOps[Webinar] Test First, Fail Fast - Simplifying the Tester's Transition to DevOps
[Webinar] Test First, Fail Fast - Simplifying the Tester's Transition to DevOps
 
Five Flute Overview
Five Flute OverviewFive Flute Overview
Five Flute Overview
 
The DevOps Dance - Shift Left, Shift Right - Get It Right
The DevOps Dance - Shift Left, Shift Right - Get It RightThe DevOps Dance - Shift Left, Shift Right - Get It Right
The DevOps Dance - Shift Left, Shift Right - Get It Right
 
Continuous Delivery
Continuous DeliveryContinuous Delivery
Continuous Delivery
 
From Config Management Sucks to #cfgmgmtlove
From Config Management Sucks to #cfgmgmtlove From Config Management Sucks to #cfgmgmtlove
From Config Management Sucks to #cfgmgmtlove
 
Automated Database Deployment at SQL Rally
Automated Database Deployment at SQL RallyAutomated Database Deployment at SQL Rally
Automated Database Deployment at SQL Rally
 
Continuous delivery is more than dev ops
Continuous delivery is more than dev opsContinuous delivery is more than dev ops
Continuous delivery is more than dev ops
 
TDD and Getting Paid
TDD and Getting PaidTDD and Getting Paid
TDD and Getting Paid
 
Keeping Your DevOps Transformation From Crushing Your Ops Capacity
Keeping Your DevOps Transformation From Crushing Your Ops Capacity Keeping Your DevOps Transformation From Crushing Your Ops Capacity
Keeping Your DevOps Transformation From Crushing Your Ops Capacity
 
Vladimir Primakov - Qa management in big agile teams
Vladimir Primakov - Qa management in big agile teamsVladimir Primakov - Qa management in big agile teams
Vladimir Primakov - Qa management in big agile teams
 
Continuous Delivery of (y)our infrastructure.
Continuous Delivery of (y)our infrastructure.Continuous Delivery of (y)our infrastructure.
Continuous Delivery of (y)our infrastructure.
 

Mehr von Agile India

Design Teams are a Design Exercise by Phillip Joe at #AgileIndia2019
Design Teams are a Design Exercise by Phillip Joe at #AgileIndia2019Design Teams are a Design Exercise by Phillip Joe at #AgileIndia2019
Design Teams are a Design Exercise by Phillip Joe at #AgileIndia2019Agile India
 
Keeping hundreds of code repositories consistent, and staying sane by Vincent...
Keeping hundreds of code repositories consistent, and staying sane by Vincent...Keeping hundreds of code repositories consistent, and staying sane by Vincent...
Keeping hundreds of code repositories consistent, and staying sane by Vincent...Agile India
 
The End is Nigh! Signs of Transformation Apocalypse by Alex Sloley at #AgileI...
The End is Nigh! Signs of Transformation Apocalypse by Alex Sloley at #AgileI...The End is Nigh! Signs of Transformation Apocalypse by Alex Sloley at #AgileI...
The End is Nigh! Signs of Transformation Apocalypse by Alex Sloley at #AgileI...Agile India
 
Strategic Domain-Driven Design by Nick Tune at #AgileIndia2019
Strategic Domain-Driven Design by Nick Tune at #AgileIndia2019Strategic Domain-Driven Design by Nick Tune at #AgileIndia2019
Strategic Domain-Driven Design by Nick Tune at #AgileIndia2019Agile India
 
All track development - (or how we dropped the collective ego and created a p...
All track development - (or how we dropped the collective ego and created a p...All track development - (or how we dropped the collective ego and created a p...
All track development - (or how we dropped the collective ego and created a p...Agile India
 
Open Salaries: from employees to managing partners by Alexey Voronin at #Agil...
Open Salaries: from employees to managing partners by Alexey Voronin at #Agil...Open Salaries: from employees to managing partners by Alexey Voronin at #Agil...
Open Salaries: from employees to managing partners by Alexey Voronin at #Agil...Agile India
 
Scaling Enterprise Agility amidst Cross Border Merger by Rocky Woestenborghs ...
Scaling Enterprise Agility amidst Cross Border Merger by Rocky Woestenborghs ...Scaling Enterprise Agility amidst Cross Border Merger by Rocky Woestenborghs ...
Scaling Enterprise Agility amidst Cross Border Merger by Rocky Woestenborghs ...Agile India
 
InfraOps Agility - A Sysad's Perspective by Dushyanth Harinath at #AgileIndia...
InfraOps Agility - A Sysad's Perspective by Dushyanth Harinath at #AgileIndia...InfraOps Agility - A Sysad's Perspective by Dushyanth Harinath at #AgileIndia...
InfraOps Agility - A Sysad's Perspective by Dushyanth Harinath at #AgileIndia...Agile India
 
Going for 10X: Building teams in a Hyper-Competitive Market by Jacob Singh at...
Going for 10X: Building teams in a Hyper-Competitive Market by Jacob Singh at...Going for 10X: Building teams in a Hyper-Competitive Market by Jacob Singh at...
Going for 10X: Building teams in a Hyper-Competitive Market by Jacob Singh at...Agile India
 
Principle 11 needs to go! by Ken France at #AgileIndia2019
Principle 11 needs to go! by Ken France at #AgileIndia2019Principle 11 needs to go! by Ken France at #AgileIndia2019
Principle 11 needs to go! by Ken France at #AgileIndia2019Agile India
 
Becoming the Catalyst - The Spark of Change that Will Move Your Team Forward ...
Becoming the Catalyst - The Spark of Change that Will Move Your Team Forward ...Becoming the Catalyst - The Spark of Change that Will Move Your Team Forward ...
Becoming the Catalyst - The Spark of Change that Will Move Your Team Forward ...Agile India
 
Branding within your UX: The secret to creating loyal customers by Bill Beard...
Branding within your UX: The secret to creating loyal customers by Bill Beard...Branding within your UX: The secret to creating loyal customers by Bill Beard...
Branding within your UX: The secret to creating loyal customers by Bill Beard...Agile India
 
Build Agile Organization: Lessons Learned from Aikido by Marc Gong at #AgileI...
Build Agile Organization: Lessons Learned from Aikido by Marc Gong at #AgileI...Build Agile Organization: Lessons Learned from Aikido by Marc Gong at #AgileI...
Build Agile Organization: Lessons Learned from Aikido by Marc Gong at #AgileI...Agile India
 
Security considerations while deploying Containerized Applications by Neepend...
Security considerations while deploying Containerized Applications by Neepend...Security considerations while deploying Containerized Applications by Neepend...
Security considerations while deploying Containerized Applications by Neepend...Agile India
 
Cloud Native in the US Federal Government by Jez Humble at #AgileIndia2019
Cloud Native in the US Federal Government by Jez Humble at #AgileIndia2019Cloud Native in the US Federal Government by Jez Humble at #AgileIndia2019
Cloud Native in the US Federal Government by Jez Humble at #AgileIndia2019Agile India
 
Building and Scaling High Performing Technology Organizations by Jez Humble a...
Building and Scaling High Performing Technology Organizations by Jez Humble a...Building and Scaling High Performing Technology Organizations by Jez Humble a...
Building and Scaling High Performing Technology Organizations by Jez Humble a...Agile India
 
Reactive Systems by Dave Farley at #AgileIndia2019
Reactive Systems by Dave Farley at #AgileIndia2019Reactive Systems by Dave Farley at #AgileIndia2019
Reactive Systems by Dave Farley at #AgileIndia2019Agile India
 
Collaboration Contracts by Diane Zajac & Doc Norton at #AgileIndia2019
Collaboration Contracts by Diane Zajac & Doc Norton at #AgileIndia2019Collaboration Contracts by Diane Zajac & Doc Norton at #AgileIndia2019
Collaboration Contracts by Diane Zajac & Doc Norton at #AgileIndia2019Agile India
 
Tuckman was wrong by Doc Norton at #AgileIndia2019
Tuckman was wrong by Doc Norton at #AgileIndia2019Tuckman was wrong by Doc Norton at #AgileIndia2019
Tuckman was wrong by Doc Norton at #AgileIndia2019Agile India
 
7 Steps to Design, Build, and Scale an AI Product by Allie Miller at #AgileIn...
7 Steps to Design, Build, and Scale an AI Product by Allie Miller at #AgileIn...7 Steps to Design, Build, and Scale an AI Product by Allie Miller at #AgileIn...
7 Steps to Design, Build, and Scale an AI Product by Allie Miller at #AgileIn...Agile India
 

Mehr von Agile India (20)

Design Teams are a Design Exercise by Phillip Joe at #AgileIndia2019
Design Teams are a Design Exercise by Phillip Joe at #AgileIndia2019Design Teams are a Design Exercise by Phillip Joe at #AgileIndia2019
Design Teams are a Design Exercise by Phillip Joe at #AgileIndia2019
 
Keeping hundreds of code repositories consistent, and staying sane by Vincent...
Keeping hundreds of code repositories consistent, and staying sane by Vincent...Keeping hundreds of code repositories consistent, and staying sane by Vincent...
Keeping hundreds of code repositories consistent, and staying sane by Vincent...
 
The End is Nigh! Signs of Transformation Apocalypse by Alex Sloley at #AgileI...
The End is Nigh! Signs of Transformation Apocalypse by Alex Sloley at #AgileI...The End is Nigh! Signs of Transformation Apocalypse by Alex Sloley at #AgileI...
The End is Nigh! Signs of Transformation Apocalypse by Alex Sloley at #AgileI...
 
Strategic Domain-Driven Design by Nick Tune at #AgileIndia2019
Strategic Domain-Driven Design by Nick Tune at #AgileIndia2019Strategic Domain-Driven Design by Nick Tune at #AgileIndia2019
Strategic Domain-Driven Design by Nick Tune at #AgileIndia2019
 
All track development - (or how we dropped the collective ego and created a p...
All track development - (or how we dropped the collective ego and created a p...All track development - (or how we dropped the collective ego and created a p...
All track development - (or how we dropped the collective ego and created a p...
 
Open Salaries: from employees to managing partners by Alexey Voronin at #Agil...
Open Salaries: from employees to managing partners by Alexey Voronin at #Agil...Open Salaries: from employees to managing partners by Alexey Voronin at #Agil...
Open Salaries: from employees to managing partners by Alexey Voronin at #Agil...
 
Scaling Enterprise Agility amidst Cross Border Merger by Rocky Woestenborghs ...
Scaling Enterprise Agility amidst Cross Border Merger by Rocky Woestenborghs ...Scaling Enterprise Agility amidst Cross Border Merger by Rocky Woestenborghs ...
Scaling Enterprise Agility amidst Cross Border Merger by Rocky Woestenborghs ...
 
InfraOps Agility - A Sysad's Perspective by Dushyanth Harinath at #AgileIndia...
InfraOps Agility - A Sysad's Perspective by Dushyanth Harinath at #AgileIndia...InfraOps Agility - A Sysad's Perspective by Dushyanth Harinath at #AgileIndia...
InfraOps Agility - A Sysad's Perspective by Dushyanth Harinath at #AgileIndia...
 
Going for 10X: Building teams in a Hyper-Competitive Market by Jacob Singh at...
Going for 10X: Building teams in a Hyper-Competitive Market by Jacob Singh at...Going for 10X: Building teams in a Hyper-Competitive Market by Jacob Singh at...
Going for 10X: Building teams in a Hyper-Competitive Market by Jacob Singh at...
 
Principle 11 needs to go! by Ken France at #AgileIndia2019
Principle 11 needs to go! by Ken France at #AgileIndia2019Principle 11 needs to go! by Ken France at #AgileIndia2019
Principle 11 needs to go! by Ken France at #AgileIndia2019
 
Becoming the Catalyst - The Spark of Change that Will Move Your Team Forward ...
Becoming the Catalyst - The Spark of Change that Will Move Your Team Forward ...Becoming the Catalyst - The Spark of Change that Will Move Your Team Forward ...
Becoming the Catalyst - The Spark of Change that Will Move Your Team Forward ...
 
Branding within your UX: The secret to creating loyal customers by Bill Beard...
Branding within your UX: The secret to creating loyal customers by Bill Beard...Branding within your UX: The secret to creating loyal customers by Bill Beard...
Branding within your UX: The secret to creating loyal customers by Bill Beard...
 
Build Agile Organization: Lessons Learned from Aikido by Marc Gong at #AgileI...
Build Agile Organization: Lessons Learned from Aikido by Marc Gong at #AgileI...Build Agile Organization: Lessons Learned from Aikido by Marc Gong at #AgileI...
Build Agile Organization: Lessons Learned from Aikido by Marc Gong at #AgileI...
 
Security considerations while deploying Containerized Applications by Neepend...
Security considerations while deploying Containerized Applications by Neepend...Security considerations while deploying Containerized Applications by Neepend...
Security considerations while deploying Containerized Applications by Neepend...
 
Cloud Native in the US Federal Government by Jez Humble at #AgileIndia2019
Cloud Native in the US Federal Government by Jez Humble at #AgileIndia2019Cloud Native in the US Federal Government by Jez Humble at #AgileIndia2019
Cloud Native in the US Federal Government by Jez Humble at #AgileIndia2019
 
Building and Scaling High Performing Technology Organizations by Jez Humble a...
Building and Scaling High Performing Technology Organizations by Jez Humble a...Building and Scaling High Performing Technology Organizations by Jez Humble a...
Building and Scaling High Performing Technology Organizations by Jez Humble a...
 
Reactive Systems by Dave Farley at #AgileIndia2019
Reactive Systems by Dave Farley at #AgileIndia2019Reactive Systems by Dave Farley at #AgileIndia2019
Reactive Systems by Dave Farley at #AgileIndia2019
 
Collaboration Contracts by Diane Zajac & Doc Norton at #AgileIndia2019
Collaboration Contracts by Diane Zajac & Doc Norton at #AgileIndia2019Collaboration Contracts by Diane Zajac & Doc Norton at #AgileIndia2019
Collaboration Contracts by Diane Zajac & Doc Norton at #AgileIndia2019
 
Tuckman was wrong by Doc Norton at #AgileIndia2019
Tuckman was wrong by Doc Norton at #AgileIndia2019Tuckman was wrong by Doc Norton at #AgileIndia2019
Tuckman was wrong by Doc Norton at #AgileIndia2019
 
7 Steps to Design, Build, and Scale an AI Product by Allie Miller at #AgileIn...
7 Steps to Design, Build, and Scale an AI Product by Allie Miller at #AgileIn...7 Steps to Design, Build, and Scale an AI Product by Allie Miller at #AgileIn...
7 Steps to Design, Build, and Scale an AI Product by Allie Miller at #AgileIn...
 

Kürzlich hochgeladen

Presentation for the Strategic Dialogue on the Future of Agriculture, Brussel...
Presentation for the Strategic Dialogue on the Future of Agriculture, Brussel...Presentation for the Strategic Dialogue on the Future of Agriculture, Brussel...
Presentation for the Strategic Dialogue on the Future of Agriculture, Brussel...Krijn Poppe
 
The Ten Facts About People With Autism Presentation
The Ten Facts About People With Autism PresentationThe Ten Facts About People With Autism Presentation
The Ten Facts About People With Autism PresentationNathan Young
 
Call Girls In Aerocity 🤳 Call Us +919599264170
Call Girls In Aerocity 🤳 Call Us +919599264170Call Girls In Aerocity 🤳 Call Us +919599264170
Call Girls In Aerocity 🤳 Call Us +919599264170Escort Service
 
Mathan flower ppt.pptx slide orchids ✨🌸
Mathan flower ppt.pptx slide orchids ✨🌸Mathan flower ppt.pptx slide orchids ✨🌸
Mathan flower ppt.pptx slide orchids ✨🌸mathanramanathan2005
 
Simulation-based Testing of Unmanned Aerial Vehicles with Aerialist
Simulation-based Testing of Unmanned Aerial Vehicles with AerialistSimulation-based Testing of Unmanned Aerial Vehicles with Aerialist
Simulation-based Testing of Unmanned Aerial Vehicles with AerialistSebastiano Panichella
 
Call Girls in Rohini Delhi 💯Call Us 🔝8264348440🔝
Call Girls in Rohini Delhi 💯Call Us 🔝8264348440🔝Call Girls in Rohini Delhi 💯Call Us 🔝8264348440🔝
Call Girls in Rohini Delhi 💯Call Us 🔝8264348440🔝soniya singh
 
Genshin Impact PPT Template by EaTemp.pptx
Genshin Impact PPT Template by EaTemp.pptxGenshin Impact PPT Template by EaTemp.pptx
Genshin Impact PPT Template by EaTemp.pptxJohnree4
 
SaaStr Workshop Wednesday w/ Kyle Norton, Owner.com
SaaStr Workshop Wednesday w/ Kyle Norton, Owner.comSaaStr Workshop Wednesday w/ Kyle Norton, Owner.com
SaaStr Workshop Wednesday w/ Kyle Norton, Owner.comsaastr
 
miladyskindiseases-200705210221 2.!!pptx
miladyskindiseases-200705210221 2.!!pptxmiladyskindiseases-200705210221 2.!!pptx
miladyskindiseases-200705210221 2.!!pptxCarrieButtitta
 
James Joyce, Dubliners and Ulysses.ppt !
James Joyce, Dubliners and Ulysses.ppt !James Joyce, Dubliners and Ulysses.ppt !
James Joyce, Dubliners and Ulysses.ppt !risocarla2016
 
PAG-UNLAD NG EKONOMIYA na dapat isaalang alang sa pag-aaral.
PAG-UNLAD NG EKONOMIYA na dapat isaalang alang sa pag-aaral.PAG-UNLAD NG EKONOMIYA na dapat isaalang alang sa pag-aaral.
PAG-UNLAD NG EKONOMIYA na dapat isaalang alang sa pag-aaral.KathleenAnnCordero2
 
Event 4 Introduction to Open Source.pptx
Event 4 Introduction to Open Source.pptxEvent 4 Introduction to Open Source.pptx
Event 4 Introduction to Open Source.pptxaryanv1753
 
call girls in delhi malviya nagar @9811711561@
call girls in delhi malviya nagar @9811711561@call girls in delhi malviya nagar @9811711561@
call girls in delhi malviya nagar @9811711561@vikas rana
 
THE COUNTRY WHO SOLVED THE WORLD_HOW CHINA LAUNCHED THE CIVILIZATION REVOLUTI...
THE COUNTRY WHO SOLVED THE WORLD_HOW CHINA LAUNCHED THE CIVILIZATION REVOLUTI...THE COUNTRY WHO SOLVED THE WORLD_HOW CHINA LAUNCHED THE CIVILIZATION REVOLUTI...
THE COUNTRY WHO SOLVED THE WORLD_HOW CHINA LAUNCHED THE CIVILIZATION REVOLUTI...漢銘 謝
 
SBFT Tool Competition 2024 -- Python Test Case Generation Track
SBFT Tool Competition 2024 -- Python Test Case Generation TrackSBFT Tool Competition 2024 -- Python Test Case Generation Track
SBFT Tool Competition 2024 -- Python Test Case Generation TrackSebastiano Panichella
 
Anne Frank A Beacon of Hope amidst darkness ppt.pptx
Anne Frank A Beacon of Hope amidst darkness ppt.pptxAnne Frank A Beacon of Hope amidst darkness ppt.pptx
Anne Frank A Beacon of Hope amidst darkness ppt.pptxnoorehahmad
 
PHYSICS PROJECT BY MSC - NANOTECHNOLOGY
PHYSICS PROJECT BY MSC  - NANOTECHNOLOGYPHYSICS PROJECT BY MSC  - NANOTECHNOLOGY
PHYSICS PROJECT BY MSC - NANOTECHNOLOGYpruthirajnayak525
 
Genesis part 2 Isaiah Scudder 04-24-2024.pptx
Genesis part 2 Isaiah Scudder 04-24-2024.pptxGenesis part 2 Isaiah Scudder 04-24-2024.pptx
Genesis part 2 Isaiah Scudder 04-24-2024.pptxFamilyWorshipCenterD
 
The 3rd Intl. Workshop on NL-based Software Engineering
The 3rd Intl. Workshop on NL-based Software EngineeringThe 3rd Intl. Workshop on NL-based Software Engineering
The 3rd Intl. Workshop on NL-based Software EngineeringSebastiano Panichella
 
Gaps, Issues and Challenges in the Implementation of Mother Tongue Based-Mult...
Gaps, Issues and Challenges in the Implementation of Mother Tongue Based-Mult...Gaps, Issues and Challenges in the Implementation of Mother Tongue Based-Mult...
Gaps, Issues and Challenges in the Implementation of Mother Tongue Based-Mult...marjmae69
 

Kürzlich hochgeladen (20)

Presentation for the Strategic Dialogue on the Future of Agriculture, Brussel...
Presentation for the Strategic Dialogue on the Future of Agriculture, Brussel...Presentation for the Strategic Dialogue on the Future of Agriculture, Brussel...
Presentation for the Strategic Dialogue on the Future of Agriculture, Brussel...
 
The Ten Facts About People With Autism Presentation
The Ten Facts About People With Autism PresentationThe Ten Facts About People With Autism Presentation
The Ten Facts About People With Autism Presentation
 
Call Girls In Aerocity 🤳 Call Us +919599264170
Call Girls In Aerocity 🤳 Call Us +919599264170Call Girls In Aerocity 🤳 Call Us +919599264170
Call Girls In Aerocity 🤳 Call Us +919599264170
 
Mathan flower ppt.pptx slide orchids ✨🌸
Mathan flower ppt.pptx slide orchids ✨🌸Mathan flower ppt.pptx slide orchids ✨🌸
Mathan flower ppt.pptx slide orchids ✨🌸
 
Simulation-based Testing of Unmanned Aerial Vehicles with Aerialist
Simulation-based Testing of Unmanned Aerial Vehicles with AerialistSimulation-based Testing of Unmanned Aerial Vehicles with Aerialist
Simulation-based Testing of Unmanned Aerial Vehicles with Aerialist
 
Call Girls in Rohini Delhi 💯Call Us 🔝8264348440🔝
Call Girls in Rohini Delhi 💯Call Us 🔝8264348440🔝Call Girls in Rohini Delhi 💯Call Us 🔝8264348440🔝
Call Girls in Rohini Delhi 💯Call Us 🔝8264348440🔝
 
Genshin Impact PPT Template by EaTemp.pptx
Genshin Impact PPT Template by EaTemp.pptxGenshin Impact PPT Template by EaTemp.pptx
Genshin Impact PPT Template by EaTemp.pptx
 
SaaStr Workshop Wednesday w/ Kyle Norton, Owner.com
SaaStr Workshop Wednesday w/ Kyle Norton, Owner.comSaaStr Workshop Wednesday w/ Kyle Norton, Owner.com
SaaStr Workshop Wednesday w/ Kyle Norton, Owner.com
 
miladyskindiseases-200705210221 2.!!pptx
miladyskindiseases-200705210221 2.!!pptxmiladyskindiseases-200705210221 2.!!pptx
miladyskindiseases-200705210221 2.!!pptx
 
James Joyce, Dubliners and Ulysses.ppt !
James Joyce, Dubliners and Ulysses.ppt !James Joyce, Dubliners and Ulysses.ppt !
James Joyce, Dubliners and Ulysses.ppt !
 
PAG-UNLAD NG EKONOMIYA na dapat isaalang alang sa pag-aaral.
PAG-UNLAD NG EKONOMIYA na dapat isaalang alang sa pag-aaral.PAG-UNLAD NG EKONOMIYA na dapat isaalang alang sa pag-aaral.
PAG-UNLAD NG EKONOMIYA na dapat isaalang alang sa pag-aaral.
 
Event 4 Introduction to Open Source.pptx
Event 4 Introduction to Open Source.pptxEvent 4 Introduction to Open Source.pptx
Event 4 Introduction to Open Source.pptx
 
call girls in delhi malviya nagar @9811711561@
call girls in delhi malviya nagar @9811711561@call girls in delhi malviya nagar @9811711561@
call girls in delhi malviya nagar @9811711561@
 
THE COUNTRY WHO SOLVED THE WORLD_HOW CHINA LAUNCHED THE CIVILIZATION REVOLUTI...
THE COUNTRY WHO SOLVED THE WORLD_HOW CHINA LAUNCHED THE CIVILIZATION REVOLUTI...THE COUNTRY WHO SOLVED THE WORLD_HOW CHINA LAUNCHED THE CIVILIZATION REVOLUTI...
THE COUNTRY WHO SOLVED THE WORLD_HOW CHINA LAUNCHED THE CIVILIZATION REVOLUTI...
 
SBFT Tool Competition 2024 -- Python Test Case Generation Track
SBFT Tool Competition 2024 -- Python Test Case Generation TrackSBFT Tool Competition 2024 -- Python Test Case Generation Track
SBFT Tool Competition 2024 -- Python Test Case Generation Track
 
Anne Frank A Beacon of Hope amidst darkness ppt.pptx
Anne Frank A Beacon of Hope amidst darkness ppt.pptxAnne Frank A Beacon of Hope amidst darkness ppt.pptx
Anne Frank A Beacon of Hope amidst darkness ppt.pptx
 
PHYSICS PROJECT BY MSC - NANOTECHNOLOGY
PHYSICS PROJECT BY MSC  - NANOTECHNOLOGYPHYSICS PROJECT BY MSC  - NANOTECHNOLOGY
PHYSICS PROJECT BY MSC - NANOTECHNOLOGY
 
Genesis part 2 Isaiah Scudder 04-24-2024.pptx
Genesis part 2 Isaiah Scudder 04-24-2024.pptxGenesis part 2 Isaiah Scudder 04-24-2024.pptx
Genesis part 2 Isaiah Scudder 04-24-2024.pptx
 
The 3rd Intl. Workshop on NL-based Software Engineering
The 3rd Intl. Workshop on NL-based Software EngineeringThe 3rd Intl. Workshop on NL-based Software Engineering
The 3rd Intl. Workshop on NL-based Software Engineering
 
Gaps, Issues and Challenges in the Implementation of Mother Tongue Based-Mult...
Gaps, Issues and Challenges in the Implementation of Mother Tongue Based-Mult...Gaps, Issues and Challenges in the Implementation of Mother Tongue Based-Mult...
Gaps, Issues and Challenges in the Implementation of Mother Tongue Based-Mult...
 

Acceptance Testing for Continuous Delivery by Dave Farley at #AgileIndia2019

  • 1. Dave Farley http://www.davefarley.net @davefarley77 http://www.continuous-delivery.co.uk (C)opyright Dave Farley 2015 Acceptance Testing for Continuous Delivery http://www.continuous-delivery.co.uk
  • 2. (C)opyright Dave Farley 2017 The Role of Acceptance Testing Local Dev. Env. Source Repository
  • 3. (C)opyright Dave Farley 2017 The Role of Acceptance Testing Artifact Repository Local Dev. Env. Deployment Pipeline Commit Production Env. Deployment App. Commit Acceptance Manual Perf1 Perf2 Staged Production Source Repository Acceptance Component Performance System Performance Staging Env. Deployment App. Manual Test Env. Deployment App.
  • 4. (C)opyright Dave Farley 2017 The Role of Acceptance Testing Artifact Repository Local Dev. Env. Deployment Pipeline Commit Production Env. Deployment App. Commit Acceptance Manual Perf1 Perf2 Staged Production Source Repository Acceptance Component Performance System Performance Staging Env. Deployment App. Manual Test Env. Deployment App. Staging Env. Deployment App. Manual Test Env. Deployment App. Component Performance System Performance Acceptance
  • 5. (C)opyright Dave Farley 2017 The Role of Acceptance Testing Artifact Repository Local Dev. Env. Deployment Pipeline Commit Production Env. Deployment App. Commit Acceptance Manual Perf1 Perf2 Staged Production Source Repository Acceptance Component Performance System Performance Staging Env. Deployment App. Manual Test Env. Deployment App. Staging Env. Deployment App. Manual Test Env. Deployment App. Component Performance System Performance Acceptance
  • 6. What is Acceptance Testing? Asserts that the code does what the users want.
  • 7. What is Acceptance Testing? An automated “definition of done”
  • 8. What is Acceptance Testing? Asserts that the code works in a “production-like” test environment.
  • 9. What is Acceptance Testing? A test of the deployment and configuration of a whole system.
  • 10. What is Acceptance Testing? Provides timely feedback on stories - closes a feedback loop.
  • 11. What is Acceptance Testing? Acceptance Testing, ATDD, BDD, Specification by Example, Executable Specifications.
  • 12. (C)opyright Dave Farley 2017 What is Acceptance Testing? A Good Acceptance Test is: An Executable Specification of the Behaviour of the System
  • 13. (C)opyright Dave Farley 2017 What is Acceptance Testing? Unit Test CodeIdea Executable spec. Build Release
  • 14. (C)opyright Dave Farley 2017 What is Acceptance Testing? Unit Test CodeIdea Executable spec. Build Release
  • 15. (C)opyright Dave Farley 2017 What is Acceptance Testing? Unit Test CodeIdea Executable spec. Build Release
  • 16. (C)opyright Dave Farley 2017 The Problem: There is often a disconnect between what users want of a system and what the software delivers.
  • 17. (C)opyright Dave Farley 2017 The Problem: There is often a disconnect between what users want of a system and what the software delivers.
  • 18. (C)opyright Dave Farley 2017 The Problem: Identifying user-need and designing a solution are two VERY difficult problems Let’s Try to NOT solve both at the same time!
  • 19. (C)opyright Dave Farley 2017 The Problem: Identifying user-need and designing a solution are two VERY difficult problems Let’s Try to NOT solve both at the same time!
  • 20. (C)opyright Dave Farley 2017 The Problem: In Most Orgs, Functional Testing is Manual
  • 21. (C)opyright Dave Farley 2017 The Problem: In Most Orgs, Functional Testing is Manual
  • 22. (C)opyright Dave Farley 2017 The Problem: In Most Orgs, Functional Testing is Manual
  • 23. (C)opyright Dave Farley 2017 The Problem: In Most Orgs, Functional Testing is Manual Slow, Low-Quality, Expensive, Unreliable, Error Prone, Fragile, Results Hard to Understand, …
  • 24. (C)opyright Dave Farley 2017 The Problem: Automated Functional Tests Often Tightly- Coupled To SUT
  • 25. (C)opyright Dave Farley 2017 The Problem: Automated Functional Tests Often Tightly- Coupled To SUT
  • 26. (C)opyright Dave Farley 2017 The Problem: Automated Functional Tests Often Tightly- Coupled To SUT Slow to Develop, Low-Quality, Expensive, Unreliable, Error Prone, Fragile, …
  • 27. (C)opyright Dave Farley 2017 The Problem: So if there is a disconnect, how can we bridge that gap?
  • 28. (C)opyright Dave Farley 2017 The Problem: So if there is a disconnect, how can we bridge that gap?
  • 29. (C)opyright Dave Farley 2017 The Solution: Establish a common shared language for expressing a user’s need
  • 30. (C)opyright Dave Farley 2017 The Solution: Establish a common shared language for expressing a user’s need
  • 31. (C)opyright Dave Farley 2017 Technique: Always capture any requirement from the perspective of “an external user of the system”
  • 32. (C)opyright Dave Farley 2017 Technique: Always capture any requirement from the perspective of “an external user of the system”
  • 33. (C)opyright Dave Farley 2017 Technique: Avoid ANY reference to HOW the system works
  • 34. (C)opyright Dave Farley 2017 Technique: Avoid ANY reference to HOW the system works
  • 35. (C)opyright Dave Farley 2017 Technique: Focus on WHAT the user wants of the system
  • 36. (C)opyright Dave Farley 2017 Technique: Focus on WHAT the user wants of the system
  • 37. (C)opyright Dave Farley 2017 Technique: Link Executable Specs to User Stories
  • 38. (C)opyright Dave Farley 2017 Technique: Link Executable Specs to User Stories
  • 39. (C)opyright Dave Farley 2017 123 Some Story S As a user I want some behaviour so that I can achieve some benefit Acceptance Criteria Story Templates ▪ A result that will indicate that the benefit is achieved ▪ Another result to confirm the benefit
  • 40. (C)opyright Dave Farley 2017 123 Some Story S As a user I want some behaviour so that I can achieve some benefit Acceptance Criteria Story Templates ▪ A result that will indicate that the benefit is achieved ▪ Another result to confirm the benefit Test Case 1a..n
  • 41. (C)opyright Dave Farley 2017 123 Some Story S As a user I want some behaviour so that I can achieve some benefit Acceptance Criteria Story Templates ▪ A result that will indicate that the benefit is achieved ▪ Another result to confirm the benefit Test Case 1a..n Test Case 2a..n
  • 42. (C)opyright Dave Farley 2017 Technique: Make the Team’s “Definition of Done” = Minimum of 1 Acceptance Test for each Acceptance Criteria
  • 43. (C)opyright Dave Farley 2017 Technique: Make the Team’s “Definition of Done” = Minimum of 1 Acceptance Test for each Acceptance Criteria
  • 44. (C)opyright Dave Farley 2017 Technique: Imagine the least technical person, who understands the problem domain, reading the spec - It should make sense to them!
  • 45. (C)opyright Dave Farley 2017 Technique: Imagine the least technical person, who understands the problem domain, reading the spec - It should make sense to them!
  • 46. (C)opyright Dave Farley 2017 Technique: Avoid “Technical Stories”, Always find the fundamental User need
  • 47. (C)opyright Dave Farley 2017 Technique: Avoid “Technical Stories”, Always find the fundamental User need
  • 48. (C)opyright Dave Farley 2017 Technique: Make each story, each specification as small as possible
  • 49. (C)opyright Dave Farley 2017 Technique: Make each story, each specification as small as possible Small is Good!
  • 50. (C)opyright Dave Farley 2015 So What’s So Hard? • Tests break when the SUT changes (Particularly UI) • This is a problem of design, the tests are too tightly-coupled to the SUT! • The history is littered with poor implementations: • UI Record-and-playback Systems • Record-and-playback of production data • Dumps of production data to test systems • Nasty automated testing products.
  • 51. (C)opyright Dave Farley 2015 So What’s So Hard? • Tests break when the SUT changes (Particularly UI) • This is a problem of design, the tests are too tightly-coupled to the SUT! • The history is littered with poor implementations: • UI Record-and-playback Systems • Record-and-playback of production data • Dumps of production data to test systems • Nasty automated testing products. Anti-Pattern! Anti-Pattern! Anti-Pattern! Anti-Pattern!
  • 52. (C)opyright Dave Farley 2015 Who Owns the Tests? • Anyone can write a test • Developers are the people that will break tests • Therefore Developers own the responsibility to keep them working • Separate Testing/QA team owning automated tests
  • 53. (C)opyright Dave Farley 2015 Who Owns the Tests? • Anyone can write a test • Developers are the people that will break tests • Therefore Developers own the responsibility to keep them working • Separate Testing/QA team owning automated tests Anti-Pattern!
  • 54. (C)opyright Dave Farley 2015 Who Owns the Tests? Developers Own Acceptance Tests!
  • 55. (C)opyright Dave Farley 2015 Properties of Good Acceptance Tests • “What” not “How” • Isolated from other tests • Repeatable • Uses the language of the problem domain • Tests ANY change • Efficient
  • 56. (C)opyright Dave Farley 2015 Properties of Good Acceptance Tests • “What” not “How” • Isolated from other tests • Repeatable • Uses the language of the problem domain • Tests ANY change • Efficient
  • 57. (C)opyright Dave Farley 2015 Public API FIX API Trade Reporting Gateway … “What” not “How” API Traders Clearing Destination Other external end-points Market Makers UI Traders
  • 58. (C)opyright Dave Farley 2015 Public API FIX API Trade Reporting Gateway … “What” not “How” Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case
  • 59. (C)opyright Dave Farley 2015 Public API FIX API Trade Reporting Gateway …FIX API “What” not “How” Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case
  • 60. (C)opyright Dave Farley 2015 Public API FIX API Trade Reporting Gateway … “What” not “How” API Traders Clearing Destination Other external end-points Market Makers UI Traders Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case
  • 61. (C)opyright Dave Farley 2015 Public API FIX API Trade Reporting Gateway … “What” not “How” FIX API Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case API External Stubs FIX-APIUI FIX-APIFIX-API Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case
  • 62. (C)opyright Dave Farley 2015 Public API FIX API Trade Reporting Gateway … “What” not “How” FIX API Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case API External Stubs FIX-APIUI FIX-API
  • 63. (C)opyright Dave Farley 2015 Public API FIX API Trade Reporting Gateway … “What” not “How” Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case Test Case API External Stubs FIX-APIUI FIX-API
  • 64. (C)opyright Dave Farley 2015 Public API FIX API Trade Reporting Gateway … “What” not “How” API External Stubs FIX-APIUI FIX-API Test infrastructure common to all acceptance tests
  • 65. (C)opyright Dave Farley 2015 “What” not “How” - Separate Deployment from Testing • Every Test should control its start conditions, and so should start and init the app. • Acceptance Test deployment should be a rehearsal for Production Release • This separation of concerns provides an opportunity for optimisation • Parallel tests in a shared environment • Lower test start-up overhead
  • 66. (C)opyright Dave Farley 2015 “What” not “How” - Separate Deployment from Testing • Every Test should control its start conditions, and so should start and init the app. • Acceptance Test deployment should be a rehearsal for Production Release • This separation of concerns provides an opportunity for optimisation • Parallel tests in a shared environment • Lower test start-up overhead Anti-Pattern!
  • 67. (C)opyright Dave Farley 2015 Properties of Good Acceptance Tests • “What” not “How” • Isolated from other tests • Repeatable • Uses the language of the problem domain • Tests ANY change • Efficient
  • 68. (C)opyright Dave Farley 2015 Properties of Good Acceptance Tests • “What” not “How” • Isolated from other tests • Repeatable • Uses the language of the problem domain • Tests ANY change • Efficient
  • 69. (C)opyright Dave Farley 2015 Test Isolation • Any form of testing is about evaluating something in controlled circumstances • Isolation works on multiple levels • Isolating the System under test • Isolating test cases from each other • Isolating test cases from themselves (temporal isolation) • Isolation is a vital part of your Test Strategy
  • 70. (C)opyright Dave Farley 2015 Test Isolation - Isolating the System Under Test
  • 71. (C)opyright Dave Farley 2015 Test Isolation - Isolating the System Under Test External System ‘A’ External System ‘C’ System Under Test ‘B’
  • 72. (C)opyright Dave Farley 2015 Test Isolation - Isolating the System Under Test External System ‘A’ External System ‘C’ System Under Test ‘B’
  • 73. (C)opyright Dave Farley 2015 Test Isolation - Isolating the System Under Test External System ‘A’ External System ‘C’ System Under Test ‘B’
  • 74. (C)opyright Dave Farley 2015 Test Isolation - Isolating the System Under Test External System ‘A’ External System ‘C’ System Under Test ‘B’ ?
  • 75. (C)opyright Dave Farley 2015 Test Isolation - Isolating the System Under Test External System ‘A’ External System ‘C’ System Under Test ‘B’Anti-Pattern!
  • 76. (C)opyright Dave Farley 2015 Test Isolation - Isolating the System Under Test System Under Test ‘B’ Test Cases Verifiable Output
  • 77. (C)opyright Dave Farley 2015 Test Isolation - Validating The Interfaces
  • 78. (C)opyright Dave Farley 2015 Test Isolation - Validating The Interfaces External System ‘A’ External System ‘C’ System Under Test ‘B’
  • 79. (C)opyright Dave Farley 2015 Test Isolation - Validating The Interfaces External System ‘A’ External System ‘C’ System Under Test ‘B’
  • 80. (C)opyright Dave Farley 2015 Test Isolation - Validating The Interfaces External System ‘A’ External System ‘C’ Test Cases Verifiable Output System Under Test ‘B’ Test Cases Verifiable Output Test Cases Verifiable Output
  • 81. (C)opyright Dave Farley 2015 Test Isolation - Validating The Interfaces External System ‘A’ External System ‘C’ Test Cases Verifiable Output System Under Test ‘B’ Test Cases Verifiable Output Test Cases Verifiable Output
  • 82. (C)opyright Dave Farley 2015 Test Isolation - Isolating Test Cases (Assuming multi-user systems…) • Tests should be efficient - We want to run LOTS! • What we really want is to deploy once, and run LOTS of tests • So we must avoid ANY dependencies between tests… • Use natural functional isolation e.g. • If testing Amazon, create a new account and a new book/product for every test-case • If testing eBay create a new account and a new auction for every test- case • If testing GitHub, create a new account and a new repository for every test-case • …
  • 83. (C)opyright Dave Farley 2015 • We want repeatable results • If I run my test-case twice it should work both times Test Isolation - Temporal Isolation
  • 84. (C)opyright Dave Farley 2015 • We want repeatable results • If I run my test-case twice it should work both times Test Isolation - Temporal Isolation def test_should_place_an_order(self): self.store.createBook(“Continuous Delivery”); order = self.store.placeOrder(book=“Continuous Delivery") self.store.assertOrderPlaced(order)
  • 85. (C)opyright Dave Farley 2015 • We want repeatable results • If I run my test-case twice it should work both times Test Isolation - Temporal Isolation def test_should_place_an_order(self): self.store.createBook(“Continuous Delivery”); order = self.store.placeOrder(book=“Continuous Delivery") self.store.assertOrderPlaced(order)
  • 86. (C)opyright Dave Farley 2015 • We want repeatable results • If I run my test-case twice it should work both times Test Isolation - Temporal Isolation def test_should_place_an_order(self): self.store.createBook(“Continuous Delivery”); order = self.store.placeOrder(book=“Continuous Delivery") self.store.assertOrderPlaced(order)
  • 87. (C)opyright Dave Farley 2015 • We want repeatable results • If I run my test-case twice it should work both times Test Isolation - Temporal Isolation def test_should_place_an_order(self): self.store.createBook(“Continuous Delivery”); order = self.store.placeOrder(book=“Continuous Delivery") self.store.assertOrderPlaced(order) Continuous Delivery
  • 88. (C)opyright Dave Farley 2015 • We want repeatable results • If I run my test-case twice it should work both times Test Isolation - Temporal Isolation def test_should_place_an_order(self): self.store.createBook(“Continuous Delivery”); order = self.store.placeOrder(book=“Continuous Delivery") self.store.assertOrderPlaced(order) Continuous Delivery
  • 89. (C)opyright Dave Farley 2015 • We want repeatable results • If I run my test-case twice it should work both times Test Isolation - Temporal Isolation def test_should_place_an_order(self): self.store.createBook(“Continuous Delivery”); order = self.store.placeOrder(book=“Continuous Delivery") self.store.assertOrderPlaced(order) Continuous Delivery1234
  • 90. (C)opyright Dave Farley 2015 • We want repeatable results • If I run my test-case twice it should work both times Test Isolation - Temporal Isolation def test_should_place_an_order(self): self.store.createBook(“Continuous Delivery”); order = self.store.placeOrder(book=“Continuous Delivery") self.store.assertOrderPlaced(order) Continuous Delivery1234 Continuous Delivery6789
  • 91. (C)opyright Dave Farley 2015 • We want repeatable results • If I run my test-case twice it should work both times Test Isolation - Temporal Isolation def test_should_place_an_order(self): self.store.createBook(“Continuous Delivery”); order = self.store.placeOrder(book=“Continuous Delivery") self.store.assertOrderPlaced(order) Continuous Delivery1234 Continuous Delivery6789 • Alias your functional isolation entities • In your test case create account ‘Dave’ in reality the in the test infrastructure ask the application to create account ‘Dave2938472398472’ and alias.
  • 92. (C)opyright Dave Farley 2015 Properties of Good Acceptance Tests • “What” not “How” • Isolated from other tests • Repeatable • Uses the language of the problem domain • Tests ANY change • Efficient
  • 93. (C)opyright Dave Farley 2015 Properties of Good Acceptance Tests • “What” not “How” • Isolated from other tests • Repeatable • Uses the language of the problem domain • Tests ANY change • Efficient
  • 94. (C)opyright Dave Farley 2015 Repeatability - Test Doubles External System
  • 95. (C)opyright Dave Farley 2015 Repeatability - Test Doubles External System Local Interface to External System
  • 96. (C)opyright Dave Farley 2015 Repeatability - Test Doubles External System Local Interface to External System Communications to External System
  • 97. (C)opyright Dave Farley 2015 Repeatability - Test Doubles External System Local Interface to External System Communications to External System TestStub Simulating External System Local Interface to External System
  • 98. (C)opyright Dave Farley 2015 Repeatability - Test Doubles External System Local Interface to External System Communications to External System TestStub Simulating External System Local Interface to External System Production Test Environm ent kjhaskjhdkjhkjh askjhl lkjasl dkjas lkajl ajsd lkjalskjlakjsdlkajsld j lkajsdlkajsldkj lkjlakjsldkjlka laskj ljl akjl kajsldijupoqwiuepoq dlkjl iu lkajsodiuqpwouoi la ]laksjdiuqoiwuoijds oijasodiaosidjuoiasud kjhaskjhdkjhkjh askjhl lkjasl dkjas lkajl ajsd lkjalskjlakjsdlkajsld j lkajsdlkajsldkj lkjlakjsldkjlka laskj ljl akjl kajsldijupoqwiuepoq dlkjl iu lkajsodiuqpwouoi la ]laksjdiuqoiwuoijds oijasodiaosidjuoiasud Configuration
  • 99. (C)opyright Dave Farley 2015 Test Doubles As Part of Test Infrastructure TestStub Simulating External System Local Interface to External System
  • 100. (C)opyright Dave Farley 2015 Test Doubles As Part of Test Infrastructure TestStub Simulating External System Local Interface to External System
  • 101. (C)opyright Dave Farley 2015 Test Doubles As Part of Test Infrastructure TestStub Simulating External System Local Interface to External System Public Interface
  • 102. (C)opyright Dave Farley 2015 Test Doubles As Part of Test Infrastructure TestStub Simulating External System Local Interface to External System Public Interface
  • 103. (C)opyright Dave Farley 2015 Test Doubles As Part of Test Infrastructure TestStub Simulating External System Local Interface to External System Test Infrastructure Test Case Test Case Test Case Test Case Test Infrastructure Back-Channel Public Interface System UnderTest
  • 104. (C)opyright Dave Farley 2015 Properties of Good Acceptance Tests • “What” not “How” • Isolated from other tests • Repeatable • Uses the language of the problem domain • Tests ANY change • Efficient
  • 105. (C)opyright Dave Farley 2015 Properties of Good Acceptance Tests • “What” not “How” • Isolated from other tests • Repeatable • Uses the language of the problem domain • Tests ANY change • Efficient
  • 106. (C)opyright Dave Farley 2015 Language of the Problem Domain - DSL • A Simple ‘DSL’ Solves many of our problems • Ease of TestCase creation • Readability • Ease of Maintenance • Separation of “What” from “How” • Test Isolation • The Chance to abstract complex set-up and scenarios • …
  • 107. (C)opyright Dave Farley 2015 Language of the Problem Domain - DSL • A Simple ‘DSL’ Solves many of our problems • Ease of TestCase creation • Readability • Ease of Maintenance • Separation of “What” from “How” • Test Isolation • The Chance to abstract complex set-up and scenarios • … BDD Behaviour Driven Development
  • 108. (C)opyright Dave Farley 2015 Language of the Problem Domain - External DSL ThoughtWorks’ TWIST |eg.Division| |numerator|denominator|quotient?| |10 |2 |5 | |12.6 |3 |4.2 | |100 |4 |33 | FITnesse Narrative: In order to communicate effectively to the business some functionality As a development team I want to use Behaviour-Driven Development Lifecycle: Before: Given a step that is executed before each scenario After: Outcome: ANY Given a step that is executed after each scenario regardless of outcome Outcome: SUCCESS Given a step that is executed after each successful scenario Outcome: FAILURE Given a step that is executed after each failed scenario Scenario: A scenario is a collection of executable steps of different type Given step represents a precondition to an event When step represents the occurrence of the event Then step represents the outcome of the event Examples: |precondition|be-captured| |abc|be captured | |xyz|not be captured| JBehave Cucumber - Gherkin
  • 109. (C)opyright Dave Farley 2015 Language of the Problem Domain - Internal DSL EasyB - Groovy given "an invalid zip code", { invalidzipcode = "221o1" } and "given the zipcodevalidator is initialized", { zipvalidate = new ZipCodeValidator() } when "validate is invoked with the invalid zip code", { value = zipvalidate.validate(invalidzipcode) } then "the validator instance should return false", { value.shouldBe false } My Homebrew - Java @Channel(fixApi, dealTicket, publicApi) @Test public void shouldSuccessfullyPlaceAnImmediateOrCancelBuyMarketOrder() { trading.placeOrder("instrument", "side: buy", “price: 123.45”, "quantity: 4", "goodUntil: Immediate”); trading.waitForExecutionReport("executionType: Fill", "orderStatus: Filled", "side: buy", "quantity: 4", "matched: 4", "remaining: 0", "executionPrice: 123.45", "executionQuantity: 4"); } My Homebrew - Pythonfrom acceptance_test_dsl.acc_test_dsl import AccTestDsl class PlaceOrderTest(AccTestDsl): def setUp(self): AccTestDsl.setUp(self) self.add_channel("TRADING") self.add_end_point("MQ") def test_should_successfully_place_market_order(self): order = self.trading.placeOrder(symbol="ZVZZT", orderType="Market", qty=300, TimeInForce='IOC') self.trading.assertOrderPlaced(order)
  • 110. (C)opyright Dave Farley 2015 Language of the Problem Domain - DSL @Test public void shouldSupportPlacingValidBuyAndSellLimitOrders() { trading.selectDealTicket("instrument"); trading.dealTicket.placeOrder("type: limit", ”bid: 4@10”); trading.dealTicket.checkFeedbackMessage("You have successfully sent a limit order to buy 4.00 contracts at 10.0"); trading.dealTicket.dismissFeedbackMessage(); trading.dealTicket.placeOrder("type: limit", ”ask: 4@9”); trading.dealTicket.checkFeedbackMessage("You have successfully sent a limit order to sell 4.00 contracts at 9.0"); }
  • 111. (C)opyright Dave Farley 2015 Language of the Problem Domain - DSL @Test public void shouldSupportPlacingValidBuyAndSellLimitOrders() { trading.selectDealTicket("instrument"); trading.dealTicket.placeOrder("type: limit", ”bid: 4@10”); trading.dealTicket.checkFeedbackMessage("You have successfully sent a limit order to buy 4.00 contracts at 10.0"); trading.dealTicket.dismissFeedbackMessage(); trading.dealTicket.placeOrder("type: limit", ”ask: 4@9”); trading.dealTicket.checkFeedbackMessage("You have successfully sent a limit order to sell 4.00 contracts at 9.0"); } @Test public void shouldSuccessfullyPlaceAnImmediateOrCancelBuyMarketOrder() { fixAPIMarketMaker.placeMassOrder("instrument", "ask: 11@52", "ask: 10@51", "ask: 10@50", "bid: 10@49"); fixAPI.placeOrder("instrument", "side: buy", "quantity: 4", "goodUntil: Immediate", "allowUnmatched: true"); fixAPI.waitForExecutionReport("executionType: Fill", "orderStatus: Filled", "side: buy", "quantity: 4", "matched: 4", "remaining: 0", "executionPrice: 50", "executionQuantity: 4"); }
  • 112. (C)opyright Dave Farley 2015 Language of the Problem Domain - DSL @Test public void shouldSupportPlacingValidBuyAndSellLimitOrders() { trading.selectDealTicket("instrument"); trading.dealTicket.placeOrder("type: limit", ”bid: 4@10”); trading.dealTicket.checkFeedbackMessage("You have successfully sent a limit order to buy 4.00 contracts at 10.0"); trading.dealTicket.dismissFeedbackMessage(); trading.dealTicket.placeOrder("type: limit", ”ask: 4@9”); trading.dealTicket.checkFeedbackMessage("You have successfully sent a limit order to sell 4.00 contracts at 9.0"); } @Test public void shouldSuccessfullyPlaceAnImmediateOrCancelBuyMarketOrder() { fixAPIMarketMaker.placeMassOrder("instrument", "ask: 11@52", "ask: 10@51", "ask: 10@50", "bid: 10@49"); fixAPI.placeOrder("instrument", "side: buy", "quantity: 4", "goodUntil: Immediate", "allowUnmatched: true"); fixAPI.waitForExecutionReport("executionType: Fill", "orderStatus: Filled", "side: buy", "quantity: 4", "matched: 4", "remaining: 0", "executionPrice: 50", "executionQuantity: 4"); } @Before public void beforeEveryTest() { adminAPI.createInstrument("name: instrument"); registrationAPI.createUser("user"); registrationAPI.createUser("marketMaker", "accountType: MARKET_MAKER"); tradingUI.loginAsLive("user"); }
  • 113. (C)opyright Dave Farley 2015 Language of the Problem Domain - DSL public void placeOrder(final String... args) { final DslParams params = new DslParams(args, new OptionalParam("type").setDefault("Limit").setAllowedValues("limit", "market", "StopMarket new OptionalParam("side").setDefault("Buy").setAllowedValues("buy", "sell"), new OptionalParam("price"), new OptionalParam("triggerPrice"), new OptionalParam("quantity"), new OptionalParam("stopProfitOffset"), new OptionalParam("stopLossOffset"), new OptionalParam("confirmFeedback").setDefault("true")); getDealTicketPageDriver().placeOrder(params.value("type"), params.value("side"), params.value("price"), params.value("triggerPrice"), params.value("quantity"), params.value("stopProfitOffset"), params.value("stopLossOffset")); if (params.valueAsBoolean("confirmFeedback")) { getDealTicketPageDriver().clickOrderFeedbackConfirmationButton(); } LOGGER.debug("placeOrder(" + Arrays.deepToString(args) + ")"); }
  • 114. (C)opyright Dave Farley 2015 Language of the Problem Domain - DSL public void placeOrder(final String... args) { final DslParams params = new DslParams(args, new RequiredParam("instrument"), new OptionalParam("clientOrderId"), new OptionalParam("order"), new OptionalParam("side").setAllowedValues("buy", "sell"), new OptionalParam("orderType").setAllowedValues("market", "limit"), new OptionalParam("price"), new OptionalParam("bid"), new OptionalParam("ask"), new OptionalParam("symbol").setDefault("BARC"), new OptionalParam("quantity"), new OptionalParam("goodUntil").setAllowedValues("Immediate", "Cancelled").setDefault("Cancelled"), new OptionalParam("allowUnmatched").setAllowedValues("true", "false").setDefault("true"), new OptionalParam("possibleResend").setAllowedValues("true", "false").setDefault("false"), new OptionalParam("unauthorised").setAllowedValues("true"), new OptionalParam("brokeredAccountId"), new OptionalParam("msgSeqNum"), new OptionalParam("orderCapacity").setAllowedValues("AGENCY", "PRINCIPAL", "").setDefault("PRINCIPA new OptionalParam("accountType").setAllowedValues("CUSTOMER", "HOUSE", "").setDefault("HOUSE"), new OptionalParam("accountClearingReference"), new OptionalParam("expectedOrderRejectionStatus").setAllowedValues("TOO_LATE_TO_ENTER", "BROKER_EXCHANGE_OPTION", "UNKNOWN_SYMBOL", "DUPLICATE_ORDER"), new OptionalParam("expectedOrderRejectionReason").setAllowedValues("INSUFFICIENT_LIQUIDITY", "INSTRUMENT_NOT_OPEN", "INSTRUMENT_DOES_NOT_EXIST", "DUPLICATE_ORDER", "QUANTITY_NOT_VALID", "PRICE_NOT_VALID", "INVALID_ORDER_INSTRUCTION", "OUTSIDE_VOLATILITY_BAND", "INVALID_INSTRUMENT_SYMBOL", "ACCESS_DENIED", "INSTRUMENT_SUSPENDED"), new OptionalParam("expectedSessionRejectionReason").setAllowedValues("INVALID_TAG_NUMBER", “REQUIRED_TAG_MISSING", …
  • 115. (C)opyright Dave Farley 2015 Language of the Problem Domain - DSL @Test public void shouldSupportPlacingValidBuyAndSellLimitOrders() { tradingUI.showDealTicket("instrument"); tradingUI.dealTicket.placeOrder("type: limit", ”bid: 4@10”); tradingUI.dealTicket.checkFeedbackMessage("You have successfully sent a limit order to buy 4.00 contracts at tradingUI.dealTicket.dismissFeedbackMessage(); tradingUI.dealTicket.placeOrder("type: limit", ”ask: 4@9”); tradingUI.dealTicket.checkFeedbackMessage("You have successfully sent a limit order to sell 4.00 contracts at } @Test public void shouldSuccessfullyPlaceAnImmediateOrCancelBuyMarketOrder() { fixAPIMarketMaker.placeMassOrder("instrument", "ask: 11@52", "ask: 10@51", "ask: 10@50", "bid: 10@49"); fixAPI.placeOrder("instrument", "side: buy", "quantity: 4", "goodUntil: Immediate", "allowUnmatched: true"); fixAPI.waitForExecutionReport("executionType: Fill", "orderStatus: Filled", "side: buy", "quantity: 4", "matched: 4", "remaining: 0", "executionPrice: 50", "executionQuantity: 4"); }
  • 116. (C)opyright Dave Farley 2015 Language of the Problem Domain - DSL @Test public void shouldSupportPlacingValidBuyAndSellLimitOrders() { tradingUI.showDealTicket("instrument"); tradingUI.dealTicket.placeOrder("type: limit", ”bid: 4@10”); tradingUI.dealTicket.checkFeedbackMessage("You have successfully sent a limit order to buy 4.00 contracts at tradingUI.dealTicket.dismissFeedbackMessage(); tradingUI.dealTicket.placeOrder("type: limit", ”ask: 4@9”); tradingUI.dealTicket.checkFeedbackMessage("You have successfully sent a limit order to sell 4.00 contracts at } @Test public void shouldSuccessfullyPlaceAnImmediateOrCancelBuyMarketOrder() { fixAPIMarketMaker.placeMassOrder("instrument", "ask: 11@52", "ask: 10@51", "ask: 10@50", "bid: 10@49"); fixAPI.placeOrder("instrument", "side: buy", "quantity: 4", "goodUntil: Immediate", "allowUnmatched: true"); fixAPI.waitForExecutionReport("executionType: Fill", "orderStatus: Filled", "side: buy", "quantity: 4", "matched: 4", "remaining: 0", "executionPrice: 50", "executionQuantity: 4"); }
  • 117. (C)opyright Dave Farley 2015 Language of the Problem Domain - DSL @Channel(fixApi, dealTicket, publicApi) @Test public void shouldSuccessfullyPlaceAnImmediateOrCancelBuyMarketOrder() { trading.placeOrder("instrument", "side: buy", “price: 123.45”, "quantity: 4", "goodUntil: Immediate”); trading.waitForExecutionReport("executionType: Fill", "orderStatus: Filled", "side: buy", "quantity: 4", "matched: 4", "remaining: 0", "executionPrice: 123.45", "executionQuantity: 4"); }
  • 118. (C)opyright Dave Farley 2015 Language of the Problem Domain - DSL @Channel(fixApi, dealTicket, publicApi) @Test public void shouldSuccessfullyPlaceAnImmediateOrCancelBuyMarketOrder() { trading.placeOrder("instrument", "side: buy", “price: 123.45”, "quantity: 4", "goodUntil: Immediate”); trading.waitForExecutionReport("executionType: Fill", "orderStatus: Filled", "side: buy", "quantity: 4", "matched: 4", "remaining: 0", "executionPrice: 123.45", "executionQuantity: 4"); }
  • 119. (C)opyright Dave Farley 2015 Language of the Problem Domain - Evolving a DSL • Write the test case first • Whoever would normally write the case specifies the language to express the idea • Get a Developer to implement the DSL to support the new test case • It’s OK for the Dev to refine the language to make it cleaner, more general - but keep it simple! • Devs should keeping pushing the DSL to be clean of ANY understanding of the “How” • Think of this as designing a language. Have some rules about what should be in and what should not.
  • 120. (C)opyright Dave Farley 2015 DSL- Four Layer Structure
  • 121. (C)opyright Dave Farley 2015 DSL- Four Layer Structure Test Case (Executable Specification) Test Case (Executable Specification) Test Case (Executable Specification) Test Case (Executable Specification)
  • 122. (C)opyright Dave Farley 2015 DSL- Four Layer Structure Domain Specific Language Test Case (Executable Specification) Test Case (Executable Specification) Test Case (Executable Specification) Test Case (Executable Specification)
  • 123. (C)opyright Dave Farley 2015 DSL- Four Layer Structure Domain Specific Language Test Case (Executable Specification) Test Case (Executable Specification) Test Case (Executable Specification) Test Case (Executable Specification) Protocol Driver (e.g. UI) Protocol Driver (e.g. API) External System Stub External System Stub
  • 124. (C)opyright Dave Farley 2015 DSL- Four Layer Structure Domain Specific Language Test Case (Executable Specification) Test Case (Executable Specification) Test Case (Executable Specification) Test Case (Executable Specification) Protocol Driver (e.g. UI) System Under Test Protocol Driver (e.g. API) External System Stub External System Stub
  • 125. (C)opyright Dave Farley 2015 Properties of Good Acceptance Tests • “What” not “How” • Isolated from other tests • Repeatable • Uses the language of the problem domain • Tests ANY change • Efficient
  • 126. (C)opyright Dave Farley 2015 Properties of Good Acceptance Tests • “What” not “How” • Isolated from other tests • Repeatable • Uses the language of the problem domain • Tests ANY change • Efficient
  • 127. (C)opyright Dave Farley 2015 Testing with Time • Test Cases should be deterministic • Time is a problem for determinism - There are two options: • Ignore time • Control time
  • 128. (C)opyright Dave Farley 2015 Testing With Time - Ignore Time Mechanism Filter out time-based values in your test infrastructure so that they are ignored Pros: • Simple! Cons: • Can miss errors • Prevents any hope of testing complex time-based scenarios
  • 129. (C)opyright Dave Farley 2015 Mechanism Treat Time as an external dependency, like an external system - and Fake it! Pros: • Very Flexible! • Can simulate any time-based scenario, with time under the control of the test case. Cons: • Slightly more complex infrastructure Testing With Time - Controlling Time
  • 130. (C)opyright Dave Farley 2015 Testing With Time - Controlling Time @Test public void shouldBeOverdueAfterOneMonth() { book = library.borrowBook(“Continuous Delivery”); assertFalse(book.isOverdue()); time.travel(“+1 week”); assertFalse(book.isOverdue()); time.travel(“+4 weeks”); assertTrue(book.isOverdue()); }
  • 131. (C)opyright Dave Farley 2015 Testing With Time - Controlling Time @Test public void shouldBeOverdueAfterOneMonth() { book = library.borrowBook(“Continuous Delivery”); assertFalse(book.isOverdue()); time.travel(“+1 week”); assertFalse(book.isOverdue()); time.travel(“+4 weeks”); assertTrue(book.isOverdue()); }
  • 132. (C)opyright Dave Farley 2015 Testing With Time - Controlling Time
  • 133. (C)opyright Dave Farley 2015 Testing With Time - Controlling Time Test Infrastructure Test Case Test Case Test Case Test Case System UnderTest public void someTimeDependentMethod() { time = System.getTime(); } System UnderTest
  • 134. (C)opyright Dave Farley 2015 Testing With Time - Controlling Time Test Infrastructure Test Case Test Case Test Case Test Case System UnderTest include Clock; public void someTimeDependentMethod() { time = Clock.getTime(); } System UnderTest
  • 135. (C)opyright Dave Farley 2015 Testing With Time - Controlling Time Test Infrastructure Test Case Test Case Test Case Test Case System UnderTest include Clock; public void someTimeDependentMethod() { time = Clock.getTime(); } public class Clock { public static clock = new SystemClock(); public static void setTime(long newTime) { clock.setTime(newTime); } public static long getTime() { return clock.getTime(); } System UnderTest
  • 136. (C)opyright Dave Farley 2015 Testing With Time - Controlling Time Test Infrastructure Test Case Test Case Test Case Test Case System UnderTest include Clock; public void someTimeDependentMethod() { time = Clock.getTime(); } public void onInit() { // Remote Call - back-channel systemUnderTest.setClock(new TestClock()); } public void time-travel(String time) { long newTime = parseTime(time); // Remote Call - back-channel systemUnderTest.setTime(newTime); } Test Infrastructure Back-Channel public class Clock { public static clock = new SystemClock(); public static void setTime(long newTime) { clock.setTime(newTime); } public static long getTime() { return clock.getTime(); } System UnderTest
  • 137. (C)opyright Dave Farley 2015 Test Environment Types • Some Tests need special treatment. • Tag Tests with properties and allocate them dynamically:
  • 138. (C)opyright Dave Farley 2015 Test Environment Types • Some Tests need special treatment. • Tag Tests with properties and allocate them dynamically: @TimeTravel @Test public void shouldDoSomethingThatNeedsFakeTime() … @Destructive @Test public void shouldDoSomethingThatKillsPartOfTheSystem() … @FPGA(version=1.3) @Test public void shouldDoSomethingThatRequiresSpecificHardware() …
  • 139. (C)opyright Dave Farley 2015 Test Environment Types • Some Tests need special treatment. • Tag Tests with properties and allocate them dynamically: @TimeTravel @Test public void shouldDoSomethingThatNeedsFakeTime() … @Destructive @Test public void shouldDoSomethingThatKillsPartOfTheSystem() … @FPGA(version=1.3) @Test public void shouldDoSomethingThatRequiresSpecificHardware() …
  • 140. (C)opyright Dave Farley 2015 Test Environment Types
  • 141. (C)opyright Dave Farley 2015 Test Environment Types
  • 142. (C)opyright Dave Farley 2015 Properties of Good Acceptance Tests • “What” not “How” • Isolated from other tests • Repeatable • Uses the language of the problem domain • Tests ANY change • Efficient
  • 143. (C)opyright Dave Farley 2015 Properties of Good Acceptance Tests • “What” not “How” • Isolated from other tests • Repeatable • Uses the language of the problem domain • Tests ANY change • Efficient
  • 144. (C)opyright Dave Farley 2015 Production-like Test Environments
  • 145. (C)opyright Dave Farley 2015 Production-like Test Environments
  • 146. (C)opyright Dave Farley 2015 Production-like Test Environments
  • 147. (C)opyright Dave Farley 2015 Production-like Test Environments
  • 148. (C)opyright Dave Farley 2015 Production-like Test Environments
  • 149. (C)opyright Dave Farley 2015 Production-like Test Environments
  • 150. (C)opyright Dave Farley 2015 Production-like Test Environments
  • 151. (C)opyright Dave Farley 2015 Make Test Cases Internally Synchronous
  • 152. (C)opyright Dave Farley 2015 Make Test Cases Internally Synchronous • Look for a “Concluding Event” listen for that in your DSL to report an async call as complete •
  • 153. (C)opyright Dave Farley 2015 Make Test Cases Internally Synchronous Example DSL level Implementation… public String placeOrder(String params…) { orderSent = sendAsyncPlaceOrderMessage(parseOrderParams(params)); return waitForOrderConfirmedOrFailOnTimeOut(orderSent); } • Look for a “Concluding Event” listen for that in your DSL to report an async call as complete •
  • 154. (C)opyright Dave Farley 2015 Make Test Cases Internally Synchronous Example DSL level Implementation… public String placeOrder(String params…) { orderSent = sendAsyncPlaceOrderMessage(parseOrderParams(params)); return waitForOrderConfirmedOrFailOnTimeOut(orderSent); } • Look for a “Concluding Event” listen for that in your DSL to report an async call as complete •
  • 155. (C)opyright Dave Farley 2015 Make Test Cases Internally Synchronous • Look for a “Concluding Event” listen for that in your DSL to report an async call as complete • If you really have to, implement a 
 “poll-and-timeout” mechanism in your test- infrastructure • Never, Never, Never, put a “wait(xx)” and expect your tests to be (a) Reliable or (b) Efficient! • Look for a “Concluding Event” listen for that in your DSL to report an async call as complete •
  • 156. (C)opyright Dave Farley 2015 Make Test Cases Internally Synchronous • Look for a “Concluding Event” listen for that in your DSL to report an async call as complete • If you really have to, implement a 
 “poll-and-timeout” mechanism in your test- infrastructure • Never, Never, Never, put a “wait(xx)” and expect your tests to be (a) Reliable or (b) Efficient! • Look for a “Concluding Event” listen for that in your DSL to report an async call as complete • Anti-Pattern!
  • 157. (C)opyright Dave Farley 2015 Scaling-Up Artifact Repository Deployment Pipeline Acceptance Commit Component Performance System Performance Staging Env. Deployment App. Production Env. Deployment App. Source Repository Manual Test Env. Deployment App.
  • 158. (C)opyright Dave Farley 2015 Scaling-Up Artifact Repository Deployment Pipeline Acceptance Commit Component Performance System Performance Staging Env. Deployment App. Production Env. Deployment App. Source Repository Manual Test Env. Deployment App. Deployment Pipeline Commit Manual Test Env. Deployment App. Artifact Repository Acceptance Acceptance Test Environment
  • 159. (C)opyright Dave Farley 2015 Scaling-Up Artifact Repository Deployment Pipeline Acceptance Commit Component Performance System Performance Staging Env. Deployment App. Production Env. Deployment App. Source Repository Manual Test Env. Deployment App. Deployment Pipeline Commit Manual Test Env. Deployment App. Artifact Repository Acceptance Acceptance Test Environment AA
  • 160. (C)opyright Dave Farley 2015 Scaling-Up Artifact Repository Deployment Pipeline Acceptance Commit Component Performance System Performance Staging Env. Deployment App. Production Env. Deployment App. Source Repository Manual Test Env. Deployment App. Deployment Pipeline Commit Manual Test Env. Deployment App. Artifact Repository Acceptance Acceptance Test Environment A A
  • 161. (C)opyright Dave Farley 2015 Scaling-Up Artifact Repository Deployment Pipeline Acceptance Commit Component Performance System Performance Staging Env. Deployment App. Production Env. Deployment App. Source Repository Manual Test Env. Deployment App. Deployment Pipeline Commit Manual Test Env. Deployment App. Artifact Repository Acceptance Acceptance Test Environment Test Host Test Host Test Host Test Host Test Host A A
  • 162. (C)opyright Dave Farley 2015 Scaling-Up Artifact Repository Deployment Pipeline Acceptance Commit Component Performance System Performance Staging Env. Deployment App. Production Env. Deployment App. Source Repository Manual Test Env. Deployment App. Deployment Pipeline Commit Manual Test Env. Deployment App. Artifact Repository Acceptance Acceptance Acceptance Test Environment Test Host Test Host Test Host Test Host Test Host AA
  • 163. (C)opyright Dave Farley 2015 Data - SUT State • One More Desirable Property… • We should be able to run our tests anywhere
 • Ideally we want SUT to be an a fairly ‘Neutral’ State • Data Defining SUT State Falls into 3 categories: • Transactional Data • Reference Data • Configuration Data
  • 164. (C)opyright Dave Farley 2015 Data - SUT State • One More Desirable Property… • We should be able to run our tests anywhere
 • Ideally we want SUT to be an a fairly ‘Neutral’ State • Data Defining SUT State Falls into 3 categories: • Transactional Data • Reference Data • Configuration Data Use Prod Data Generate in Scope of Test Use Versioned Test Data
  • 165. (C)opyright Dave Farley 2015 Data - SUT State • One More Desirable Property… • We should be able to run our tests anywhere
 • Ideally we want SUT to be an a fairly ‘Neutral’ State • Data Defining SUT State Falls into 3 categories: • Transactional Data • Reference Data • Configuration Data Use Prod Data Generate in Scope of Test Use Versioned Test Data
  • 166. (C)opyright Dave Farley 2015 Data - SUT State • One More Desirable Property… • We should be able to run our tests anywhere
 • Ideally we want SUT to be an a fairly ‘Neutral’ State • Data Defining SUT State Falls into 3 categories: • Transactional Data • Reference Data • Configuration Data Use Prod Data Generate in Scope of Test Use Versioned Test Data
  • 167. (C)opyright Dave Farley 2015 Data - SUT State • One More Desirable Property… • We should be able to run our tests anywhere
 • Ideally we want SUT to be an a fairly ‘Neutral’ State • Data Defining SUT State Falls into 3 categories: • Transactional Data • Reference Data • Configuration Data Use Prod Data Generate in Scope of Test Use Versioned Test Data
  • 168. (C)opyright Dave Farley 2015 Anti-Patterns in Acceptance Testing
  • 169. (C)opyright Dave Farley 2015 Anti-Patterns in Acceptance Testing • Don’t use UI Record-and-playback Systems
  • 170. (C)opyright Dave Farley 2015 Anti-Patterns in Acceptance Testing • Don’t use UI Record-and-playback Systems • Don’t Record-and-playback production data. This has a role, but it is NOT Acceptance Testing
  • 171. (C)opyright Dave Farley 2015 Anti-Patterns in Acceptance Testing • Don’t use UI Record-and-playback Systems • Don’t Record-and-playback production data. This has a role, but it is NOT Acceptance Testing • Don’t dump production data to your test systems, instead define the absolute minimum data that you need
  • 172. (C)opyright Dave Farley 2015 Anti-Patterns in Acceptance Testing • Don’t use UI Record-and-playback Systems • Don’t Record-and-playback production data. This has a role, but it is NOT Acceptance Testing • Don’t dump production data to your test systems, instead define the absolute minimum data that you need • Don’t assume Nasty Automated Testing Products(tm) will do what you need. Be very sceptical about them. Start with YOUR strategy and evaluate tools against that.
  • 173. (C)opyright Dave Farley 2015 Anti-Patterns in Acceptance Testing • Don’t use UI Record-and-playback Systems • Don’t Record-and-playback production data. This has a role, but it is NOT Acceptance Testing • Don’t dump production data to your test systems, instead define the absolute minimum data that you need • Don’t assume Nasty Automated Testing Products(tm) will do what you need. Be very sceptical about them. Start with YOUR strategy and evaluate tools against that. • Don’t have a separate Testing/QA team! Quality is down to everyone - Developers own Acceptance Tests!!!
  • 174. (C)opyright Dave Farley 2015 Anti-Patterns in Acceptance Testing • Don’t use UI Record-and-playback Systems • Don’t Record-and-playback production data. This has a role, but it is NOT Acceptance Testing • Don’t dump production data to your test systems, instead define the absolute minimum data that you need • Don’t assume Nasty Automated Testing Products(tm) will do what you need. Be very sceptical about them. Start with YOUR strategy and evaluate tools against that. • Don’t have a separate Testing/QA team! Quality is down to everyone - Developers own Acceptance Tests!!! • Don’t let every Test start and init the app. Optimise for Cycle-Time, be efficient in your use of test environments.
  • 175. (C)opyright Dave Farley 2015 Anti-Patterns in Acceptance Testing • Don’t use UI Record-and-playback Systems • Don’t Record-and-playback production data. This has a role, but it is NOT Acceptance Testing • Don’t dump production data to your test systems, instead define the absolute minimum data that you need • Don’t assume Nasty Automated Testing Products(tm) will do what you need. Be very sceptical about them. Start with YOUR strategy and evaluate tools against that. • Don’t have a separate Testing/QA team! Quality is down to everyone - Developers own Acceptance Tests!!! • Don’t let every Test start and init the app. Optimise for Cycle-Time, be efficient in your use of test environments. • Don’t include Systems outside of your control in your Acceptance Test Scope
  • 176. (C)opyright Dave Farley 2015 Anti-Patterns in Acceptance Testing • Don’t use UI Record-and-playback Systems • Don’t Record-and-playback production data. This has a role, but it is NOT Acceptance Testing • Don’t dump production data to your test systems, instead define the absolute minimum data that you need • Don’t assume Nasty Automated Testing Products(tm) will do what you need. Be very sceptical about them. Start with YOUR strategy and evaluate tools against that. • Don’t have a separate Testing/QA team! Quality is down to everyone - Developers own Acceptance Tests!!! • Don’t let every Test start and init the app. Optimise for Cycle-Time, be efficient in your use of test environments. • Don’t include Systems outside of your control in your Acceptance Test Scope • Don’t Put ‘wait()’ instructions in your tests hoping it will solve intermittency
  • 177. (C)opyright Dave Farley 2015 Tricks for Success
  • 178. (C)opyright Dave Farley 2015 Tricks for Success • Do Ensure That Developers Own the Tests
  • 179. (C)opyright Dave Farley 2015 Tricks for Success • Do Ensure That Developers Own the Tests • Do Focus Your Tests on “What” not “How”
  • 180. (C)opyright Dave Farley 2015 Tricks for Success • Do Ensure That Developers Own the Tests • Do Focus Your Tests on “What” not “How” • Do Think of Your Tests as “Executable Specifications”
  • 181. (C)opyright Dave Farley 2015 Tricks for Success • Do Ensure That Developers Own the Tests • Do Focus Your Tests on “What” not “How” • Do Think of Your Tests as “Executable Specifications” • Do Make Acceptance Testing Part of your “Definition of Done”
  • 182. (C)opyright Dave Farley 2015 Tricks for Success • Do Ensure That Developers Own the Tests • Do Focus Your Tests on “What” not “How” • Do Think of Your Tests as “Executable Specifications” • Do Make Acceptance Testing Part of your “Definition of Done” • Do Keep Tests Isolated from one-another
  • 183. (C)opyright Dave Farley 2015 Tricks for Success • Do Ensure That Developers Own the Tests • Do Focus Your Tests on “What” not “How” • Do Think of Your Tests as “Executable Specifications” • Do Make Acceptance Testing Part of your “Definition of Done” • Do Keep Tests Isolated from one-another • Do Keep Your Tests Repeatable
  • 184. (C)opyright Dave Farley 2015 Tricks for Success • Do Ensure That Developers Own the Tests • Do Focus Your Tests on “What” not “How” • Do Think of Your Tests as “Executable Specifications” • Do Make Acceptance Testing Part of your “Definition of Done” • Do Keep Tests Isolated from one-another • Do Keep Your Tests Repeatable • Do Use the Language of the Problem Domain - Do try the DSL approach, whatever your tech.
  • 185. (C)opyright Dave Farley 2015 Tricks for Success • Do Ensure That Developers Own the Tests • Do Focus Your Tests on “What” not “How” • Do Think of Your Tests as “Executable Specifications” • Do Make Acceptance Testing Part of your “Definition of Done” • Do Keep Tests Isolated from one-another • Do Keep Your Tests Repeatable • Do Use the Language of the Problem Domain - Do try the DSL approach, whatever your tech. • Do Stub External Systems
  • 186. (C)opyright Dave Farley 2015 Tricks for Success • Do Ensure That Developers Own the Tests • Do Focus Your Tests on “What” not “How” • Do Think of Your Tests as “Executable Specifications” • Do Make Acceptance Testing Part of your “Definition of Done” • Do Keep Tests Isolated from one-another • Do Keep Your Tests Repeatable • Do Use the Language of the Problem Domain - Do try the DSL approach, whatever your tech. • Do Stub External Systems • Do Test in “Production-Like” Environments
  • 187. (C)opyright Dave Farley 2015 Tricks for Success • Do Ensure That Developers Own the Tests • Do Focus Your Tests on “What” not “How” • Do Think of Your Tests as “Executable Specifications” • Do Make Acceptance Testing Part of your “Definition of Done” • Do Keep Tests Isolated from one-another • Do Keep Your Tests Repeatable • Do Use the Language of the Problem Domain - Do try the DSL approach, whatever your tech. • Do Stub External Systems • Do Test in “Production-Like” Environments • Do Make Instructions Appear Synchronous at the Level of the Test Case
  • 188. (C)opyright Dave Farley 2015 Tricks for Success • Do Ensure That Developers Own the Tests • Do Focus Your Tests on “What” not “How” • Do Think of Your Tests as “Executable Specifications” • Do Make Acceptance Testing Part of your “Definition of Done” • Do Keep Tests Isolated from one-another • Do Keep Your Tests Repeatable • Do Use the Language of the Problem Domain - Do try the DSL approach, whatever your tech. • Do Stub External Systems • Do Test in “Production-Like” Environments • Do Make Instructions Appear Synchronous at the Level of the Test Case • Do Test for ANY change
  • 189. (C)opyright Dave Farley 2015 Tricks for Success • Do Ensure That Developers Own the Tests • Do Focus Your Tests on “What” not “How” • Do Think of Your Tests as “Executable Specifications” • Do Make Acceptance Testing Part of your “Definition of Done” • Do Keep Tests Isolated from one-another • Do Keep Your Tests Repeatable • Do Use the Language of the Problem Domain - Do try the DSL approach, whatever your tech. • Do Stub External Systems • Do Test in “Production-Like” Environments • Do Make Instructions Appear Synchronous at the Level of the Test Case • Do Test for ANY change • Do Keep your Tests Efficient
  • 190. (C)opyright Dave Farley 2015 Further Exploration • http://en.wikipedia.org/wiki/Behavior-driven_development • http://www.thoughtworks.com/insights/blog/specification-example • https://cukes.info/ • http://jbehave.org/ • http://www.agiledata.org/essays/databaseTesting.html • http://www.red-gate.com/ • http://www.dbmaestro.com/ • https://www.youtube.com/watch?v=pw_RBblVny4
  • 191. (C)opyright Dave Farley 2015 Q&A http://www.continuous-delivery.co.uk Dave Farley http://www.davefarley.net @davefarley77