Professional Documents
Culture Documents
Acceptance Testing For Continuous Farley Acceptance Testing Acceptance Testing
Acceptance Testing For Continuous Farley Acceptance Testing Acceptance Testing
Continuous Delivery
Dave Farley
http://www.davefarley.net
@davefarley77
http://www.continuous-delivery.co.uk
The Role of Acceptance Testing
Source
Repository
The Role of Acceptance Testing
Deployment Pipeline
Local Dev. Env. Commit
Acceptance
Source
Repository
Commit
Acceptance
Manual Test Env.
Production Env.
Artifact
Deployment
Deployment Production Repository Manual App.
App.
Staged Perf1
Perf2
Staging Env. Component
Performance
Deployment
App.
System
Performance
The Role of Acceptance Testing
Deployment Pipeline
Local Dev. Env. Commit
Acceptance
Source
Repository
Commit
Acceptance
Manual Test Env.
Production Env.
Artifact
Deployment
Deployment Production Repository Manual App.
App.
Staged Perf1
Perf2
Staging Env. Component
Performance
Deployment
App.
System
Performance
The Role of Acceptance Testing
Deployment Pipeline
Local Dev. Env. Commit
Acceptance
Source
Repository
Commit
Acceptance
Manual Test Env.
Production Env.
Artifact
Deployment
Deployment Production Repository Manual App.
App.
Staged Perf1
Perf2
Staging Env. Component
Performance
Deployment
App.
System
Performance
What is Acceptance Testing?
• Asserts that the code does what the users want.
An Executable Specification of
the Behaviour of the System
What is Acceptance Testing?
Executable
Idea Unit Test Code Build Release
spec.
What is Acceptance Testing?
Executable
Idea Unit Test Code Build Release
spec.
What is Acceptance Testing?
Executable
Idea Unit Test Code Build Release
spec.
So What’s So Hard?
• Tests break when the SUT changes (Particularly UI)
• UI Record-and-playback Systems
•
Anti-Pattern!
UI Record-and-playback Systems
•
Anti-Pattern!
Record-and-playback of production data
•
Anti-Pattern!
Dumps of production data to test systems
•
Anti-Pattern!
Nasty automated testing products.
Who Owns the Tests?
•
tests Anti-Pattern!
Separate Testing/QA team owning automated
Who Owns the Tests?
Developers Own
Acceptance Tests!
Properties of Good Acceptance Tests
• “What” not “How”
• Repeatable
• Efficient
Properties of Good Acceptance Tests
• “What” not “How”
• Repeatable
• Efficient
“What” not “How”
UI Other
Market Clearing
Traders API Traders external
Makers Destination
end-points
Trade
Public API FIX API Reporting …
Gateway
“What” not “How”
Test Test
Test Test Test
Case Test Case
Case Case Case
Case
Test Test
Test Case Case Test Test Test Test
Case Test
Case Case Case Case
Test Case
Test
Case Test Test Test
Case Test Test Test
Case Case Case
Case Case Case
Trade
Public API FIX API Reporting …
Gateway
“What” not “How”
Test Test
Test Test Test
Case Test Case
Case Case Case
Case
Test Test
Test Case Case Test Test Test Test
Case Test
Case Case Case Case
Test Case
Test
Case Test Test Test
Case Test Test Test
Case Case Case
Case Case Case
Trade
Public API FIX API Reporting …
Gateway
“What” not “How”
Test Test
Test Test Test
Case Test Case
Case Case Case
Case
Test Test
Test Case Case Test Test Test Test
Case Test
Case Case Case Case
Test Case
Test
Case Test Test Test
Case Test Test Test
Case Case Case
Case Case Case
UI Other
Market Clearing
Traders API Traders external
Makers Destination
end-points
Trade
Public API FIX API Reporting …
Gateway
“What” not “How”
Test Test
Test Test Test
Case Test Case
Case Case Case
Case
Test Test
Test Case Case Test Test Test Test
Case Test
Case Case Case Case
Test Case
Test
Case Test Test Test
Case Test Test Test
Case Case Case
Case Case Case
UI External
API FIX-API
Stubs
Trade
Public API FIX API Reporting …
Gateway
“What” not “How”
Test Test
Test Test Test
Case Test Case
Case Case Case
Case
Test Test
Test Case Case Test Test Test Test
Case Test
Case Case Case Case
Test Case
Test
Case Test Test Test
Case Test Test Test
Case Case Case
Case Case Case
UI External
API FIX-API
Stubs
Trade
Public API FIX API Reporting …
Gateway
“What” not “How”
Test Test
Test Test Test
Case Test Case
Case Case Case
Case
Test Test
Test Case Case Test Test Test Test
Case Test
Case Case Case Case
Test Case
Test
Case Test Test Test
Case Test Test Test
Case Case Case
Case Case Case
UI External
API FIX-API
Stubs
Trade
Public API FIX API Reporting …
Gateway
“What” not “How”
sts
e te
a n c
e pt External
UI API FIX-API
a c c Stubs
all
o
o nt
mm
c o
tu re
tr uc
a s
in fr
st
Te
Trade
Public API FIX API Reporting …
Gateway
“What” not “How” - Separate Deployment from Testing
•
Anti-Pattern!
Every Test should control its start conditions,
and so should start and init the app.
• Repeatable
• Efficient
Properties of Good Acceptance Tests
• “What” not “How”
• Repeatable
• Efficient
Test Isolation
• Any form of testing is about evaluating
something in controlled circumstances
External System
‘A’
?
System Under Test
‘B’
External System
‘C’
Test Isolation - Isolating the System Under Test
Anti-Pattern!
External System
‘A’
System Under Test
‘B’
External System
‘C’
Test Isolation - Isolating the System Under Test
Test Cases
External System Verifiable
Output
‘A’
Test Cases
External System Verifiable
Output
‘C’
Test Isolation - Isolating Test Cases
• Assuming multi-user systems…
• 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
• …
Test Isolation - Temporal Isolation
• We want repeatable results
self.store.assertOrderPlaced(order)
Test Isolation - Temporal Isolation
• We want repeatable results
self.store.assertOrderPlaced(order)
Test Isolation - Temporal Isolation
• We want repeatable results
self.store.assertOrderPlaced(order)
Test Isolation - Temporal Isolation
• We want repeatable results
self.store.assertOrderPlaced(order)
Test Isolation - Temporal Isolation
• We want repeatable results
self.store.assertOrderPlaced(order)
Test Isolation - Temporal Isolation
• We want repeatable results
self.store.assertOrderPlaced(order)
Test Isolation - Temporal Isolation
• We want repeatable results
self.store.assertOrderPlaced(order)
Test Isolation - Temporal Isolation
• We want repeatable results
self.store.assertOrderPlaced(order)
• Repeatable
• Efficient
Properties of Good Acceptance Tests
• “What” not “How”
• Repeatable
• Efficient
Repeatability - Test Doubles
External System
Repeatability - Test Doubles
Local Interface
to External System
External System
Repeatability - Test Doubles
Local Interface
to External System
Communications
to External System
External System
Repeatability - Test Doubles
Communications TestStub
Simulating External
to External System
System
External System
Repeatability - Test Doubles
t
n
en
on t
tio
vir es
Local Interface Local Interface
m
to External System to External System
En T
uc
od
Communications TestStub
Simulating External
to External System
System
n
Pr
io
lkjalskjlakjsdlkajsld j
lkajsdlkajsldkj
at
]laksjdiuqoiwuoijds
oijasodiaosidjuoiasud
ur
kjhaskjhdkjhkjh askjhl lkjasl dkjas lkajl ajsd
lkjalskjlakjsdlkajsld j
lkajsdlkajsldkj
ig
lkjlakjsldkjlka laskj ljl akjl kajsldijupoqwiuepoq dlkjl iu
lkajsodiuqpwouoi la
]laksjdiuqoiwuoijds
oijasodiaosidjuoiasud
nf
Co
External System
Test Doubles As Part of Test Infrastructure
Local Interface
to External System
TestStub
Simulating External
System
Test Doubles As Part of Test Infrastructure
Local Interface
to External System
TestStub
Simulating External
System
Test Doubles As Part of Test Infrastructure
Public Interface
Local Interface
to External System
TestStub
Simulating External
System
Test Doubles As Part of Test Infrastructure
Public Interface
Local Interface
to External System
TestStub
Simulating External
System
Test Doubles As Part of Test Infrastructure
Test Test Test Test
Case Case Case Case
Test Infrastructure
Public Interface
st
Te
Test Infrastructure
r
de
Un Back-Channel
em
Local Interface
st
to External System
Sy
TestStub
Simulating External
System
Properties of Good Acceptance Tests
• “What” not “How”
• Repeatable
• Efficient
Properties of Good Acceptance Tests
• “What” not “How”
• Repeatable
• Efficient
Language of the Problem Domain - DSL
@Test
public void shouldSuccessfullyPlaceAnImmediateOrCancelBuyMarketOrder()
{
fixAPIMarketMaker.placeMassOrder("instrument", "ask: 11@52", "ask: 10@51", "ask: 10@50", "bid: 10@49");
@Test
public void shouldSuccessfullyPlaceAnImmediateOrCancelBuyMarketOrder()
{
fixAPIMarketMaker.placeMassOrder("instrument", "ask: 11@52", "ask: 10@51", "ask: 10@50", "bid: 10@49");
@Before
public void beforeEveryTest()
{
adminAPI.createInstrument("name: instrument");
registrationAPI.createUser("user");
registrationAPI.createUser("marketMaker", "accountType: MARKET_MAKER");
tradingUI.loginAsLive("user");
}
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();
}
@Test
public void shouldSuccessfullyPlaceAnImmediateOrCancelBuyMarketOrder()
{
fixAPIMarketMaker.placeMassOrder("instrument", "ask: 11@52", "ask: 10@51", "ask: 10@50", "bid: 10@49");
@Test
public void shouldSuccessfullyPlaceAnImmediateOrCancelBuyMarketOrder()
{
fixAPIMarketMaker.placeMassOrder("instrument", "ask: 11@52", "ask: 10@51", "ask: 10@50", "bid: 10@49");
• Repeatable
• Efficient
Properties of Good Acceptance Tests
• “What” not “How”
• Repeatable
• Efficient
Testing with Time
• Ignore time
• Control time
Testing With Time - Ignore Time
Mechanism
Pros:
• Simple!
Cons:
• Can miss errors
• Prevents any hope of testing complex time-based
scenarios
Testing With Time - Controlling Time
Mechanism
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
@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());
}
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());
}
Testing With Time - Controlling Time
Testing With Time - Controlling Time
Test Test Test Test
Case Case Case Case
Test Infrastructure
st
r Te
de
public void someTimeDependentMethod()
{
Un
time = System.getTime();
}
em
st
Sy
Testing With Time - Controlling Time
Test Test Test Test
Case Case Case Case
Test Infrastructure
st
r Te
de
include Clock;
Un
{
time = Clock.getTime();
}
em
st
Sy
Testing With Time - Controlling Time
Test Test Test Test
Case Case Case Case
Test Infrastructure
include Clock;
st
public void someTimeDependentMethod()
{
Te
time = Clock.getTime();
}
r
de
public class Clock {
Un
public static clock = new SystemClock();
return clock.getTime();
}
Testing With Time - Controlling Time
Test Test Test Test
Case Case Case Case
Test Infrastructure
include Clock;
st
public void someTimeDependentMethod()
{
Te
time = Clock.getTime();
}
r
de
public class Clock {
Un
public static clock = new SystemClock(); Test Infrastructure
public static void setTime(long newTime) {
Back-Channel
em
clock.setTime(newTime);
}
st
return clock.getTime();
}
@Destructive
@Test
public void shouldDoSomethingThatKillsPartOfTheSystem()
…
@FPGA(version=1.3)
@Test
public void shouldDoSomethingThatRequiresSpecificHardware()
…
Test Environment Types
• Some Tests need special treatment.
@Destructive
@Test
public void shouldDoSomethingThatKillsPartOfTheSystem()
…
@FPGA(version=1.3)
@Test
public void shouldDoSomethingThatRequiresSpecificHardware()
…
Test Environment Types
Test Environment Types
Properties of Good Acceptance Tests
• “What” not “How”
• Repeatable
• Efficient
Properties of Good Acceptance Tests
• “What” not “How”
• Repeatable
• Efficient
Production-like Test Environments
Production-like Test Environments
Production-like Test Environments
Production-like Test Environments
Production-like Test Environments
Production-like Test Environments
Production-like Test Environments
Make Test Cases Internally Synchronous
Make Test Cases Internally Synchronous
•
Anti-Pattern!
Never, Never, Never, put a “wait(xx)” and expect
your tests to be (a) Reliable or (b) Efficient!
Scaling-Up
Deployment Pipeline
Commit
Acceptance
Source
Repository
Artifact
Deployment
Deployment
Repository App.
App.
Deployment Pipeline
Commit
Artifact
Deployment
Deployment
Repository App.
App.
Deployment Pipeline
Commit
Artifact
Deployment
A
Repository
Deployment
App.
App.
Deployment Pipeline
Commit
Artifact
Deployment
A
Repository
Deployment
App.
App.
Test Host
Test Host
Test Host
Test Host
Deployment Pipeline Test Host
Commit
Artifact
Deployment
A
Repository
Deployment
App.
App.
Test Host
Test Host
Test Host
Test Host
Deployment Pipeline Test Host
Commit
Acceptance
Manual Test Env.
Production Env.
Artifact
Deployment
A
Repository
Deployment
App.
App.
• Don’t dump production data to your test systems, instead define the absolute
minimum data that you need
Anti-Patterns in Acceptance Testing
• Don’t use UI Record-and-playback Systems
• 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.
Anti-Patterns in Acceptance Testing
• Don’t use UI Record-and-playback Systems
• 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 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 let every Test start and init the app. Optimise for Cycle-Time, be efficient in
your use of test environments.
Anti-Patterns in Acceptance Testing
• Don’t use UI Record-and-playback Systems
• 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 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
Anti-Patterns in Acceptance Testing
• Don’t use UI Record-and-playback Systems
• 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 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
Tricks for Success
Tricks for Success
• Do Ensure That Developers Own the Tests
Tricks for Success
• Do Ensure That Developers Own the Tests
• Do Use the Language of the Problem Domain - Do try the DSL approach, whatever
your tech.
Tricks for Success
• Do Ensure That Developers Own the Tests
• Do Use the Language of the Problem Domain - Do try the DSL approach, whatever
your tech.
• Do Use the Language of the Problem Domain - Do try the DSL approach, whatever
your tech.
• Do Use the Language of the Problem Domain - Do try the DSL approach, whatever
your tech.
• Do Use the Language of the Problem Domain - Do try the DSL approach, whatever
your tech.
• Do Use the Language of the Problem Domain - Do try the DSL approach, whatever
your tech.
http://www.continuous-delivery.co.uk
Dave Farley
http://www.davefarley.net
@davefarley77