Posted on November 26th, 2008

There’s been lots of chatter lately about whether Agile is Dead, or if Scrum is [better|worse] than Lean, and whether Lean can be used for Development teams, or if Scrum should be shot, and so on, and thus forth. Here’s my view, subject to correction:

  • Agile is a mindset. It is actually agile, with a lowercase a. The manifesto was a marketing document. You can not judge whether someone, or some team, is agile using checklists.
  • XP (Extreme Programming) is targeted towards improving the way we write software. If you are working with a software team, you can’t leave home without it. TDD, Pair Programming, Acceptance Tests, Onsite Customer – vital, vital things to a well-oiled software team
  • Scrum is at a higher level. The practices can be applied to a software team, but can easily be applied to non-software as well. Its goal is increased communication and decreased risk by helping stabilize the efforts necessary to get to wherever we are trying to go. It’s one of the most likely reached-for agile practices, even though things like the Daily Stand-Up require teams to be past two of the 5 Dysfunctions of a Team to be even remotely effective. Scrum starts to be challenging as it scales without some true experts around – Scrum of Scrums, to me, just isn’t optimal (not that I have a better suggestion)
  • Lean seems to be two things, although I know it isn’t. To me (and this is my view after all) the important things here are optimizing the whole, reducing waste, and value stream mapping. The thinking behind this is vital to getting the other practices working well. But Lean is really at home changing organizations and large teams. While things like Value Stream Mapping and Kanban are coming out of this, for people trying to understand agility in the context of their team, figuring out how to improve once you’ve gotten the data can be a little too abstract.

A lot of this also has to do with things like the Dreyfus Model of Skills Acquisition – beginners need to be told what to do – which is why Scrum works so well. 3 practices, we’ll teach them to you in a weekend, and you can get up and running with it. Scrummerfall is easy to do when you aren’t also combining the practices with continuous improvement models.

So what should you start with if you want to make a software team better? There are two ways I suggest:

  1. Jump in with both feet (or "Throw ‘em in the deep end") – Talk to the team about the XP practices. Agree as a team to give it a go for x amount of time and to reevaluate. Be sure to give enough time for people to become at least a little comfortable (I’d suggest 1-3 months, but YMMV). The key here is continuous reflection on what is working and what isn’t. During the trial period work to make the practices work instead of assuming it won’t work for your team. At the end, have a half to day long retrospective on what worked and why, and then decide as a team how to move forward
  2. Evaluate and Apply – In this case, you use tools like value stream maps to get a sense of the overall health of the organization and the team. You selectively apply practices to improve areas, remembering that the goal is to optimize the whole. This is actually much harder than option 1 as you have to work to continuously implement new practices. You also lose the "shock and awe" when coming in as a change agent – people expect changes early on, but may be anticipating them settling down.

So I find the whole arguments silly. If we’re optimizing software teams, then we look to software practices. If we aren’t, we don’t. If I use Value Stream Mapping during my Retrospective with my Onsite Customer right after our Product Demos, it’s all part of becoming agile. I may not be "doing" XP or "doing" Scrum or "doing" Lean – and from the people and leaders I’ve talked to, that’s perfectly fine. But I also have enough respect for their ideas that if I’m mixing and matching, and cutting and tweaking, that I not blame a process I’m not even following. Perhaps if more people would simply acknowledge they aren’t following the process, and instead talk about why they aren’t, we could make more progress as a whole.

Until then, we’ll keep seeing people spinning their wheels and being kicked out of groups and denouncing each other’s practices.  When Uncle Bob suggested craftsmanship over crap as the 5th manifesto point, we should have embraced it as a community not only from a software engineering side, but a communication side as well.

Happy Thanksgiving All. Gobble Gobble.

No Comments


Posted on November 13th, 2008

If you are getting any of these types of exceptions compiling code:

  • error CS1501: No overload for method ‘WaitOne’ takes ‘1′ arguments
  • error CS1501: No overload for method ‘WaitAny’ takes ‘2′ arguments
  • error CS1501: No overload for method ‘WaitAll’ takes ‘2′ arguments

Then you are trying to compile code with .NET 3.5 that someone has written using .NET 3.5 SP1. And there ya go.

5 Comments


Posted on November 7th, 2008

