0
Kodas ir specifikacijadu zuikiai vienu šūviucode specOsvaldas GrigasVadim Platonov
What happens next● Motivation● Case study● Live demo
Specification?Requirements?Scenarios?Documentation?User stories?What do we need?Test cases?Use cases?Code?amples?Accepta
Start with the code?
Requirements?
Specifications?
Test Cases?
codeSpecificationRequirementsTest Cases
What did we try?
Behavior-DrivenDevelopment
BDD?
Domain experts + DevsSpecify scenarios in plain textDevsAutomate scenarios as testsJenkinsPublish scenarios to WikiDomain ...
Lets Make a Payment.
Domain expertsDescribe a featureAccount can only be debited ifit has sufficient balance and isnot blocked for debit.
Domain experts + DevsSpecify scenariosScenario: Debiting an account with sufficient balanceGiven a liability account LT000...
DevsAutomated scenarios as testspublic class DebitAccountextends JUnitStory {@Given("a $type account $number with a balanc...
Room forimprovement
Developershave to maintain stories, test code and their mappingCOOL
What if...specifications were generated from test code?
Business language● gets lost in implementation details● is not enforced in codeCOOL
What if...core parts of production code were reflectedin specifications?
Specifyscenariosin plain textAutomatescenariosas testsSpecifyscenariosin code
Story: Debiting an accountScenario: Sufficient balanceGiven: Account with● id: LT000001● balance: USD 100● balance type: L...
codeYes I can! *
public class Debiting_an_accountextends Story<Account, DebitAccount> {@Testpublic void sufficient_balance() {givenEvents(n...
DDD? CQRS?EventSourcing?
Domain-Driven DesignCrash Course
DDDUbiquitous LanguageAccountDebitCreditAssetLiabilityBalance
public class Debiting_an_accountextends Story<Account, DebitAccount> {@Testpublic void sufficient_balance() {givenEvents(n...
DDDEntitypublic class Account extends AggregateRoot {private Balance balance;public void credit(Amount amount) { ... }publ...
public class Debiting_an_accountextends Story<Account, DebitAccount> {@Testpublic void sufficient_balance() {givenEvents(n...
DDDIsolated DomainDomaindata storemessagebrokerclient services
Event Sourcing Crash Course
EventsCapture all changes to domain statepublic class AccountDebited {public String accountNumber;public BigDecimal amount...
EventsNever lose dataAccountCreated 0AccountCredited 300AccountCredited 1000AccountCredited 1500AccountDebited 900AccountC...
public class Debiting_an_accountextends Story<Account, DebitAccount> {@Testpublic void sufficient_balance() {givenEvents(n...
Command-QueryResponsibilitySegregationCrashCourse
Read ModelCQRSWrite ModelQueryCommand
CQRSCommandpublic class DebitAccount {public final String accountNumber;public final BigDecimal amount;public final String...
public class Debiting_an_accountextends Story<Account, DebitAccount> {@Testpublic void sufficient_balance() {givenEvents(n...
Putting it all together
MongoDBDomain(Aggregates)Projectors(Groovy)CommandHandlersQueryServicesClient(Wicket)Event StoreEventsEventsCommands Proje...
Domain(Aggregates)CommandHandlersUser StoryTestsEventsCommandsMockEvent StoreEventsEventsTestingthe Domain
Live DemoCoding Specifications
AttributionsPhoto: Accidents - after crash 1978 SkodaAuthor: Istvan TakacsURL: http://commons.wikimedia.org/wiki/File:Acci...
Upcoming SlideShare
Loading in...5
×

Kodas ir specifikacija: du zuikiai vienu šūviu

414

Published on

Osvaldo Grigo ir Vadim Platonov pranešimas "Kodas ir specifikacija: du zuikiai vienu šūviu" skaitytas Agile dienoje 2013 gegužės 9 d.

Kaip Behavior-Driven Development idėjas pritaikėme kurdami finansinių paslaugų valdymo sistemą. Kaip galima kodą paversti pirminiu tiesos šaltiniu, kai automatizuotais testais užrašomi reikalavimai.
Trumpai supažindinsime su mūsų architektūros specifika, paremta DDD, CQRS ir Event Sourcing principais, kurie atveria naujas galimybes, bet kartu atneša naujų iššūkių. Kokias darėme klaidas, ir kaip jų išvengti.

Published in: Technology, Business
0 Comments
4 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
414
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
4
Comments
0
Likes
4
Embeds 0
No embeds

No notes for slide

Transcript of "Kodas ir specifikacija: du zuikiai vienu šūviu"

  1. 1. Kodas ir specifikacijadu zuikiai vienu šūviucode specOsvaldas GrigasVadim Platonov
  2. 2. What happens next● Motivation● Case study● Live demo
  3. 3. Specification?Requirements?Scenarios?Documentation?User stories?What do we need?Test cases?Use cases?Code?amples?Accepta
  4. 4. Start with the code?
  5. 5. Requirements?
  6. 6. Specifications?
  7. 7. Test Cases?
  8. 8. codeSpecificationRequirementsTest Cases
  9. 9. What did we try?
  10. 10. Behavior-DrivenDevelopment
  11. 11. BDD?
  12. 12. Domain experts + DevsSpecify scenarios in plain textDevsAutomate scenarios as testsJenkinsPublish scenarios to WikiDomain expertsDescribe features
  13. 13. Lets Make a Payment.
  14. 14. Domain expertsDescribe a featureAccount can only be debited ifit has sufficient balance and isnot blocked for debit.
  15. 15. Domain experts + DevsSpecify scenariosScenario: Debiting an account with sufficient balanceGiven a liability account LT000001 with a balance of 100 USD,not blocked for debitWhen the account LT000001 is debited for 20 USDThen the debit succeeds producing a running balance of 80 USD
  16. 16. DevsAutomated scenarios as testspublic class DebitAccountextends JUnitStory {@Given("a $type account $number with a balance of$balance USD, $debitStatus for debit")public void givenAnAccount(String type, String number,int balance, String debitStatus) {// ...}@When("the account $number is debited for $amount USD")public void whenAccountIsDebitedBy(String number, int amount) {// ...}@Then("the debit $result producing a running balance of $balance USD")public void thenDebitResultsIn(String result, int balance) {// ...}}
  17. 17. Room forimprovement
  18. 18. Developershave to maintain stories, test code and their mappingCOOL
  19. 19. What if...specifications were generated from test code?
  20. 20. Business language● gets lost in implementation details● is not enforced in codeCOOL
  21. 21. What if...core parts of production code were reflectedin specifications?
  22. 22. Specifyscenariosin plain textAutomatescenariosas testsSpecifyscenariosin code
  23. 23. Story: Debiting an accountScenario: Sufficient balanceGiven: Account with● id: LT000001● balance: USD 100● balance type: Liability● additional currency support: Disallowed● debiting allowed: Yes● crediting allowed: YesWhen: Debit account with● account number: LT000001● amount: 20● currency: USDThen: Account debited● with amount 20● with running balance 80● with currency "USD"codeCan I dothat?
  24. 24. codeYes I can! *
  25. 25. public class Debiting_an_accountextends Story<Account, DebitAccount> {@Testpublic void sufficient_balance() {givenEvents(new AccountCreated("LT000001", "USD", LIABILITY),accountCredited("LT000001", "any", $(30, "USD")),accountCredited("LT000001", "any", $(70, "USD")));onCommand(new DebitAccount("LT000001", "any", $(20), "USD"));expectEvent(AccountDebited.class).with("amount", $(20)).with("runningBalance", $(80)).with("currency", "USD");}}
  26. 26. DDD? CQRS?EventSourcing?
  27. 27. Domain-Driven DesignCrash Course
  28. 28. DDDUbiquitous LanguageAccountDebitCreditAssetLiabilityBalance
  29. 29. public class Debiting_an_accountextends Story<Account, DebitAccount> {@Testpublic void sufficient_balance() {givenEvents(new AccountCreated("LT000001", "USD", LIABILITY),accountCredited("LT000001", "any", $(30, "USD")),accountCredited("LT000001", "any", $(70, "USD")));onCommand(new DebitAccount("LT000001", "any", $(20), "USD"));expectEvent(AccountDebited.class).with("amount", $(20)).with("runningBalance", $(80)).with("currency", "USD");}}
  30. 30. DDDEntitypublic class Account extends AggregateRoot {private Balance balance;public void credit(Amount amount) { ... }public void debit(Amount amount) { ... }}
  31. 31. public class Debiting_an_accountextends Story<Account, DebitAccount> {@Testpublic void sufficient_balance() {givenEvents(new AccountCreated("LT000001", "USD", LIABILITY),accountCredited("LT000001", "any", $(30, "USD")),accountCredited("LT000001", "any", $(70, "USD")));onCommand(new DebitAccount("LT000001", "any", $(20), "USD"));expectEvent(AccountDebited.class).with("amount", $(20)).with("runningBalance", $(80)).with("currency", "USD");}}
  32. 32. DDDIsolated DomainDomaindata storemessagebrokerclient services
  33. 33. Event Sourcing Crash Course
  34. 34. EventsCapture all changes to domain statepublic class AccountDebited {public String accountNumber;public BigDecimal amount;public BigDecimal runningBalance;public String currency;}
  35. 35. EventsNever lose dataAccountCreated 0AccountCredited 300AccountCredited 1000AccountCredited 1500AccountDebited 900AccountCredited 1200AccountDebited 800AccountDebited 700timeBalance
  36. 36. public class Debiting_an_accountextends Story<Account, DebitAccount> {@Testpublic void sufficient_balance() {givenEvents(new AccountCreated("LT000001", "USD", LIABILITY),accountCredited("LT000001", "any", $(30, "USD")),accountCredited("LT000001", "any", $(70, "USD")));onCommand(new DebitAccount("LT000001", "any", $(20), "USD"));expectEvent(AccountDebited.class).with("amount", $(20)).with("runningBalance", $(80)).with("currency", "USD");}}
  37. 37. Command-QueryResponsibilitySegregationCrashCourse
  38. 38. Read ModelCQRSWrite ModelQueryCommand
  39. 39. CQRSCommandpublic class DebitAccount {public final String accountNumber;public final BigDecimal amount;public final String currency;}
  40. 40. public class Debiting_an_accountextends Story<Account, DebitAccount> {@Testpublic void sufficient_balance() {givenEvents(new AccountCreated("LT000001", "USD", LIABILITY),accountCredited("LT000001", "any", $(30, "USD")),accountCredited("LT000001", "any", $(70, "USD")));onCommand(new DebitAccount("LT000001", "any", $(20), "USD"));expectEvent(AccountDebited.class).with("amount", $(20)).with("runningBalance", $(80)).with("currency", "USD");}}
  41. 41. Putting it all together
  42. 42. MongoDBDomain(Aggregates)Projectors(Groovy)CommandHandlersQueryServicesClient(Wicket)Event StoreEventsEventsCommands ProjectionsProjectionsEvents
  43. 43. Domain(Aggregates)CommandHandlersUser StoryTestsEventsCommandsMockEvent StoreEventsEventsTestingthe Domain
  44. 44. Live DemoCoding Specifications
  45. 45. AttributionsPhoto: Accidents - after crash 1978 SkodaAuthor: Istvan TakacsURL: http://commons.wikimedia.org/wiki/File:Accidents_-_after_crash_1978_Skoda.jpgLicense: http://creativecommons.org/licenses/by-sa/3.0/deed.enPhoto: Tram in Kraków, PolandAuthor: AstrorekURL: http://commons.wikimedia.org/wiki/File:Tramwaj_krakow_3.jpgLicense: http://creativecommons.org/licenses/by-sa/3.0/deed.enPhoto: Mokate 3in1© Copyright 2013 Mokate S.A.URL: http://www.mokate.eu/Image: JBehave examples@ Copyright JBehaveURL: http://jbehave.org/Image: Rainbow@ Copyright MoonglowlillyURL: http://moonglowlilly.deviantart.com/art/PNG-RAINBOW-324144428Image: Debit cardURL: http://www.capitalistbanter.com/2011/05/featured/the-best-and-worst-time-to-use-a-debit-card/
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×