<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.conchango.com/utility/FeedStylesheets/atom.xsl" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><title type="html">James Broome Blog</title><subtitle type="html" /><id>http://blogs.conchango.com/jamesbroome/atom.aspx</id><link rel="alternate" type="text/html" href="http://blogs.conchango.com/jamesbroome/default.aspx" /><link rel="self" type="application/atom+xml" href="http://blogs.conchango.com/jamesbroome/atom.aspx" /><generator uri="http://communityserver.org" version="2.1.20423.1">Community Server</generator><updated>2008-07-08T16:51:00Z</updated><entry><title>The fast and the furious - Developer Productivity</title><link rel="alternate" type="text/html" href="http://blogs.conchango.com/jamesbroome/archive/2008/07/31/the-fast-and-the-furious-developer-productivity.aspx" /><id>http://blogs.conchango.com/jamesbroome/archive/2008/07/31/the-fast-and-the-furious-developer-productivity.aspx</id><published>2008-07-31T20:12:00Z</published><updated>2008-07-31T20:12:00Z</updated><content type="html">&lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;I'm a big fan of anything that can make me work faster - working on an agile project can be at quite a hectic pace and anything that can save me a couple of minutes, especially if its something I do often is a good thing.&lt;/p&gt;  &lt;p&gt;I spoke at our last community day about &lt;a href="http://dannorth.net/introducing-bdd" target="_blank"&gt;Behaviour Driven Development&lt;/a&gt; and why &lt;a href="http://blogs.conchango.com/jamesbroome/archive/2008/07/22/why-bdd-works-for-agile.aspx" target="_blank"&gt;I thought it really fitted with agile&lt;/a&gt; processes. After the session a colleague commented on my use of the keyboard and even went as far as to say he was impressed that I hadn't used the mouse at all when demo-ing the code I was talking about. Now a compliment is a compliment and I'll take it, but I actually remember thinking at the time that I was being really clumsy and slow - I think my nerves got to me a bit talking in front of 40 or so people, and everyone knows that you can't type when someone's watching!&amp;nbsp; &lt;/p&gt;  &lt;p&gt;But it got me thinking that as I've been using &lt;a href="http://www.jetbrains.com/resharper/" target="_blank"&gt;ReSharper&lt;/a&gt; for about a year or so now that was I starting to take it for granted that everyone else had too. &lt;/p&gt;  &lt;p&gt;So, I thought I'd expand on that a little and compile a short list of tools that I use on a daily basis that makes my life easier and quicker. There's generally a learning curve involved in each one, even just adjusting your mindset to &lt;a href="http://www.bioinformaticszen.com/2007/08/be-more-productive-throw-away-your-mouse/" target="_blank"&gt;not reach for the mouse&lt;/a&gt;! This isn't entirely altruistic, as I'm really looking for suggestions on more! &lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;h4&gt;&lt;a href="http://www.launchy.net/" target="_blank"&gt;Launchy&lt;/a&gt; &lt;/h4&gt;  &lt;p&gt;When you really get into the keyboard mindset, you want to start using it for every application. This tool enables you to launch any application without the need to reach for the mouse, so your fingers are ready to go as soon as it fires up! Alt+Enter is the default shortcut. Type "firefox" and hit Enter to launch the next tool... (after a few times, Launchy predicts what you want as you type, so I can now launch Firefox with just an "f").&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;h4&gt;&lt;a href="http://www.mozilla.com/en-US/firefox/" target="_blank"&gt;Firefox extensions&lt;/a&gt; &lt;/h4&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;So everyone knows that Firefox is awesome, but for me its the extensions that make it totally indispensable.&amp;nbsp; Here's a few that I use:&lt;/p&gt;  &lt;blockquote&gt;   &lt;h4&gt;&lt;a href="https://addons.mozilla.org/en-US/firefox/addon/1843" target="_blank"&gt;Firebug&lt;/a&gt;&lt;/h4&gt;    &lt;p&gt;I don't know how anyone can be a web developer without it. No more hours spent tweaking CSS files and hitting F5 to find that you have no idea what you're actually doing and that you really don't understand CSS. I can now muck in with the iDevs (although there is an argument for saying that a little knowledge in the wrong hands is a dangerous thing!)&lt;/p&gt;    &lt;p&gt;&amp;nbsp;&lt;/p&gt;    &lt;h4&gt;&lt;a href="https://addons.mozilla.org/en-US/firefox/addon/1341" target="_blank"&gt;Hit a Hint&lt;/a&gt; &lt;/h4&gt;    &lt;p&gt;A keyboard navigation extension for Firefox. Who said that you had to use the mouse when browsing the web?! Just hit "h" and watch numbers appear by every link on the page. Type your number, hit enter and away you go.&lt;/p&gt;    &lt;p&gt;&amp;nbsp;&lt;/p&gt;    &lt;h4&gt;Google toolbar&lt;/h4&gt;    &lt;p&gt;Not really an extension as such but gives you the ability to search Google from any page within Firefox. Ctrl+K to jump straight to it, and a cheeky Alt+Enter opens the results in a new tab. Nice.&lt;/p&gt;    &lt;p&gt;So, if we start to string them together - you've got an Alt+Space, an f for Firefox and Enter in Launchy, a Ctrl+K, enter your search term and hit enter. How often do you search Google in a day? Even shaving 10 seconds off this is going to save years in your life! (I have not actually worked this out).&lt;/p&gt;    &lt;p&gt;UPDATE! Woah! - in the space of writing this post, I've just learnt that there's an even quicker way through Lanuchy :&lt;/p&gt;    &lt;p&gt;Alt+Enter, "google", Tab, "Search term", Enter and there you go - even quicker. And once you've done this once, Launchy is predicting that you want Google after "goo" so you don't even have to type it out in full.&lt;/p&gt; &lt;/blockquote&gt;  &lt;blockquote&gt;   &lt;h4&gt;&amp;nbsp;&lt;/h4&gt;    &lt;h4&gt;&lt;a href="https://addons.mozilla.org/en-US/firefox/addon/3615" target="_blank"&gt;Delicious Bookmarks&lt;/a&gt;&lt;/h4&gt;    &lt;p&gt;If, like me, you use Delicious to manage you bookmarks, you can use the Delicious Bookmarks extension to access them directly through Firefox. No more manual synchronisation between laptops - you can even hide the standard bookmarks menu to ensure that all links are stored in the cloud. And there's lots of nice keyboard shortcuts to jump to and tag new links.&lt;/p&gt; &lt;/blockquote&gt;  &lt;blockquote&gt;   &lt;p&gt;&amp;nbsp;&lt;/p&gt;    &lt;h4&gt;&lt;a href="https://addons.mozilla.org/en-US/firefox/addon/38630" target="_blank"&gt;iMacros&lt;/a&gt;&lt;/h4&gt;    &lt;p&gt;If you're a web developer and spend a lot of time repeating the same repetitive tasks over and over again to test your site, use this to automate anything possible. On my current project, I often have to launch the site and log in before I can test some functionality, so I have a macro that does this for me. &lt;/p&gt;    &lt;p&gt;I no longer have to wait for the application to spin up before I click Log In and manually enter the info, instead I can use the macro to do this for me whilst I get on with something else. &lt;/p&gt;    &lt;p&gt;The beauty of these macros is that they can be bookmarked (and it integrates with Delicious) so I can access them from anywhere and by using the keyboard.&lt;/p&gt;    &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;/blockquote&gt;  &lt;h4&gt;&lt;a href="http://www.testdriven.net" target="_blank"&gt;TestDriven.Net&lt;/a&gt;&lt;/h4&gt;  &lt;p&gt;On my current project we use the MSTest automated test tools that are integrated within Visual Studio. Whilst I believe that one testing framework is fairly similar to another, I really dislike the Test View and other test management windows that you get with MSTest. Test Driven.Net integrates with MSTest so that you can pop-up a menu using the right-click button or a keyboard shortcut and run the tests directly from where you are. Also the Repeat Test Run option is really good for doing just that, from wherever you are in the solution.&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;h4&gt;&lt;a href="http://www.jetbrains.com/resharper/" target="_blank"&gt;ReSharper&lt;/a&gt;&lt;/h4&gt;  &lt;p&gt;So I've saved the best (beast?) till last. If could go on and on about how much I love ReSharper how I could no longer work without it. I'm not going to list out why its awesome as it would take too long, but if this is new to you then I would start by reading this:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blog.excastle.com/2007/01/31/blog-event-the-31-days-of-resharper/" title="http://blog.excastle.com/2007/01/31/blog-event-the-31-days-of-resharper/"&gt;http://blog.excastle.com/2007/01/31/blog-event-the-31-days-of-resharper/&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;and then watching some of this:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.jameskovacs.com/blog/BecomingAJediPart3OfN.aspx" title="http://www.jameskovacs.com/blog/BecomingAJediPart3OfN.aspx"&gt;http://www.jameskovacs.com/blog/BecomingAJediPart3OfN.aspx&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;I would consider myself an intermediate ReSharper user - able to make someone's day with a helpful shortcut thrown in when pair programming or just looking over someone's shoulder, but I'm still far from being a &lt;a href="http://blogs.jetbrains.com/dotnet/2007/05/the-resharper-jedi/" target="_blank"&gt;Jedi&lt;/a&gt; as they say. &lt;/p&gt;  &lt;p&gt;Through working at Conchango, in the last 6 months I've had the pleasure of meeting both &lt;a href="http://www.ayende.com/Blog/" target="_blank"&gt;Oren Eini&lt;/a&gt; and &lt;a href="http://www.jpboodhoo.com/Home.oo" target="_blank"&gt;Jean-Paul Boodhoo&lt;/a&gt; and watching them code first hand and it really is mind blowing stuff. Hopefully this post has had even just a fraction of the impact that those situations had on me in realising what is possible and that constant self improvement is a scary but awesome thing!&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;img src="http://blogs.conchango.com/aggbug.aspx?PostID=12092" width="1" height="1"&gt;</content><author><name>james.broome</name><uri>http://blogs.conchango.com/members/james.broome.aspx</uri></author><category term=".NET" scheme="http://blogs.conchango.com/jamesbroome/archive/tags/.NET/default.aspx" /><category term="Conchango" scheme="http://blogs.conchango.com/jamesbroome/archive/tags/Conchango/default.aspx" /><category term="Miscellaneous/General" scheme="http://blogs.conchango.com/jamesbroome/archive/tags/Miscellaneous_2F00_General/default.aspx" /></entry><entry><title>Why BDD works for Agile</title><link rel="alternate" type="text/html" href="http://blogs.conchango.com/jamesbroome/archive/2008/07/22/why-bdd-works-for-agile.aspx" /><id>http://blogs.conchango.com/jamesbroome/archive/2008/07/22/why-bdd-works-for-agile.aspx</id><published>2008-07-22T22:34:00Z</published><updated>2008-07-22T22:34:00Z</updated><content type="html">&lt;p&gt;&amp;nbsp;&lt;/p&gt;
 
