# Emergent Architecture with TDD/BDD
James Kovacs @jameskovacs
James is very clearly Canadian (not that there is anything wrong with that)
Software is VERY different from physical engineering
“Blueprints” are not really useful in software in the same way
Various attempts to achieve that, especially UML and tools like Rational Rose, have failed
THEY ARE USEFUL for visualizing, but not for designing
These up front diagrams don’t usually survive actual development and end up sitting on a shelf
UML IS a great whiteboarding tool, though
Executable specifications was the holy grail that UML was trying to achieve.
So, we can use BDD frameworks/tools to achieve this instead.
We end up with code that we can use to explore scalability, adaptability, etc.
The demands of architecture are that you code less and less, which is the wrong way to go – the architect should be blazing the trail and figuring out the way to go BY WRITING CODE, not writing documents and diagrams
TDD is a skill and will take some time until you feel comfortable. James said it took him six months to feel comfortable.
TDD is about DESIGN
The last responsible moment – you know the least at the start of a project and learn more as time goes on, so you should delay any decisions until the last RESPONSIBLE moment. You still need to do SUFFICIENT architecture, design, and documntation.
You have to work out the risky parts of the application early – things that might not perform well, might become bottlenecks, etc.
We need to be prepared to throw out bad code/bad experiements. The learning is the value – don’t be afraid to throw away code because it is written already if it doesn’t perform well.
Ping Pong Pairing – one dev writes a test, the other writes the code to pass it and then writes another test and passes control back to the other dev.
You should pair with multiple people during the course of an interation. This helps share the architecture and encourages common code ownership.
## Given, When, Then
Given a shopping cart with a single item
When an identical item is added
Then the quanity of the single item should be incremented
You can specify architectural concerns in specifications (performance, scalability, other -ilities)
Given is the state of the world coming in to the test.
When is the SINGLE action that is being taken
Then is the result of that action. You might have several assertions – you want to make sure all of the resulting states within your system are correct. This is different from unit tests where you really only want to have one assertion per test.
MSpec is available via Nuget. The only caveat is the first time you install MSpec you need to run a batch file in it’s tools folder to set up integration with Resharper (you are using resharper, right?).
Write your test names in English with the words separated by underscores – more ruby style than C# style.
You are writing your specifications in C# with Visual Studio.
MSpec is very much not Business Analyst friendly and probably not tester friendly unless your testers know how to write code (which in my opinion they should, but that’s beside the point).
You write an outer class that defines the context (the “Given”) and then put inner classes for each “When” and “Then”.
You can go through the user interface via Selenium or WatiN – MSpec can drive them.
MSpec can produce a nicely formatted HTML report.
Or you could use SpecFlow. SpecFlow uses plain text files lightly formatted with Gerkin keywords (Gerkin comes from the Cucumber testing tool, a ruby thing)
SpecFlow has an extension that installs into Visual Studio that has templates, IntelliSense/Syntax Highlighting, and a runner.
You write step definitions in C# code that map the English language text to code. If you run a spec that doesn’t have backing code, the runner will tell you what code you need to write (it actually generates the code) to back the step.
The extension for the SpecFlow text files is .feature
The English language is in an attribute on the method that implements the step and is matched with the text speciifcation via Regex.
It is brittle in the sense that if your text string don’t match it will break.
It actually needs a unit test runner behind it – there is a build step that turns your specification files into unit tests. It can use either NUnit or MSTest (NUnit is the default).