I’ve been working on some more spikes around my Fluent Fitnesse effort mentioned a couple of days ago. One of the things this is designed to be is a roundtrip tool – so Fitnesse pages get converted to code, and vice versa. This way the business people still use Fitnesse for all of their work, and the coders can build and maintain it in code.

The spike tonight was the basic parsing of a page. I had some ideas of what I wanted to do, but I hadn’t settled on a strategy. So I did what I always do when I’m stuck – I write a test:

[Test]
public void AllLinesStartingWithBangNotInATableShouldBePlacedInTheHeaderBuffer()
{
    string expected = @"!contents -R2 -g -p -f -h
!define COMMAND_PATTERN {%m %p}
!define TEST_RUNNER {dotnet2\FitServer.exe}
!path C:\Users\Cory\Documents\Visual Studio 2008\Projects\FluentFitnesse\DivisionFixtures\bin\Debug\DivisionFixtures.dll
";

    string actual = HeaderParser.Parse(SAMPLE_PAGE);

    Assert.AreEqual(expected, actual);

}

Seemed reasonable enough. I knew in my head this wouldn’t be perfect – definitions can happen throughout the page, and this kind of shoves them all into one. But I knew that would come out later. So I wrote some code to make it pass:

public class HeaderParser
{
    public static string Parse(string page)
    {
        StringBuilder output = new StringBuilder();
        foreach (string line in page.Split(new char[] { '\r','\n' }, StringSplitOptions.RemoveEmptyEntries))
        {
            if (line.StartsWith("!"))
            {
                if (line.IndexOf("|") > 0)
                    continue;

                output.AppendLine(line);
            }
        }
        return output.ToString();
    }
}

Again, not perfect. For example, if you haven’t used Fitnesse, why does it matter if line.IndexOf("|") is greater than 0? (It’s because you can tell the wiki not to process WikiWords inside a table by prefixing the table row with a bang (!)). But I was on a mission – because I knew that this whole thing wouldn’t last. So I wrote my next test:

[Test]
public void CommentTableWithOneLineShouldConvertToFluentFitnesseCommentClass()
{
    string commentTable = @"|Comment|
|Module1.DivisionDoFixture|";

    string expected = @"using(FluentFitnesse.Comment.BoundTable)" + System.Environment.NewLine
                      + "{" + System.Environment.NewLine
                      + "FluentFitnesse.Comment.Call.Comment(\"Module1.DivisionDoFixture\");" + System.Environment.NewLine
                      + "}" + System.Environment.NewLine;

    string actual = CommentParser.Parse(commentTable);

    Assert.AreEqual(expected, actual);
}
}

This deals with |Comment| tables in Fitnesse, which won’t be tied to a class. And the code to make this pass? This nasty thing:

