B D D
Behavior Driven Development
In 360 seconds !
B D D = T D D evolved
Following slides are going to demonstrate that in Java
STARTING T D D
public class TradeTest {
@Test
public void checkNoAlertUnderThreshold() {
TradingServices ts = new TradingServices(...);
Stock s = ts.createStock("STK", 15.0);
ts.tradeAt(s, 5);
Assert.assertEquals("OFF", s.getAlertStatus());
}
@Test
public void checkAlertAboveThreshold() {
TradingServices ts = new TradingServices(...);
Stock s = ts.createStock("STK", 4.0);
ts.tradeAt(s, 5);
Assert.assertEquals("ON", s.getAlertStatus());
}
}
T D D going out of control
More use cases => More tests => more code repeated :
-
construct TradingServices
- if constructor change, I need to change everywhere
- create a stock / trade a stock
- if signature change, I need to change everywhere
- if method is moved to another class ...
- check the status
- assertEquals("OFF", s.getStatus()) : is that comprehensive testing ?
- => Refactoring
T D D BACK UNDER CONTROL
public class TradeTest {
TradeSteps steps = new TradeSteps();
@Test
public void checkNoAlertUnderThreshold() {
steps.givenStock("STK", 5);
steps.whenTradeStockAt("STK", 4);
steps.thenAlert("STK", "OFF");
}
@Test
public void checkAlertAboveThreshold() {
steps.givenStock("STK", 4);
steps.whenTradeStockAt("STK", 5);
steps.thenAlert("STK", "ON");
}
}
T D D BACK UNDER CONTROL
public class TradeSteps {
TradingServices ts = new TradingServices(...);
Map<String, Stock> stocks = new Map();
public void gicenStock(Sting name, Double threshold) {
stocks.put(name, ts.createStock(name, threshold));
}
public void tradeAt(String name, Double value) {
ts.tradeAt(stocks.get(name), value);
}
public void thenAlert(String name, String status) {
Assert.assertEquals(status, stocks.get(name).getStatus());
}
}
BENEFITS OF REFACTORING
- The test are more readable (given / when / then)
- but not as readable as plain english
- The steps are reusable accross tests and easy to write
- provided they are only doing one thing
- and instanciating steps is easy
- if the constructor or method signature change :
- no need to change, I just need to write another step and to mock additional parameters
- BUT what if I need more :
- HTML reports readable by business analysts
- What EXACTLY is going wrong : the "given" or the "when" or the "then"
B D D
Scenario : no alert when trade under threshold
Given stock STK with threshold 5.0
When I trade STK at 4.0
Then the alert status of STK is OFF
Scenario : alert when trade above threshold
Given stock STK with threshold 4.0
When I trade STK at 5.0
Then the alert status of STK is ON
B D D
public class TradeSteps {
@Given("stock $name with threshold $t")
public void givenStock(String name, Double threshold) {}
@When("I trade $name at $v")
public void whenTradeStock(String name, Double value) {}
@Then("the alert status of $name is $s")
public void thenAlert(String name, String status) {}
}
B D D
B D D benefits OVER T D D
- Same benfits as T D D
- agreement on behavior before implementation (but we can agree in plain english)
- enforce good design (ex : dependency injection)
- free regression testing
- free documentation
- Speaks the business language, not programmer language
- Better communication
- Unambiguous for analysts, testers and programmers
- Easy refactoring of code since scenario do not change
SCALING B D D
- Use dependency injection from your app
public class StepsFactory {
DatasourceFactory dsF = new DatasourceFactory(...);
Factory f = new Factory(dsF);
public TradeSteps tradeSteps() {
return new TradeSteps(f.tradeServices());
}
}
SCALING B D D
- Use Continuous Integration
- The BDD framework must integrate with your CI server
- ex : jBehave is a jUnit extension
=> native support with all CI servers that support jUnit
=> native support with all CI servers that support java
SCALING B D D
- Treat Steps as production code (even if they are untested)
- group steps together but keep classes small
- ideally, one steps per service
- CreateStockServices => CreateStockSteps
- TradeStockServices => TradeStockSteps
BDD
By Christophe Blin
BDD
What is Bdd ? Why use it ?
- 2,560