&lt;p&gt;As I mentioned in &lt;a href="http://blogs.conchango.com/jamesbroome/archive/2008/07/08/hello-world.aspx" target="_blank"&gt;my first post&lt;/a&gt; (and will probably continue to do so for the unforeseeable future), I recently attended &lt;a href="http://www.jpboodhoo.com/training.oo" target="_blank"&gt;JP Boodhoo's Nothin' But Dot Net training 'boot camp'&lt;/a&gt; which has motivated me to start to write about some of the stuff that I learnt and am still trying to make sense of...&lt;/p&gt;
 
&lt;p&gt;The main focus of the course was using &lt;a href="http://dannorth.net/introducing-bdd" target="_blank"&gt;Behaviour Driven Design&lt;/a&gt; to drive out an application, tests first, from the top down. I was very familiar with the concept of automated unit testing, having used NUnit in the past and using the MSTest tools on my current project. However, I don't think I could truly say that I'd been working 'test first' or that the design of our application was driven out by the test cases. Also, if I were to give a summary report of our automated tests to one of our Business Analysts, I guarantee that it would be met with a blank expression. This makes it tricky to prove that the tests are correct - do they match the requirement and, if this changes, what tests need to change to reflect this?&lt;/p&gt;
 
&lt;p&gt;The whole idea behind &lt;a href="http://en.wikipedia.org/wiki/Behavior_driven_development" target="_blank"&gt;BDD&lt;/a&gt; is to write tests in &lt;a href="http://en.wikipedia.org/wiki/Plain_English" target="_blank"&gt;plain English&lt;/a&gt;, describing the behaviours of the thing that you are testing. When the things that you are testing are written in the common language of the domain, the tests are then describing the behaviour of that domain. The main advantage of this is that the tests reflect the user stories, the business requirements of the application. Careful choice of naming conventions and syntax mean that a unit test report can read like a functional specification. Therefore, it can be read by a non-technical person e.g. the project sponsor, a domain expert, a business analyst and the tests can be validated against the requirements. If a new developer joins the team, they may not know the domain of the application however looking at the tests will immediately give them a very clear idea of the intent of the code. &lt;/p&gt;
 
