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.
12. Domain experts + Devs
Specify scenarios in plain text
Devs
Automate scenarios as tests
Jenkins
Publish scenarios to Wiki
Domain experts
Describe features
14. Domain experts
Describe a feature
Account can only be debited if
it has sufficient balance and is
not blocked for debit.
15. Domain experts + Devs
Specify scenarios
Scenario: Debiting an account with sufficient balance
Given a liability account LT000001 with a balance of 100 USD,
not blocked for debit
When the account LT000001 is debited for 20 USD
Then the debit succeeds producing a running balance of 80 USD
16. Devs
Automated scenarios as tests
public class DebitAccount
extends 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) {
// ...
}
}
34. Events
Capture all changes to domain state
public class AccountDebited {
public String accountNumber;
public BigDecimal amount;
public BigDecimal runningBalance;
public String currency;
}
35. Events
Never lose data
AccountCreated 0
AccountCredited 300
AccountCredited 1000
AccountCredited 1500
AccountDebited 900
AccountCredited 1200
AccountDebited 800
AccountDebited 700
time
Balance
36. public class Debiting_an_account
extends Story<Account, DebitAccount> {
@Test
public 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");
}
}