CodeMash – Practical B/TDD

Well lunch was good, still at CodeMash.  Now sitting down in the afternoon session on Practical Behavior/Test Driven Development.  Apparently supposed to have some prereq software, so I’m trying to set those up on my machine rigth now.  Presentation is being given by a gentleman by the name of Philip Japikse.

Reviewed the concepts of User Stories and Context Specification.  Apparently these underpin the usage of MSpec, a tool for automating the running of user tests.  MSpec allows you to write Context Specification tests that group unit tests into a context of a feature expressed as a context specification.  The point apparently, is that MSpec will autogenerate HTML reports that can be shown to business analysts and other business stakeholders so they can understand what is being tested and how it’s being tested.

An example of a template of a test using this syntax looks a little like the below:

using Machine.Specifications;
using MbUnit.Framework;
using Rhino.Mocks;

namespace ThirdPartyToolSetupConcerns
{
    [Subject("0-Complete Application Concerns"), Tags("0-Complete Application Concerns")]
    public class When_Setting_Up_Third_Party_References
    {

         Establish context = () =>
	{
	   _toolMock = MockRepository.GenerateMock<ItoolRepository>();
	};

         Because ACTION;

        It Should_Get_List_Of_Tools_From_Command_Line = () =>
	{
	        _toolMock.Expect(tm => tm.HasTool()).IgnoreArguments().Return(true);
		var toolValidtor = new ToolValidator(_toolMock);
		Assert.IsTrue(toolValidator.HasTool());

	};
        It Should_Look_Up_Files_Required_For_Each_Tool_From_Database;
        It Should_Copy_Missing_Or_Updated_Files_Into_Correct_Directories_For_Each_Tool;
    }
}

The “Establish” and “Because” are delegates created to allow the test to be written in a context specification manner.  It seems to me that each “IT” is a separate actual unit test.  When run looks a lot like running tests in nUnit as long as you’ve named your test classes and test methods in a meaningful manner.  I think the value of MSpec is that it generates reports that are nicely formatted for your business stakeholders and such.

To implement the tests you use lambda expressions with no parameters, hence the ” = () => ” syntax, to create the code that does the setup and the code that implements each test in each one of the “IT” areas.  If no closure after an “IT”, then that test hasn’t  been implemented yet.  Above there is one closure for setup code and one test is implemented.

Actually there’s a little more, it looks like the benefit here is to layout the unit tests that you will fill in using a TDD approach and have the skeleton verified by your business stakeholders before you begin.  You can layout tests in the manner above without actually filling in the tests or any code and show the nicely formatted report about what you will test to your stakeholders and get agreement before moving forward.  Once you have business agreement on you MSpec setup you can then start codign by filling in the tests defined in each “IT” and writing code to make the tests  pass….interesting.

Now we’re going to start filling in some code ourselves.  Let’s see how this goes.

Just went over the notion of a “Row” test.  Apparently not supported in MSpec, but is supported in mbUnit and nUnit.  The idea is let’s you declare several different parameters for the same test so can write one test and run it with many different inputs.   Sounds like a really good way to cover my test cases with less code.

It looks like “Establish” delegate is used to demarcate a section of the test for setup.   Anything that needs to be setup for the “IT” tests to run below would be put here.  Phil suggests making all variables ‘internal’ and marking test projects friends so can set variable values for testing.  Phil went indicates he never marks any variables private, always internal so they can be accessed from a test.   Interesting…….

Beginning to go over mocking in a test driven development situation.  Phil’s using RhinoMock, whcih is what we use, so this is all making good sense to me.  Phil just setup an example showing how to inject the mock object into a method, it looks almost exactly like the process we use, so nice to see these experts telling people to do what we already do!  I like a little validation.

Going over the nitty gritty of using a mock object.  Specifically we’re talking about creating a wrapper for the file system so we can mock file system operations.  Interesting discussion, Phil suggests you only ever throw custom excpetions.  He suggests this because you can log in the creation of your custom exception and not worry about logging exceptions as they’re bubbled up.  Interesting theory.

Well presentation is winding down.  Very interesting, bdd stuff could be very beneficial from a process standpoint.  Also, again feel very good about what we are already doing after sitting through this.  Now have to figure out what to do for dinner!

Leave a Reply

Your email address will not be published. Required fields are marked *