&lt;p&gt;Let's take the following hypothetical user story for a staff telephone directory application:&lt;/p&gt;
 
&lt;blockquote&gt; 
&lt;p&gt;"As a user I should be able to view an alphabetical list of the employees so that I can quickly find the person I wish to contact."&lt;/p&gt;
&lt;/blockquote&gt;
 
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
 
&lt;p&gt;We may start with writing a test class something like this...&lt;/p&gt;
 
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
 &lt;div&gt;
&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,'Courier New',courier,monospace;"&gt;&lt;span&gt;using&lt;/span&gt; System; &lt;br&gt;&lt;/pre&gt;
&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,'Courier New',courier,monospace;"&gt;&lt;span&gt;using&lt;/span&gt; System.Collections.Generic;&lt;br&gt;&lt;br&gt;&lt;span&gt;using&lt;/span&gt; Observation = MbUnit.Framework.TestAttribute;&lt;br&gt;&lt;span&gt;using&lt;/span&gt; Context = MbUnit.Framework.TestFixtureAttribute;&lt;br&gt;&lt;br&gt;[Concerning(&lt;span&gt;typeof&lt;/span&gt;(DirectoryTasks))]&lt;br&gt;&lt;span&gt;public&lt;/span&gt; &lt;span&gt;class&lt;/span&gt; when_the_directory_tasks_is_told_to_get_all_the_employees_beginning_with_the_letter_A : SpecificationContext&lt;br&gt;{&lt;br&gt;    &lt;span&gt;private&lt;/span&gt; IEnumerable&amp;lt;Employee&amp;gt; results;&lt;br&gt;    &lt;span&gt;private&lt;/span&gt; IDirectoryTasks sut; &lt;span&gt;//sut = System Under Test    &lt;/span&gt;&lt;br&gt;&lt;br&gt;    &lt;span&gt;protected&lt;/span&gt; &lt;span&gt;override&lt;/span&gt; &lt;span&gt;void&lt;/span&gt; establish_context()&lt;br&gt;    {&lt;br&gt;        &lt;span&gt;//Test set up here e.g. mock objects etc...        &lt;/span&gt;&lt;br&gt;        &lt;span&gt;this&lt;/span&gt;.sut = &lt;span&gt;new&lt;/span&gt; DirectoryTasks();&lt;br&gt;    }&lt;br&gt;&lt;br&gt;    &lt;span&gt;protected&lt;/span&gt; &lt;span&gt;override&lt;/span&gt; &lt;span&gt;void&lt;/span&gt; because()&lt;br&gt;    {&lt;br&gt;        &lt;span&gt;this&lt;/span&gt;.results = &lt;span&gt;this&lt;/span&gt;.sut.GetEmployeesBeginningWith(&lt;span&gt;"A"&lt;/span&gt;);&lt;br&gt;    }&lt;br&gt;&lt;br&gt;    [Observation]&lt;br&gt;    &lt;span&gt;public&lt;/span&gt; &lt;span&gt;void&lt;/span&gt; should_ask_the_telephone_directory_for_all_the_employees_that_begin_with_A()&lt;br&gt;    {&lt;br&gt;        &lt;span&gt;//Interaction based test checking that we are talking to the TelephoneDirectory domain object    &lt;/span&gt;&lt;br&gt;    }&lt;br&gt;&lt;br&gt;    [Observation]&lt;br&gt;    &lt;span&gt;public&lt;/span&gt; &lt;span&gt;void&lt;/span&gt; should_return_the_list_of_employees_in_alphabetical_order()&lt;br&gt;    {&lt;br&gt;        &lt;span&gt;//State based test  &lt;/span&gt;&lt;br&gt;    }&lt;br&gt;}&lt;br&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;Note the name of the test class describes the context of the tests. The test methods (observations) are describing the expected behaviour of the thing that we are testing. Note too the Arrange, Act, Assert style of the test. We establish the context for the test, perform the action that we want to test and then assert the correct behaviours of the system under test. &lt;/p&gt;