public static string Parse(string page)
{
    StringBuilder classOutput = new StringBuilder();
    bool inCommentTable = false;

    foreach (string line in page.Split(new char[] { ‘\r’,'\n’ }, StringSplitOptions.RemoveEmptyEntries))
    {
        if (line.StartsWith("|Comment|"))
        {
            inCommentTable = true;
            classOutput.AppendLine("using(FluentFitnesse.Comment.BoundTable)");
            classOutput.AppendLine("{");
        }
        else if (inCommentTable)
        {
            if (line.Trim().Length == 0)
            {
                classOutput.AppendLine("}");
                inCommentTable = false;
            }
            else
            {
                string contents = line.Replace(‘|’, ‘ ‘);
                classOutput.AppendLine("FluentFitnesse.Comment.Call.Comment(\"" + contents.Trim() + "\");");
            }
        }
    }

    if (inCommentTable)
    {
        classOutput.AppendLine("}");
    }

    return classOutput.ToString();
}

My spidey-pattern senses were tingling, but I wanted one more test:

 

[Test]
public void TextNotInATableShouldBeConvertedToFluentFitnesseTextCall()
{
    string page = "This is some text";
    string expected = "FluentFitnesse.Text.Call.Text(\"This is some text\");";
    string actual = PageTextParser.Parse(page);
    Assert.AreEqual(expected, actual);
}

And the code?

public static string Parse(string page)
{
    return "FluentFitnesse.Text.Call.Text(\"" + page + "\");";
}

Ah! Now that’s more like it. Since text can be anywhere in the page, it has to stay in the same place because otherwise it will be all jumbled. For the header I knew it wasn’t as important, because, after all, it is header information. But page text not in a table means that I have to preserve the line locations. Which means that my initial though of parsing the pages and spitting out whole sections of code is off – I instead need to parse line by line and pass
to a more Chain-based approach to let handlers deal with what to output next.

I’m sure that had I taken time to write and sketch I would have come to the same conclusion, but having the natural feel of the tests and writing code is something that is so, well, satisfying.

No Comments


Posted on November 3rd, 2008

One of the biggest challenges for people using FitNesse in any scale is how to manage the pages. Since everything is a wiki, and mapped dynamically to adapter classes, it becomes very easy to break, very easy to make brittle, and pretty difficult to refactor. While there has been work on the interwebs to make things better (for example, Jeremy Miller’s StoryTeller), I kept thinking about ways we could make things better without having to rewrite things.

Last week at KaizenConf I was talking with Scott Bellware about FitNesse and the challenges. The way I see it, right now you’ve got 3 basic options:

  • FitNesse
  • DSLs
  • RSpec

We’ve noted FitNesse’s issues already. DSLs are interesting in that they are in the context and domain of your users, but managing editing and creating them can be a pain. I really like RSpec, and have for a long time, but I really only like xSpec in Ruby – I haven’t particularly cared for it in other languages. It runs into a similar challenge of DSLs, and mixes in programming constructs as well.

When I really started thinking about it, most complaints I hear about FitNesse are around refactoring and management. You are writing things in a Wiki syntax that map back to code – but if you need to change that code, it becomes darn near impossible to know what you’ve broken. If we can solve that, then we might be able to make FitNesse a little more usable.

The inspiration point came out of the ALT.NET discussions around Fluent NHibernate – people had challenges writing all the XML configuration (or thinly veiled XML in the form of C# code) to hook up NHibernate, so they made some interfaces and abstracted code to make it much easier to work with. So why not do the same for FitNesse? Let’s look at a typical DoFixture:


!|MathFixtures.DivisionFixture|
|When The Numerator Is|3|And Divisor Is|1|Then Result Is|3|
|When The Numerator Is|7|And Divisor Is|2|Then Result Is|2.5|
|When The Numerator Is|4|And Divisor Is|2|Then Result Is|2|

Pretty straightforward. To run this, you’d have to create a mapping class. Using C#, that would look like:


public class DivisionFixture : fitlibrary.DoFixture
{
    public bool WhenTheNumeratorIsAndDivisorIsThenResultIs(double num, double div, double result)
    {
        return (num / div) == result;
    }
}

So we now begin to see the problem. What if we realize our tests should specify the behavior we want, so we want to change it from "Then Result Is" to "Then The Result Should Be"? We have to change both our FitNesse page and our C# class – and we won’t know until runtime that we missed something.

What if, instead, we could do the following?


FluentFitnesse.Fixture
f =
    new FluentFitnesse.Fixture
();

using (f.BoundTable)
{
    f.Call.WhenNumeratorIs_AndDivisorIs_ThenResultIs(3.0, 1.0, 3.0);
    f.Call.WhenNumeratorIs_AndDivisorIs_ThenResultIs(7.0, 2.0, 3.5);

     f.Call.WhenNumeratorIs_AndDivisorIs_ThenResultIs(4.0, 2.0, 2.0);
}

return f.Output;

The output of which is our FitNesse table from above. Now what we have is a specification we can actually refactor. If we change the method name in our underlying classes, it becomes a compile-time issue – not something we discover way down the line. Even better, the call is using our Fixture object – so no concerns about it being out of sync.

The guts behind it is pretty simple, and requires just some minor modifications to your FitNesse fixture class. First, you have to use underscores where the parameter values should be inserted (as you can see from the above example). Second, your methods need to be virtual, as we are creating a DynamicProxy. Third, they need to return bool – something you are probably already doing with a DoFixture anyway.

With that out of the way, simply create a class for each wiki page you want which implements an IFitnessePage instance.


public class DemoDivision : FluentFitnesse.IFitnessePage
{
    #region IFitnessePage Members

    public string Header()
    {
        return @"!contents -R2 -g -p -f -h
                !define COMMAND_PATTERN {%m %p}
                !define TEST_RUNNER {dotnet2\FitServer.exe}
                !path C:\Users\Cory\Documents\Visual Studio 2008\Projects\MathFixtures\bin\Debug\MathFixtures.dll";
    }

    public string Render()
    {
        FluentFitnesse.Fixture
f =
            new FluentFitnesse.Fixture
();

        using (f.BoundTable)
        {
            f.Call.WhenNumeratorIs_AndDivisorIs_ThenQuotientShouldBe(3.0, 1.0, 3.0);
            f.Call.WhenNumeratorIs_AndDivisorIs_ThenQuotientShouldBe(6.0, 2.0, 3.0);
        }

        f.Call.WhenNumeratorIs_AndDivisorIs_ThenQuotientShouldBe(7.0, 2.0, 3.5);

        return f.Output;
    }

    #endregion
}

Running this will produce the output:


!|MathFixtures.DivisionFixture|
|When Numerator Is|3.0|And Divisor Is|1.0|Then Quotient Should Be|3.0|
|When Numerator Is|6.0|And Divisor Is|2.0|Then Quotient Should Be|3.0|

|When Numerator Is|7.0|And Divisor Is|2.0|Then Quotient Should Be|3.5|

Notice the extra space. That’s because if you are using a Flow-style fixture, you don’t want the rows right underneath the fixture name. What happens is that BoundTable returns an object that inserts an extra line when "disposed".

The entirety of the Fixture class looks like:


namespace FluentFitnesse
{
    public class Fixture
    {
        private StringBuilder output;
        private T fixtureObject;

        public Fixture()
        {
            output = new StringBuilder();
            fixtureObject = CreateWrapper();
        }

      
;  private T CreateWrapper()
        {
            Castle.DynamicProxy.ProxyGenerator proxyGen = new Castle.DynamicProxy.ProxyGenerator();
            T instance = proxyGen.CreateClassProxy(new MethodInterceptor(output));
            return instance;
        }

        public IDisposable BoundTable
        {
            get
            {
                return new BoundTable(typeof(T), output);
            }
        }

        public T Call
        {
            get
            {
                return fixtureObject;
            }
        }

        public string Output
        {
            get { return output.ToString(); }
        }
    }

    public class MethodInterceptor : Castle.Core.Interceptor.IInterceptor
    {
        private StringBuilder sb;

        private string SplitCamelCase(string s)
        {
            Regex upperCaseRegex = new Regex(@"[A-Z]{1}[a-z]*");
            MatchCollection matches = upperCaseRegex.Matches(s);
            List words = new List();
            foreach (Match match in matches)
            {
                words.Add(match.Value);
            }
            return String.Join(" ", words.ToArray());
        }

        public MethodInterceptor(StringBuilder sb)
        {
            this.sb = sb;
        }

        #region IInterceptor Members

        public void Intercept(Castle.Core.Interceptor.IInvocation invocation)
        {
            string methodName = invocation.Method.Name;
            string[] parts = methodName.Split(‘_’);
            if (parts.Length != invocation.Arguments.Length)
            {
                Console.WriteLine("WARNING! Number of arguments does not match the number of parts in the method name");
                Console.ReadLine();
            }

            int argPos = 0;
            sb.Append("|");
            foreach (string part in parts)
            {
                sb.Append(SplitCamelCase(part) + "|" + invocation.Arguments[argPos] + "|");
                argPos++;
            }
            sb.AppendLine();
            invocation.ReturnValue = true;
        }

        #endregion
    }

    public class BoundTable : IDisposable
    {
        private StringBuilder output;

        public BoundTable(Type t, StringBuilder sb)
        {
            this.output = sb;
            output.AppendLine("!|" + t.FullName + "|");
        }

        #region IDisposable Members

        public void Dispose()
        {
            output.AppendLine();
        }

        #endregion
    }

}

Which, as you can see, uses the Castle DynamicProxy to wrap the Fixture code and intercept all calls to it. It’s all a bit hacky -I don’t like passing around StringBuilders, etc – but I wanted to get a baseline out there to see if people thought this would be useful.

The basic use case would be that you would gen out all of your FitNesse pages using a utility which took in a list of assemblies that contained your mappers. Ideally we could either reverse-gen C# code from the content pages, or otherwise have a way to tell when the pages are out of date (in case the users are changing them).

I’m really interested in feedback on this. I think this could really help out the "refactoring is hard in FitNesse" stigma. What do you all think?

1 Comment