I've just come across BBD and specflow and it looks very interesting. When writing user stories they are typically on a high-level and the actor users the GUI. So when writing scenarios they will typically be GUI test or integration test from a high level of the system. But what about unit test further down in the solution? E.g. service endpoints, business objects, etc. Should I write new scenarios for those or is there a way to reuse the same scenarios for low level testing (unit tests) or should I copy and past the scenarios?
Please let me know if I have got it all wrong.
BDD frameworks like SpecFlow are designed to help technical team members communicate more easily with non-technical stakeholders of a project.
The English-language specs aren't easy to maintain or refactor. Since the only people who read unit-level tests or examples are technical and able to read code, I prefer to use unit-testing frameworks such as NUnit at that level.
Scenarios often have far more complexity in them than unit tests. Normally I find that they cover a number of combinations of internal business logic, and each aspect which makes up a combination will be the responsibility of a different unit of code. The logic in the scenarios will therefore be split up amongst a number of different unit tests, and you won't be able to copy them.
Sometimes I use the scenarios to guide my unit tests. I might find that a bit of logic ends up being the responsibility of a particular unit of code, and then I can copy just the relevant steps from the scenario into the unit tests as a comment.
// Given I have $100 in my account
var account = new Mock<Account>();
account.SetupGet(a => a.Balance).Returns(100);
var accountProvider = new Mock<AccountProvider>();
accountProvider.Setup(ap => ap.AccountFor("lunivore")).Returns(account);
// When I ask for $20
var atm = new ATM(accountProvider);
atm.PutInCardFor("lunivore");
int money = atm.RequestMoney(20);
// Then I should get $20
Assert.AreEqual(20, money);
// And my account should have paid out $20
account.verify(a => a.PayOut(20));
I encourage you to copy the language in which the scenarios are written (eg: PayOut
). This is aligned with Domain Driven Design's "ubiquitous language". Carrying that language into both unit tests and code also helps a team converse with stakeholders, because you won't have to do the translation over and over.
Putting Given / When / Then into comments also really helps me focus on delivering code that's actually going to be used, instead of trying to guess at all the edge cases. The best quality code is the stuff you don't write.
Good luck!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With