Continuous
Behavior
BDD in Continuous Delivery
CoDers Who Test
15th May 2018
Gáspár Nagy
coach • trainer • bdd addict • creator of specflow
“The BDD Books: Discovery” • http://bddbooks.com
@gasparnagy • gaspar@specsolutions.eu
Copyright © Gaspar NagyCopyright © Gaspar Nagy
bdd addict
given.when.then
CAUTION!
on the stage
Gáspár Nagy
coach, trainer and bdd addict
creator of SpecFlow
gaspar@specsolutions.eu
https://specsolutions.eu
@gasparnagy
Copyright © Gaspar NagyCopyright © Gaspar Nagy
What makes you nervous on
the day of the release?
My first app…
A long time ago* in a galaxy
far, far away**…
* 1995
** Veszprém, Hungary
Copyright © Gaspar NagyCopyright © Gaspar Nagy
My dream-projects in 1995
• Working software that was in use
• Exciting technical solutions
• Continuous learning
• And no conflicts in the team…
…because I was alone
Copyright © Gaspar NagyCopyright © Gaspar Nagy
My first “real” project…
Copyright © Gaspar NagyCopyright © Gaspar Nagy
Practicing team work
Copyright © Gaspar NagyCopyright © Gaspar Nagy
Practicing team work
And by a
modem for
“A”
Copyright © Gaspar NagyCopyright © Gaspar Nagy
Integration is more than merging…
changed
foo.cpp
changed
bar.cpp
?
void ProcessOrder()
{
…
+ account->Withdraw(sum);
…
}
void FinalizeOrder()
{
…
+ account->Withdraw(sum);
…
}
Copyright © Gaspar NagyCopyright © Gaspar Nagy
What is integration, then?
Ensuring that the improvements developed independently still form a working unit
Resolving file-
level conflicts
Can compile,
can build
Can be
deployed
There is no
regression
[Enter your
specific step
here]
Copyright © Gaspar NagyCopyright © Gaspar Nagy
Proper integration is difficult…
Copyright © Gaspar NagyCopyright © Gaspar Nagy
Frequency reduces difficulty (Fowler)
• „if it hurts, do it more often”
Copyright © Gaspar NagyCopyright © Gaspar Nagy
Continuous Integration, CI
Ensures that the improvements developed independently still form a working unit
• Resolving file-level conflicts
• Compilation, build
• Unit tests
• ...
Copyright © Gaspar NagyCopyright © Gaspar Nagy
Continuous integration revealed the next
problems…
• Manual regression testing does not scale…
• Manual deployments are error-prone…
Copyright © Gaspar NagyCopyright © Gaspar Nagy
Continuous Delivery, CD
Ensures that the application is always in a potentially deployable state (whether we
deploy is a manual decision)
• CI +
• Deployable
• Automated regression tests
(Acceptance Tests)
• ...
Copyright © Gaspar NagyCopyright © Gaspar Nagy
CD vs. CD
Continuous Delivery vs. Continuous Deployment
Copyright © Gaspar NagyCopyright © Gaspar Nagy
Continuous Delivery, Continuous Deployment
Copyright © Gaspar NagyCopyright © Gaspar Nagy
“Continues delivery can be achieved by anyone,
Continues deployment is only for some specific
products…”
/some people/
Copyright © Gaspar NagyCopyright © Gaspar Nagy
Continuous Deployment, CD
Ensures that the application is always actual
• CD +
• Fully* automated verification
• Automated non-functional tests
• Appropriate context (eg. SaaS)
• ...
• ???
„live”
Copyright © Gaspar NagyCopyright © Gaspar Nagy
Continuous Deployment is the key to understand the
“CD” mentality…
…so let’s try!
Copyright © Gaspar NagyCopyright © Gaspar Nagy
What are your fears?
• I am afraid of pushing the “release” button!
• The feedback I get from my tests are not useful!
Copyright © Gaspar NagyCopyright © Gaspar Nagy
More testing and more automation!
Source: World Quality Report 2015/16
increased by 35%
increased by 60%
0%
5%
10%
15%
20%
25%
30%
35%
40%
45%
50%
Amount of IT budget allocated to QA Ratio of test case automation
2014
2015
Small tests = small problems;
Big tests = big problems
• They are SLOOOOOOW!
• They are BRITTLE!
• They need awful lot of MAINTENANCE!
• They FAIL!!!
Copyright © Gaspar NagyCopyright © Gaspar Nagy
Our typical automated tests are
not good enough for CD…
Copyright © Gaspar NagyCopyright © Gaspar Nagy
What’s wrong with our tests?
Episode #1
PO: We have far too many prod issues. We have
to improve our CD pipeline…
Write more tests!
Team: How much more?
Episode #2
PO: Are your tests balanced according to the test
automation pyramid?
Team: … not fully…, more like an ice-cream cone
PO: Then write more unit tests!
Episode #3
PO: You should increase your test coverage!
Team: You mean line coverage? How much?
PO: Well… what is exactly a code line doing?
Episode #4
PO: You should cover the risks better!
Team: How do we know if we have covered
them?
Copyright © Gaspar NagyCopyright © Gaspar Nagy
PO controlling testing activities…
Problem Domain Solution Domain
Lightbulb by Unknown Author is licensed under CC BY-SA
PO
REQ APP
TESTS
Copyright © Gaspar NagyCopyright © Gaspar Nagy
You cannot control something that is
outside of your control…
Copyright © Gaspar NagyCopyright © Gaspar Nagy
Tests should be part of shared ownership…
Problem Domain Solution Domain
Lightbulb by Unknown Author is licensed under CC BY-SA
REQ APP
TESTS
Copyright © Gaspar NagyCopyright © Gaspar Nagy
How could the entire team
own the tests?
Copyright © Gaspar NagyCopyright © Gaspar Nagy
Tests should be part of shared ownership…
Problem Domain Solution Domain
Lightbulb by Unknown Author is licensed under CC BY-SA
The old PIN
should be
correct
public void VerifyOldPin(string enteredOldPin)
{
var db = new CardRespoitory();
var oldPin = db.LoadOldPin(CurrentCard);
if (oldPin != enteredOldPin)
{
throw new InvalidPinException();
}
}
Implements
[TestMethod]
public void ShuldFailWhenOldPinIncorrect()
{
var cardStoreMock = new CardStoreMock();
cardStoreMock.SetCard("1234678", "1234");
var sut = new CardService();
var result = sut.ChangePin("1234678", "1111",
"1212", "1212");
Assert.IsFalse(result);
}
Copyright © Gaspar NagyCopyright © Gaspar Nagy
Specification by example
Problem Domain Solution Domain
Lightbulb by Unknown Author is licensed under CC BY-SA
The old PIN
should be
correct
public void VerifyOldPin(string enteredOldPin)
{
var db = new CardRespoitory();
var oldPin = db.LoadOldPin(CurrentCard);
if (oldPin != enteredOldPin)
{
throw new InvalidPinException();
}
}
Implements
[TestMethod]
public void ShuldFailWhenOldPinIncorrect()
{
var cardStoreMock = new CardStoreMock();
cardStoreMock.SetCard("1234678", "1234");
var sut = new CardService();
var result = sut.ChangePin("1234678", "1111",
"1212", "1212");
Assert.IsFalse(result);
}
Old PIN is incorrect
• PIN is 1234
• Enter old PIN: 1111
• Change PIN
⇒ PIN change rejected
Illustrates
Automates
Copyright © Gaspar NagyCopyright © Gaspar Nagy
Codified tests are hard to maintain
• What was the example?
• Why were these
numbers used?
• What did we want to
verify?
[TestMethod]
public void ShuldFailWhenOldPinIncorrect()
{
var cardStoreMock = new CardStoreMock();
cardStoreMock.SetCard("1234678", "1234");
var sut = new CardService();
var result = sut.ChangePin("1234678", "1111",
"1212", "1212");
Assert.IsFalse(result);
}
Copyright © Gaspar NagyCopyright © Gaspar Nagy
BDD is here to help?
Copyright © Gaspar NagyCopyright © Gaspar Nagy
Formulated BDD scenarios
Problem Domain Solution Domain
The old PIN
should be
correct
public void VerifyOldPin(string enteredOldPin)
{
var db = new CardRespoitory();
var oldPin = db.LoadOldPin(CurrentCard);
if (oldPin != enteredOldPin)
{
throw new InvalidPinException();
}
}
Implements
Old PIN is incorrect
• PIN is 1234
• Enter old PIN: 1111
• Change PIN
⇒ PIN change rejected
Illustrates
Scenario: Old PIN is incorrect
Given my old pin is 1234
And I enter 1111 as old PIN
When I try to change my PIN
Then the PIN change should be rejected [Then]
public void I_enter_PIN_as_old_pin(string pin)
{
changePinContext.SetOldPin(pin);
}
[When]
public void I_enter_PIN_as_old_pin(string pin)
{
changePinContext.SetOldPin(pin);
}
[Given]
public void I_enter_PIN_as_old_pin(string pin)
{
changePinContext.SetOldPin(pin);
}
Copyright © Gaspar NagyCopyright © Gaspar Nagy
Behavior Driven Development
Problem Domain Solution Domain
Lightbulb by Unknown Author is licensed under CC BY-SA
REQ APP
Given
When
Then
SPECS
Validates Verifies
Copyright © Gaspar NagyCopyright © Gaspar Nagy
Behavior Driven Development is about
understanding & validating
business requirements
through illustrative examples
Copyright © Gaspar NagyCopyright © Gaspar Nagy
BDD is not about tests!
Copyright © Gaspar NagyCopyright © Gaspar Nagy
Functional quality is not only about whether
IT WORKS as expected…
but also about
whether the EXPECTATIONS ARE GOOD and
DOCUMENTED…
Functional quality
Episode in a later season…
PO: We have got a strange prod issue. Could we
look into that?
Team: Sure. Let’s have a look at the related BDD
scenarios…
PO: I see. I think there is an important case we
did not detail enough…
Copyright © Gaspar NagyCopyright © Gaspar Nagy
Happy ending
Copyright © Gaspar NagyCopyright © Gaspar Nagy
Finally I’ve got a dream-project again
• It was a complex service used by hundreds of apps and through them millions of
users all over the world
• Processed several thousands of requests per second
• Was critical in the client’s service chain
• We rolled it out without any severe issues…
• And we knew that there will be no problems…
• Because we had shared control over the specs (BDD scenarios)
• And this gave us confidence to push the release button
Copyright © Gaspar NagyCopyright © Gaspar Nagy
Continuous deployment is about CONFIDENCE
…and you need to keep the link to the problem
domain to gain that
Why was my first project working?
• Short cycles
• Instant release
• Close to “business” but also
close to users
Copyright © Gaspar NagyCopyright © Gaspar Nagy
Think about YOUR tests…
Are they also linking the solution with the problem?
Source: https://shashinki.com/
Thank you!
Gáspár Nagy
coach • trainer • bdd addict • creator of specflow
“The BDD Books: Discovery” • http://bddbooks.com
@gasparnagy • gaspar@specsolutions.eu
Copyright © Gaspar NagyCopyright © Gaspar Nagy

