I don't know how about you, but I'm a great fan of TDD. Seriously, I find it to be one of the best practices I have in my toolbox. Nevertheless it has some limitations.
TDD does a great job for you if you are a developer. It focuses on the low level allowing to simulate any possible situation in any given component. It keeps your brain busy working out the best ways to write the system in a testable fashion making use of the good design patterns and practices. Another important feature - protects you from over-engineering by setting the scope early - implement just enough to make the tests pass and nothing else. Not to say that you get the tests automation for almost free. That's all well known and cool, except for the last thing.
I've witnessed it many times that even though you've done a great job applying TDD, it is useless for anyone other than programmers. Unit-tests are all about the low level components in isolation. They cannot be read by non-devs. Understanding the component structure is also tricky. OOP was supposed to simplify things by making programs talk in the domain terms and UML would visualise it. This seemed to be a great idea in the past, but looks like we are getting dumber or OOP and UML do not actually solve the problem.
Anyway, what I was seeing on my previous projects is that even though we had great number of tests and a decent coverage, this was useless for our quality control and the QA folks were doing their own testing often duplicating the effort since they could not use and control the product of the TDD. It's just in the wrong format. Even I do struggle understanding some tests after a couple of months.
BDD brings the two worlds closer together, but it's not a replacement for TDD, it's just a level on top of it. See the Test Automation Pyramid.
As there is more control introduced over the software testing these days in my industry, I don't find it wise to discard the valuable information. So I started looking around to make my tests more readable.
Before that, I was giving my test cases three component names -
public void Add_2and2_ShouldReturn4()
var calc = new Calc();
var result = calc.Add(2, 2);
Unfortunately, the last two can become quite verbose if you have more than one assertion of a complicated context setup. Keeping them short makes you lose the details and end up with too generic phrases.
After having some good time applying BDD with SpecFlow, I fell in love with the Gherkin Given-When-Then syntax. Literally, the three component test case name is the same. I tried using SpecFlow for unit-tests but it wasn't that nice. Productivity went down. Additional steps were needed to generate the steps from text and regenerate them after rephrasing - as the result more time lost.
So I was actually wanting something C#-pish with a bit Gherkin flavour. After asking some collegues and Googling for a while, I've figured out the best option for me - the StoryQ. I also decided to switch to FluentAssertions from
Nunit Assert.That(). It forms better messages which in combination with StoryQ brings awesome results!
Here are some samples from the
public class DemoTest
public void PassingExample()
new Story("Data Safety").Tag("sprint 1")
.InOrderTo("Keep my data safe")
.IWant("All credit card numbers to be encrypted")
.WithScenario("submitting shopping cart")
The output is as follows:
Story is Data Safety => (#sprint 1)
In order to Keep my data safe
As a User
I want All credit card numbers to be encrypted
With scenario submitting shopping cart
Given I have typed my credit card number into the checkout page => Passed
When I click the Buy button => Passed
And the browser posts my credit card number over the internet => Passed
Then the form should be posted over https => Passed
Meaningful tests and the output, what a joy!