&lt;p&gt;Writing the specification first drives out the need for the following supporting domain classes: &lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;div&gt;
&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,'Courier New',courier,monospace;"&gt;&lt;span&gt;public&lt;/span&gt; &lt;span&gt;class&lt;/span&gt; DirectoryTasks : IDirectoryTasks&lt;br&gt;{&lt;br&gt;    &lt;span&gt;public&lt;/span&gt; IEnumerable&amp;lt;Employee&amp;gt; GetEmployeesBeginningWith(&lt;span&gt;string&lt;/span&gt; first_letter)&lt;br&gt;    {&lt;br&gt;        &lt;span&gt;throw&lt;/span&gt; &lt;span&gt;new&lt;/span&gt; NotImplementedException();&lt;br&gt;    }&lt;br&gt;}&lt;br&gt;&lt;br&gt;&lt;span&gt;public&lt;/span&gt; &lt;span&gt;interface&lt;/span&gt; IDirectoryTasks&lt;br&gt;{&lt;br&gt;    IEnumerable&amp;lt;Employee&amp;gt; GetEmployeesBeginningWith(&lt;span&gt;string&lt;/span&gt; first_letter);&lt;br&gt;}&lt;br&gt;&lt;br&gt;&lt;span&gt;public&lt;/span&gt; &lt;span&gt;class&lt;/span&gt; Employee {}&lt;/pre&gt;&lt;/div&gt;
&lt;pre class="csharpcode"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre class="csharpcode"&gt;&lt;font size="1"&gt;&lt;/font&gt;&lt;/pre&gt;

