Shaking Things Up: Scrum, Agile, and TDD

In mid September I started working as a vendor for Microsoft. The majority of my time involves coding. Prior to September I had only a vague idea of what scrum and test-driven development were. Scrum aside, I just couldn't understand why anyone would want to spend time writing all these tests and THEN code their application. My philosophy was, "Let me get some code together that needs to be tested. THEN I'll write the tests." Of course, as you've probably already guessed, the tests were seldom written. 


I've learned a great deal since that September day, and I continue to do so. The entire project I'm on follows agile methodologies, uses scrum, and is coded by way of test-driven development. It was a shock to my system. Not all software development at Microsoft is handled this way, incidentally. I consider myself one of the lucky ones to be exposed to it.


I come from the "old school" way of thinking. That is, project managers and business analysts would spend months and months (if not years) writing up specifications and project plans. More frequently than not, no development was done until the business owners signed off on these specifications. In addition, because very little (if anything) functional was put in front of the stake-holders during this entire time, the specifications were frequently revised and edited many times, to the point where they were often vaguely identifiable from their originals. 


This is the type of management approach that caused the project at my last employer to fail. The client demanded that full specifications be completed as one of the requisites of my employer getting paid. The development team would start to implement as much as we could due to pending deadlines - only to find obvious holes or errors in the logic once we put usable features in front of the people in the middle of writing the specs. We were literally developing to a moving target. One of the systems, a workflow API, was redesigned four times because the requirements kept changing as we delivered what was documented. So we were faced with pending deadlines to deliver functional specifications for several modules as well as pending deadlines for development - in parallel. You do the math. Because the director had staffed up so much to get all these specifications done (for a while there were 15 people on the PM team), and because it took almost a year, the money ran out.  


Now, with that in mind, imagine a methodology whereby you could put useful functionality in the hands of the stake-holders on a regular basis (perhaps monthly) right from the start. Each month you deliver functionality, and you get instant feedback on that delivered functionality so you can make it better the next month while you're continuing to build the system. By stake-holders, I mean the actual client - the people you're building the system for, not the project managers or business analysts caught in the middle who are trying to gather requirements. 


This doesn't solve the problem of some clients requiring large functional specification documents, but it does offer at least one potential change to the way they're written: the functional specification can be written AFTER the majority of functionality has been developed and delivered. This is a huge step toward an accurate specification and it also drastically reduces the amount of time it takes to write the document. In addition, every month the development team is getting direct input to keep the application's business usefulness on track. Granted, there are cases in which business owners will not release budgetary dollars for development until these specifications are signed off, but that is a case for another blog entry.


When I was reading about scrum and agile methodologies I found myself approaching it with skepticism. I was so used to spending the time to create complete logical and physical models before a line of code was written that I just couldn't understand how anyone could possibly set all that aside and only code what was required for that particular month. It only took about two months for me to truly see how this new approach works so much better for everyone right from the start. The hardest part is often convincing the die-hard old-schoolers that it's time for a change.


With the help of Doug Seven, Brad Wilson, and Scott Densmore I am also now a big proponent of test-driven development. For those who are unfamiliar, here is a simple example.


I was asked to create new methods on a class, and these methods would allow someone to add and delete a shortcut from one group to or from another.

 

With test-driven development, you write your test first, then you write just enough code to make the test pass. The theory is that you could spend hours, weeks, or months trying to account for every possible (real and theoretical) scenario as you design an object model or database. Instead of spending so much time on that, you write some tests that validate the one immediate goal you have.


To fulfill the requirement given to me, the first thing I typed was the following code:

 

        [TestMethod]

        public void AddShortCutWithTwoExistingIdsReturnsTrue()

        {

            Guid toGroupId = new Guid("{45722B64-0354-4ed4-A813-1BD67926EAA0}");

            Guid foreignGroupId = new Guid("{F4B729C4-B922-42bc-BED9-C70D9F0A8C36}");

            bool result;

 

            result = disco.AddShortcut(toGroupId, foreignGroupId);

 

            Assert.IsTrue(result, "AddShortcut failed.");

        }

 

        // AddShortcutWithNonExistentToGroupIdThrows

        // AddShortcutWithInvalidToGroupIdThrows

        // AddShortcutWithInvalidForeignGroupIdThrows

        // AddShortcutWithNonExistentForeignGroupIdThrows

        // DeleteShortcutWithNonExistentFromGroupIdThrows

        // DeleteShortcutWithInvalidFromGroupIdThrows

        // DeleteShortcutWithNonExistentForeignGroupIdThrows

        // DeleteShortcutWithInvalidForeignGroupIdThrows

        // DeleteShortcutWithTwoValidIdsReturnsTrue