Continuous Behavior - BDD in Continuous Delivery (CoDers Who Test, Gothenburg, 15/5/2018)

  • 1.
    Continuous Behavior BDD in ContinuousDelivery CoDers Who Test 15th May 2018 Gáspár Nagy coach • trainer • bdd addict • creator of specflow “The BDD Books: Discovery” • http://bddbooks.com @gasparnagy • gaspar@specsolutions.eu
  • 3.
    Copyright © GasparNagyCopyright © Gaspar Nagy bdd addict given.when.then CAUTION! on the stage Gáspár Nagy coach, trainer and bdd addict creator of SpecFlow gaspar@specsolutions.eu https://specsolutions.eu @gasparnagy
  • 4.
    Copyright © GasparNagyCopyright © Gaspar Nagy What makes you nervous on the day of the release?
  • 5.
  • 6.
    A long timeago* in a galaxy far, far away**… * 1995 ** Veszprém, Hungary
  • 8.
    Copyright © GasparNagyCopyright © Gaspar Nagy My dream-projects in 1995 • Working software that was in use • Exciting technical solutions • Continuous learning • And no conflicts in the team… …because I was alone
  • 9.
    Copyright © GasparNagyCopyright © Gaspar Nagy My first “real” project…
  • 10.
    Copyright © GasparNagyCopyright © Gaspar Nagy Practicing team work
  • 11.
    Copyright © GasparNagyCopyright © Gaspar Nagy Practicing team work And by a modem for “A”
  • 12.
    Copyright © GasparNagyCopyright © Gaspar Nagy Integration is more than merging… changed foo.cpp changed bar.cpp ? void ProcessOrder() { … + account->Withdraw(sum); … } void FinalizeOrder() { … + account->Withdraw(sum); … }
  • 13.
    Copyright © GasparNagyCopyright © Gaspar Nagy What is integration, then? Ensuring that the improvements developed independently still form a working unit Resolving file- level conflicts Can compile, can build Can be deployed There is no regression [Enter your specific step here]
  • 14.
    Copyright © GasparNagyCopyright © Gaspar Nagy Proper integration is difficult…
  • 15.
    Copyright © GasparNagyCopyright © Gaspar Nagy Frequency reduces difficulty (Fowler) • „if it hurts, do it more often”
  • 16.
    Copyright © GasparNagyCopyright © Gaspar Nagy Continuous Integration, CI Ensures that the improvements developed independently still form a working unit • Resolving file-level conflicts • Compilation, build • Unit tests • ...
  • 17.
    Copyright © GasparNagyCopyright © Gaspar Nagy Continuous integration revealed the next problems… • Manual regression testing does not scale… • Manual deployments are error-prone…
  • 18.
    Copyright © GasparNagyCopyright © Gaspar Nagy Continuous Delivery, CD Ensures that the application is always in a potentially deployable state (whether we deploy is a manual decision) • CI + • Deployable • Automated regression tests (Acceptance Tests) • ...
  • 19.
    Copyright © GasparNagyCopyright © Gaspar Nagy CD vs. CD Continuous Delivery vs. Continuous Deployment
  • 20.
    Copyright © GasparNagyCopyright © Gaspar Nagy Continuous Delivery, Continuous Deployment
  • 21.
    Copyright © GasparNagyCopyright © Gaspar Nagy “Continues delivery can be achieved by anyone, Continues deployment is only for some specific products…” /some people/
  • 22.
    Copyright © GasparNagyCopyright © Gaspar Nagy Continuous Deployment, CD Ensures that the application is always actual • CD + • Fully* automated verification • Automated non-functional tests • Appropriate context (eg. SaaS) • ... • ??? „live”
  • 23.
    Copyright © GasparNagyCopyright © Gaspar Nagy Continuous Deployment is the key to understand the “CD” mentality… …so let’s try!
  • 24.
    Copyright © GasparNagyCopyright © Gaspar Nagy What are your fears? • I am afraid of pushing the “release” button! • The feedback I get from my tests are not useful!
  • 25.
    Copyright © GasparNagyCopyright © Gaspar Nagy More testing and more automation! Source: World Quality Report 2015/16 increased by 35% increased by 60% 0% 5% 10% 15% 20% 25% 30% 35% 40% 45% 50% Amount of IT budget allocated to QA Ratio of test case automation 2014 2015
  • 26.
    Small tests =small problems; Big tests = big problems • They are SLOOOOOOW! • They are BRITTLE! • They need awful lot of MAINTENANCE! • They FAIL!!!
  • 27.
    Copyright © GasparNagyCopyright © Gaspar Nagy Our typical automated tests are not good enough for CD…
  • 28.
    Copyright © GasparNagyCopyright © Gaspar Nagy What’s wrong with our tests?
  • 29.
    Episode #1 PO: Wehave far too many prod issues. We have to improve our CD pipeline… Write more tests! Team: How much more?
  • 30.
    Episode #2 PO: Areyour tests balanced according to the test automation pyramid? Team: … not fully…, more like an ice-cream cone PO: Then write more unit tests!
  • 31.
    Episode #3 PO: Youshould increase your test coverage! Team: You mean line coverage? How much? PO: Well… what is exactly a code line doing?
  • 32.
    Episode #4 PO: Youshould cover the risks better! Team: How do we know if we have covered them?
  • 33.
    Copyright © GasparNagyCopyright © Gaspar Nagy PO controlling testing activities… Problem Domain Solution Domain Lightbulb by Unknown Author is licensed under CC BY-SA PO REQ APP TESTS
  • 34.
    Copyright © GasparNagyCopyright © Gaspar Nagy You cannot control something that is outside of your control…
  • 35.
    Copyright © GasparNagyCopyright © Gaspar Nagy Tests should be part of shared ownership… Problem Domain Solution Domain Lightbulb by Unknown Author is licensed under CC BY-SA REQ APP TESTS
  • 36.
    Copyright © GasparNagyCopyright © Gaspar Nagy How could the entire team own the tests?
  • 37.
    Copyright © GasparNagyCopyright © Gaspar Nagy Tests should be part of shared ownership… Problem Domain Solution Domain Lightbulb by Unknown Author is licensed under CC BY-SA The old PIN should be correct public void VerifyOldPin(string enteredOldPin) { var db = new CardRespoitory(); var oldPin = db.LoadOldPin(CurrentCard); if (oldPin != enteredOldPin) { throw new InvalidPinException(); } } Implements [TestMethod] public void ShuldFailWhenOldPinIncorrect() { var cardStoreMock = new CardStoreMock(); cardStoreMock.SetCard("1234678", "1234"); var sut = new CardService(); var result = sut.ChangePin("1234678", "1111", "1212", "1212"); Assert.IsFalse(result); }
  • 38.
    Copyright © GasparNagyCopyright © Gaspar Nagy Specification by example Problem Domain Solution Domain Lightbulb by Unknown Author is licensed under CC BY-SA The old PIN should be correct public void VerifyOldPin(string enteredOldPin) { var db = new CardRespoitory(); var oldPin = db.LoadOldPin(CurrentCard); if (oldPin != enteredOldPin) { throw new InvalidPinException(); } } Implements [TestMethod] public void ShuldFailWhenOldPinIncorrect() { var cardStoreMock = new CardStoreMock(); cardStoreMock.SetCard("1234678", "1234"); var sut = new CardService(); var result = sut.ChangePin("1234678", "1111", "1212", "1212"); Assert.IsFalse(result); } Old PIN is incorrect • PIN is 1234 • Enter old PIN: 1111 • Change PIN ⇒ PIN change rejected Illustrates Automates
  • 39.
    Copyright © GasparNagyCopyright © Gaspar Nagy Codified tests are hard to maintain • What was the example? • Why were these numbers used? • What did we want to verify? [TestMethod] public void ShuldFailWhenOldPinIncorrect() { var cardStoreMock = new CardStoreMock(); cardStoreMock.SetCard("1234678", "1234"); var sut = new CardService(); var result = sut.ChangePin("1234678", "1111", "1212", "1212"); Assert.IsFalse(result); }
  • 40.
    Copyright © GasparNagyCopyright © Gaspar Nagy BDD is here to help?
  • 41.
    Copyright © GasparNagyCopyright © Gaspar Nagy Formulated BDD scenarios Problem Domain Solution Domain The old PIN should be correct public void VerifyOldPin(string enteredOldPin) { var db = new CardRespoitory(); var oldPin = db.LoadOldPin(CurrentCard); if (oldPin != enteredOldPin) { throw new InvalidPinException(); } } Implements Old PIN is incorrect • PIN is 1234 • Enter old PIN: 1111 • Change PIN ⇒ PIN change rejected Illustrates Scenario: Old PIN is incorrect Given my old pin is 1234 And I enter 1111 as old PIN When I try to change my PIN Then the PIN change should be rejected [Then] public void I_enter_PIN_as_old_pin(string pin) { changePinContext.SetOldPin(pin); } [When] public void I_enter_PIN_as_old_pin(string pin) { changePinContext.SetOldPin(pin); } [Given] public void I_enter_PIN_as_old_pin(string pin) { changePinContext.SetOldPin(pin); }
  • 42.
    Copyright © GasparNagyCopyright © Gaspar Nagy Behavior Driven Development Problem Domain Solution Domain Lightbulb by Unknown Author is licensed under CC BY-SA REQ APP Given When Then SPECS Validates Verifies
  • 43.
    Copyright © GasparNagyCopyright © Gaspar Nagy Behavior Driven Development is about understanding & validating business requirements through illustrative examples
  • 44.
    Copyright © GasparNagyCopyright © Gaspar Nagy BDD is not about tests!
  • 45.
    Copyright © GasparNagyCopyright © Gaspar Nagy Functional quality is not only about whether IT WORKS as expected… but also about whether the EXPECTATIONS ARE GOOD and DOCUMENTED… Functional quality
  • 46.
    Episode in alater season… PO: We have got a strange prod issue. Could we look into that? Team: Sure. Let’s have a look at the related BDD scenarios… PO: I see. I think there is an important case we did not detail enough…
  • 47.
    Copyright © GasparNagyCopyright © Gaspar Nagy Happy ending
  • 48.
    Copyright © GasparNagyCopyright © Gaspar Nagy Finally I’ve got a dream-project again • It was a complex service used by hundreds of apps and through them millions of users all over the world • Processed several thousands of requests per second • Was critical in the client’s service chain • We rolled it out without any severe issues… • And we knew that there will be no problems… • Because we had shared control over the specs (BDD scenarios) • And this gave us confidence to push the release button
  • 49.
    Copyright © GasparNagyCopyright © Gaspar Nagy Continuous deployment is about CONFIDENCE …and you need to keep the link to the problem domain to gain that
  • 50.
    Why was myfirst project working? • Short cycles • Instant release • Close to “business” but also close to users
  • 51.
    Copyright © GasparNagyCopyright © Gaspar Nagy Think about YOUR tests… Are they also linking the solution with the problem?
  • 52.
  • 53.
    Thank you! Gáspár Nagy coach• trainer • bdd addict • creator of specflow “The BDD Books: Discovery” • http://bddbooks.com @gasparnagy • gaspar@specsolutions.eu
  • 54.
    Copyright © GasparNagyCopyright © Gaspar Nagy