&lt;p&gt;And the test class uses the following utility classes:&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;div&gt;
&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,'Courier New',courier,monospace;"&gt;&lt;span&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span&gt;/// Base class for all test contexts - enforces the Arrange, Act, Assert style testing&lt;/span&gt;&lt;br&gt;&lt;span&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;br&gt;[Context]&lt;br&gt;&lt;span&gt;public&lt;/span&gt; &lt;span&gt;abstract&lt;/span&gt; &lt;span&gt;class&lt;/span&gt; SpecificationContext&lt;br&gt;{&lt;br&gt;    [SetUp]&lt;br&gt;    &lt;span&gt;public&lt;/span&gt; &lt;span&gt;void&lt;/span&gt; Setup()&lt;br&gt;    {&lt;br&gt;        &lt;span&gt;this&lt;/span&gt;.establish_context();&lt;br&gt;        &lt;span&gt;this&lt;/span&gt;.because();&lt;br&gt;    }&lt;br&gt;&lt;br&gt;    &lt;span&gt;protected&lt;/span&gt; &lt;span&gt;abstract&lt;/span&gt; &lt;span&gt;void&lt;/span&gt; because();&lt;br&gt;    &lt;span&gt;protected&lt;/span&gt; &lt;span&gt;abstract&lt;/span&gt; &lt;span&gt;void&lt;/span&gt; establish_context();&lt;br&gt;}&lt;br&gt;&lt;br&gt;&lt;span&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span&gt;/// Attribute used in grouping observations&lt;/span&gt;&lt;br&gt;&lt;span&gt;/// when generating test report&lt;/span&gt;&lt;br&gt;&lt;span&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;br&gt;[AttributeUsage(AttributeTargets.Class)]&lt;br&gt;&lt;span&gt;public&lt;/span&gt; &lt;span&gt;class&lt;/span&gt; ConcerningAttribute : Attribute&lt;br&gt;{&lt;br&gt;    &lt;span&gt;private&lt;/span&gt; &lt;span&gt;readonly&lt;/span&gt; Type concern;&lt;br&gt;&lt;br&gt;    &lt;span&gt;public&lt;/span&gt; ConcerningAttribute(Type concern)&lt;br&gt;    {&lt;br&gt;        &lt;span&gt;this&lt;/span&gt;.concern = concern;&lt;br&gt;    }&lt;br&gt;&lt;br&gt;    &lt;span&gt;public&lt;/span&gt; Type Concern&lt;br&gt;    {&lt;br&gt;        get { &lt;span&gt;return&lt;/span&gt; &lt;span&gt;this&lt;/span&gt;.concern; }&lt;br&gt;    }&lt;br&gt;}&lt;/pre&gt;&lt;/div&gt;
&lt;pre class="csharpcode"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre class="csharpcode"&gt;&lt;font size="1"&gt;&lt;/font&gt;&lt;/pre&gt;