I came up with 10 unit tests, all of which validate 2 little methods – AddShortcut and DeleteShortcut. Now it’s my job to write one test, as I did above, and then write just enough code to get that test to pass. The following is actually too much (all I needed was a method that returned true, but I thought that would be too simple for this example):

 

        public bool AddShortcut(Guid toGroupId, Guid foreignGroupId)

        {

            if (toGroupId == new Guid("{45722B64-0354-4ed4-A813-1BD67926EAA0}") &&

                foreignGroupId == new Guid("{F4B729C4-B922-42bc-BED9-C70D9F0A8C36}"))

            {

                return true;

            }

 

            return false;

        }

 

Note the hard-coded Guids. That is because I don’t need any more code in order to make the test pass. As I write the other 9 tests, my code will look more and more like you’d be used to, but before I would have spent possibly an hour thinking about how I wanted to implement these two methods. Instead, in one hour I have all my code written, and there are at least 10 unit tests that validate that the code works the way it should.


A side effect of this test-driven development is a specification for my method - in code. In other words, someone who needed to write a spec could examine my tests and gain a huge amount of information to accurately document what this particular method of the class does. 


Now consider the effect on the project if every developer did this, especially in a scrum / agile environment. We have just a couple dozen classes in our project and well over 300 unit tests. I can now feel much more confident in updating my code (or adding new code) because I have the ability to run all unit tests that were written by all developers on the project to insure I haven't made any breaking changes.


Thanks to my new team of mentors for teaching me this. It's funny how in just a couple of months I'm at a point now where I shutter to think of writing code without having a test that I'm trying to satisfy first!

8 Comments

  • We are using Scrum every day (even when the Scrum master is off) and I must say it's the best thing we ever did
    Now we just have to instal red and green lava lamps and have the green ones light up when the build succeeds and the red ones when it fails for our continuous integration projects


    Denis

  • I am developing a web application which has two important things: Getting stuff out of and into databases, presenting a user interface to do so.

    I cannot figure out how to:
    A - Develop this bit by bit, it needs some big design up front, at least I think it does.

    B - Write meaningful tests. All examples of TDD come with nice scenario's that are 'testable', like a Queue class. Sure, but hey, I don't write those, I'm writing a Handler to query a blob from a table and display it as an image, how the hell do I test that?

    So, I don't think it will work for me. Are there project types that are more suited to TDD and types that are less suited?

  • Hello,

    I wonder which tools you use to support your SCRUM
    based processes? Anything for customer feedback management? Collaborative release/sprint planning/tracking? What is your bug-tracker?

    Thanks,
    Alexey

  • Mike,

    Your "A" point is an assumption that is frequently made by people who are not familiar with scrum. In other words, do you really need "some big design up front"? What kind of data are you getting and putting in to the database?

    With regard to your "B" point, user interfaces (i.e. web pages) are much harder to write unit tests for. Your "handler" could be in its own class library, which you can then test from a test project. This class library could be referenced from your web application. If you move as much logic as possible out of your web pages and into this class library, more and more becomes unit testable.

    Hope this helps,
    Russ

  • Hi Alexey,

    We use Team Foundation Server for everything: tracking scrum stories, user acceptance tests, bugs, etc. Every iteration and sprint is entered into TFS so each of these things can be organized properly.

  • Yes, every tip helps, thanks.

    Regarding big design up front, I mean stuff like a DAL and BLL, authentication and authorization. I guess I'm afraid that with every step you take, you might find yourself repeating code, so you'd have to refactor the code that you've already written.

    Is that accounted for, or does that not happen?

  • Hi Mike,

    While refactoring is indeed a big part this whole approach, I think you'll find that the time to develop the system is still reduced, and the system that is developed is more useful.

    I'm a big proponent of splitting things up into DAL and BLL asssemblies for more reasons that just because "that's n-tier and that's what everybody is supposed to do these days." Every application is different, and you need to measure the positives and negatives of having more than a couple of tiers.

    One reason I enjoy having these additional layers where I'm able to do it is that it completely unblocks developers working on other tiers by introducing mock objects. For example, if I'm doing the BLL and I need to talk to the DAL, I don't have to wait for that developer to finish. All I have to do is create a simple object that mimics, in a very simple way, how I'd interact with your DAL. This is made possible many ways, particularly with the use of interfaces.

    I might have a DataManager class in my DAL that I call from the BLL. This DataManager is responsible for the CRUD of all my data, no matter how I choose to break it up within my DAL. DataManager is the entry point. If I create IDataManager in the DAL, I can create a class called DataManagerMock in my BLL which also implements IDataManager. Now I don't really have to know or care how far you've gotten (or not gotten).

    Hope this helps,
    Russ

  • If you want to find a black lava lamp we are the black lava lamps champions.
    Have you been looking for the perfect Black Lava Lamp for a great deal? Our Black Lava Lamps shine in the light and look stunning in the dark. We love using black light lava lamp products throughout our house to bring life to the rooms and help things stand out. We have the Best Prices on Black Lava Lamps.
    Lava lamps have fascinated and mesmerized the public for decades.
    We have had many motion lamps on sale. They are in the same era as disco balls and black lights. Buy lava lamps at an affordable rate and you just might have it for years to come. Light up a dark room today.

Comments have been disabled for this content.