&lt;p&gt;Each test class relates to a specific context for a set of tests, which translate as the specification for the system under test. So, you may have more than one test class for each thing that you are testing if there are different test contexts e.g. &lt;/p&gt;
&lt;div&gt;
&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,'Courier New',courier,monospace;"&gt;when_the_directory_tasks_is_told_to_get_all_the_employees_in_a_department&lt;br&gt;&lt;br&gt;when_the_directory_tasks_is_told_to_get_all_the_employees_with_a_specific_last_name&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And each test context may have multiple tests, or observations, each with different assertions. The assertions themselves can also follow the same BDD coding styles so instead of the typical&lt;/p&gt;
&lt;div&gt;
&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,'Courier New',courier,monospace;"&gt;Assert.IsTrue();&lt;br&gt;&lt;br&gt;Assert.AreEqual();&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We can use&lt;/p&gt;
&lt;div&gt;
&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;font-family:consolas,'Courier New',courier,monospace;"&gt;results.should_only_contain();&lt;br&gt;&lt;br&gt;result.is_equal_to();&lt;br&gt;&lt;br&gt;dependency.was_told_to();&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Of course, the fluent syntax of the code in the above examples is made possible by the goodness of C# extension methods and some creative thinking about the design and naming of classes. But taking the mantra Red, Green, Refactor, the only thing preventing you from writing truly expressive code is your own creativity. Write the code how you want to use it from the tests, get the code compiling, get the test passing, then refactor the code. &lt;/p&gt;

&lt;p&gt;Writing the tests first drives out the code from the top down, whilst writing them in a BDD style syntax gives a meaning to why the tests are there and &lt;a href="http://en.wikipedia.org/wiki/YAGNI" target="_blank"&gt;why that piece of 'real' code should then be written&lt;/a&gt;. As &lt;a href="http://www.conchango.com/we-do-this/how/" target="_blank"&gt;I'm already working in an agile environment&lt;/a&gt;, collaborating with business analysts and working from user stories, developing features in this way just seems to totally fit. Its only a small step to produce a report of all the tests, parsing the class and method names to give you something like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Directory Tasks &lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;When the directory tasks is told to get all the employees beginning with the letter A&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;should ask the telephone directory for all the employees that begin with A 
&lt;/li&gt;

&lt;li&gt;should return the list of employees in alphabetical order 
&lt;/li&gt;

&lt;li&gt;should return the list of employees in groups of 10 &lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
&lt;p&gt;When the directory tasks is told to get all the employees in a department&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;should etc... &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Look familiar? The tests start to become a direct specification for the system that can be read, understood and validated by any member of the team. They are written in the language of the domain and describe the behaviour of the domain. If the specification changes, or new requirements are added (or missing) it is easy to see which tests and therefore what code needs to change. The code itself becomes the living breathing documentation of the application and this really supports an agile iterative cycle of development, adding new features one at a time. &lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;Please note: The example above will compile, but the tests won't yet pass due to the GetEmployeesBeginningWith() method throwing a NotImplementedException. In future posts I will build on this example to flesh out the tests and the associated code.&lt;/p&gt;

&lt;p&gt;The test framework used here is MBUnit, so a reference is needed to MBUnit.Framework. Alternatively, the test framework can be replaced by changing the aliases in the using statements at the top of the file.&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;For more info, see &lt;a href="http://behaviour-driven.org/" title="http://behaviour-driven.org/"&gt;http://behaviour-driven.org/&lt;/a&gt;&lt;/p&gt;
&lt;img src="http://blogs.conchango.com/aggbug.aspx?PostID=11949" width="1" height="1"&gt;</content><author><name>james.broome</name><uri>http://blogs.conchango.com/members/james.broome.aspx</uri></author><category term=".NET" scheme="http://blogs.conchango.com/jamesbroome/archive/tags/.NET/default.aspx" /><category term="Agile" scheme="http://blogs.conchango.com/jamesbroome/archive/tags/Agile/default.aspx" /><category term="Testing" scheme="http://blogs.conchango.com/jamesbroome/archive/tags/Testing/default.aspx" /><category term="BDD" scheme="http://blogs.conchango.com/jamesbroome/archive/tags/BDD/default.aspx" /></entry><entry><title>Hello World</title><link rel="alternate" type="text/html" href="http://blogs.conchango.com/jamesbroome/archive/2008/07/08/hello-world.aspx" /><id>http://blogs.conchango.com/jamesbroome/archive/2008/07/08/hello-world.aspx</id><published>2008-07-08T15:51:00Z</published><updated>2008-07-08T15:51:00Z</updated><content type="html">&lt;br&gt;&lt;p class="MsoNormal"&gt;So, okay, the title’s a bit cheesy (and probably been used a
thousand times before) for the blog of a software developer, but after almost a
year to the day of working at Conchango this is my first blog post so it seemed
quite apt.&lt;/p&gt;&lt;p class="MsoNormal"&gt;&amp;nbsp;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;One of the many benefits of working here at Conchango is
that you’re surrounded by a mass of immense knowledge and experience. This was
obviously one of the things that attracted me to this company in the first
place, but I remember finding it quite daunting when I first arrived. I finally
started writing a couple of internal blog posts earlier this year about some
issues we’d worked through on my current project, but stalled when it came to
publishing this to the big wide world. Maybe I just thought there would be people
who could say more on the matter, or express a better solution or technical
explanation.&lt;/p&gt;&lt;p class="MsoNormal"&gt;&amp;nbsp;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;Anyway, I recently had the pleasure of attending &lt;a href="http://www.jpboodhoo.com" target="_blank"&gt;JP
Boodhoo’s&lt;/a&gt; &lt;a href="http://www.jpboodhoo.com/training.oo" target="_blank"&gt;Nothin’ But .Net ‘boot camp’&lt;/a&gt; course in Vancouver and it got me
thinking (a lot). I could talk all day about how good this course is both from
a technical perspective and on a personal level, but for now I just want to
focus on one point, which I why I started writing this in the first place.&lt;/p&gt;&lt;p class="MsoNormal"&gt;&amp;nbsp;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;&lt;span&gt;&lt;/span&gt;One of the things
that JP encourages people not to do is put technical experts, well known
bloggers, industry ‘celebrities’ and the like on a pedestal. ‘How did you get
so good?’, ‘What’s your secret?’ etc are some of the questions that he commonly
gets asked, to which he adamantly replies that he’s no different from anyone
else. He just focused on what he knew he wanted. Once you accept that there
will always be people better than you, always someone with a different opinion
and always a different way to do something, what have you got to lose? You
should only be competing with yourself when striving for improvement. &lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&amp;nbsp;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;I also realised whilst talking to a colleague recently that
the feeling of being out of my depth that I had when I first joined Conchango
has never really gone away, but instead has turned from something that is scary
and overwhelming to something that feels exciting and challenging. Knowing that
you’re constantly going to be working with new technologies, hearing new ideas
and applying new concepts is a good feeling and I don’t think that I’d want it
any other way.&lt;/p&gt;&lt;p class="MsoNormal"&gt;&amp;nbsp;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;So, that’s why I decided to jump in at the deep end and
write this post. I don’t know yet what will follow, but we’ve definitely been
doing some interesting things here on my current project that are worth talking
about and we’ve solved some really complex (read stressful!) problems during
the course of the last 12 months. I also intend to somehow make sense of the
intense (14 – 20 hour days!) Nothin’ But .Net course and once my mind has
recovered try to distill this information into &lt;a href="http://blog.jpboodhoo.com/GettingStartedLearningSomeNewDeveloperHabits.aspx" target="_blank"&gt;smaller manageable pieces&lt;/a&gt; that I
can apply on my current project.&lt;/p&gt;&lt;p class="MsoNormal"&gt;&amp;nbsp;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;But that’s all to follow.&lt;/p&gt;&lt;p class="MsoNormal"&gt;&amp;nbsp;&lt;/p&gt;

&lt;p class="MsoNormal"&gt;So there it is, as is rapidly becoming the norm, I’m
officially out of my comfort zone again. No turning back. Maybe someone else
will follow my lead?&lt;/p&gt;&lt;p class="MsoNormal"&gt;&amp;nbsp;&lt;/p&gt;

&lt;img src="http://blogs.conchango.com/aggbug.aspx?PostID=11726" width="1" height="1"&gt;</content><author><name>james.broome</name><uri>http://blogs.conchango.com/members/james.broome.aspx</uri></author><category term=".NET" scheme="http://blogs.conchango.com/jamesbroome/archive/tags/.NET/default.aspx" /><category term="Conchango" scheme="http://blogs.conchango.com/jamesbroome/archive/tags/Conchango/default.aspx" /><category term="Miscellaneous/General" scheme="http://blogs.conchango.com/jamesbroome/archive/tags/Miscellaneous_2F00_General/default.aspx" /></entry></feed>