I had an interesting conversation with a long time friend and fellow IT worker, Eric Moore, today. Our conversations tend to ramble unpredictably at times, and this evenings was no different.

In the course of the conversation Eric elaborated a series of connected thoughts about IT projects that hit home with me. It was not that anything he said was a new concept in and of itself, but the way he said it was what I found so compelling. I’ll get to what, and how, he said in a moment, first I need to set the stage a little.

I believe that Agile development, TDD and the other iterative approaches to development offer significant benefits over more traditional Waterfall approaches. I believe this, getting clients and employers to understand and accept the benefits is more difficult.

Over the years I have seen a familiar pattern play out in Waterfall style projects. As the project nears or completes the Verification portion of the life-cycle, one of a number of things happens.

WaterfallBecause of the long(er) duration of time between the Requirements/Design phases and the Verification phase in Waterfall projects as compared to typical Agile projects there is often a period of frantic redesign and tweaking during verification.

This is caused by a number of issues but a frequent cause is the fact that the stakeholders that participated in the Design phases are gone by the time the Verification phase begins.

Or, the Stakeholders were not committed to the process and did not take seriously the necessity to actually design first. Remember this fact, it becomes important later.

One way or another, by the time your project reaches the Verification phase it degenerates into a series of recriminations, “thats not what we meant/wanted/needed”, meetings, and emergency changes in order to achieve what was really needed.

Waterfall development tends to exacerbate this tendency because of the longer timeline as I mentioned before. Agile development on the other hand tends to minimize this symptom due to its short cycle iterative approach.

(Agile development can also be abused to inject continuous never ending scope creep precisely because of its shorter cycles. Keep this in mind as well, it to becomes important.)

Iterative

Because Agile builds the design as it goes, with minimal requirements gathering, it usually results in delivering exactly what was actually needed. Its iterative approach allows the stakeholders to continuously fine tune their goals and design within a feedback loop that is typically very fast.

But if you are working with someone that wants to keep tweaking and tuning with no end in sight then you have entered the Agile “death spiral” and need to break out.

So no matter which methodology we use, we are often faced with a similar set of frustrations, both as developers, and stakeholders. The “Just one more thing” Frustrationsyndrome, or the “thats what I asked for, but it’s not what I wanted/needed/meant” syndrome.

In order to avoid these sources of frustration and project failure you need to deal with the “Economies” in software development.

Finally we are back to my friend Eric, he pointed out a general truth that applies to both IT projects and life in general.

Paraphrasing, Eric said something along the lines of. If something is free and seemingly plentiful, people tend to be wasteful and careless with it.

They will take more than they need, tend not to treat it with respect and in general not show appreciation for it. But when you make that same thing “cost” in some way, then they will tend to be more careful of it, take it more seriously, and treat it with respect. The trick is how to instill “cost” into whatever it is you are dealing with.

Design and requirements are often looked at as “free” by the business side, in the sense that they can continue to revise and expand on them, therefor they don’t really need to put a great deal of effort up front, since they know they can tweak and expand on them “once I see the product running”. In Watefall approaches that is a red flag that indicates the project is going to go over budget and exceed schedules. In Agile approaches that is expected behavior, too a point, but not when it becomes excessive.

So how do we prevent this in either method? Add cost to changes. Make the participants have to “pay” some kind of cost for making changes. This could be time or effort on their part. Have them participate in the design sessions and change sessions along with the rest of the team. Not going home on time, or loosing time in other areas of their life and work is usually an effective “cost”.

If it is a client that is making changes frequently or inappropriately, begin to micro manage their expectations. Call and email them about each and every step along the way, literally drown them in information and requests for clarification. Sooner rather than later they will realize that changes are costly to them, then you will begin to find out what is really important to them.

I am sure I will expand on these thoughts later. This is not meant to be an exhaustive comparison between design methodologies or project management and risk management approaches. Just some thoughts on the “Economies” of Software Development.

Cheers,

Robert Porter

 

 

 


 
Categories: Programming | TDD


December 7, 2007
@ 10:01 AM

Microsoft has released a Live Lab's (Microsoft Research and Live Services) preview technology package called Volta.

Volta is a framework that allows a developer to potentially build a multi tier application initially as an client application, and then use a technique called "declarative tier-splitting" to identify which pieces of the application run on a server and which pieces run on the client.

This is accomplished by using and XML like declarative markup within the code. With this approach a developer can focus on getting the application designed and functional and then let Volta split the tiers and create the communications "glue" that lets the applications tiers work together.

How this is accomplished is rather interesting, Microsoft decided to go with an MSIL based approach, mostly accomplished in the post compilation area. MSIL code is rewritten to run in Javascript for the client, and ASP.NET for the server side, typically as a web service.

Since Volta works it's magic at the MSIL level, any CLR targeted language is supported, C#, VB.NET, IronPython and others. Visual Studio 2008 is required at this stage, 2005 is not supported and it is unclear if it will ever be.

So show me some code already!

The code shown below is from the Volta Recipe's page. It shows the [RunAtOrigin] custom attribute in use.

namespace VEMashup.Weather
{
    [RunAtOrigin]
    public class WeatherSvcProxy
    {
        public string GetJsonWeatherInfoFor(double lat, double lng)
        {
            var baseUri = @"http://ws.geonames.org/weatherIcaoJSON";
            var uri = baseUri + "?lat=" + lat.ToString() + "&lng=" + lng.ToString();
            var xhr = new Microsoft.LiveLabs.Volta.Xml.XMLHttpRequest();
            xhr.Open("GET", uri);
            xhr.Send();
            if (xhr.Status == 200)
                return xhr.ResponseText;
            else
                return null;
        }  
    }
}

 

This is an example of "tier splitting" via markup. This tells the Volta framework that this code is destined to run on the server. Code not marked will continue to run on the client. This means that as a developer you can postpone deciding how and where to partition your application until the last minute.

The agile developer in me seriously enjoys this particular aspect! Volta technology is seriously early in the life cycle however, so bear in mind that this will change before it gets released.

There is a handy list of known issues you should review before you start playing with the framework.

You could think of Volta as architecture refactoring on steroids. As shown below Microsoft has designed it explicitly with that in mind. (Image from Volta Web Site.)

image001

Bear in mind that you are not limited to 2 tiers, you can retarget portions of your application to as many tiers as you want!

All in all I think this bears some watching!

Cheers,

Robert Porter


 
Categories: .NET | Agile | ASP.NET | Javascript | Programming | Reviews | TDD | Tools and Toys | VB.NET | Visual Studio | XML


November 27, 2007
@ 11:36 PM

No matter how agile your development practices are, and no matter how skilled your team is, you can still generate a failure.

There are some sure signs you are headed for a failure that you can watch for. One of the most obvious and common is when deadlines are set without regard to input from the development staff.

Artificial "drop dead" dates are always a sure sign of trouble to come. It is especially worrisome because it is so prevalent. I have participated in a number of projects where the milestones, phase durations etc, are set in stone before all of the analysis is even complete.

A common scenario, particularly in "internal" non commercial projects is that the business unit identifies a desired set of functionality and delivers the desire in the form of a loosely defined set of requirements, accompanied by a delivery date that is usually wildly optimistic.

I actually worked for a company where the development manager was fond of saying: "The customer will settle for 80% of the desired functionality."

This is far more common than anyone would like to believe. And the particular company I am speaking of is still developing internal projects with the same mentality 10 years later. (I am no longer there, but people I know still are.)

The result of this "settle for" mentality is that there is a loss of confidence in the development group by the customer, and a sense of hopelessness in the developers that becomes pervasive. Most developers leave, a core group will stay until they burn out, but by and large these teams are marred by high turnover rates, low morale and frequent re-organizations.

Do you work for a settle for group? Any idea on how to combat this from within? Please share your thoughts!

Cheers,

Robert Porter


 
Categories: Programming | Ramblings | Rant | TDD


If you write code for a living, no matter what language, flavor, or IDE, sooner or later you begin to develop/write code to a set of unwritten rules that experience has taught you. Sometimes these rules are based on great, hard won lessons, wrested from spectacular failure or success. (Both failure, and success are great learning opportunities.)

Other times they are holdovers from some other project or something you learned from someone else. Or even something you just do but can't explain. My favorite story about the genesis of those kind of rules is as follows.

Child watches Parent making a meatloaf, after the meatloaf is made, Parent takes it out of the pan and cuts about 2 inches off one end and then puts it in the oven. Child ask's Parent why they always cuts 2 inches off the meatloaf? Parent pauses for a moment and says they are not sure why, but their Parent always did that. They decide to call Grand Parent and ask them, Grand Parent thinks for a minute and says it's because their Parent also did the same thing. A quick IM to Great Grand Parent asking why this was done results in the response: "Cause my oven was small and a full size meatloaf would not fit!"

Sometimes, we continue a practice out of habit, not because the need is still there. Most of the time this is fine, but sometimes we unconsciously propagate a behavior or methodology that has lost it's meaning or usefulness over time. Sometimes even to our detriment. It is useful therefor to question why we do things the way we do every now and again. A few moments of introspection can lead to an "Ohhhhh" moment.

I recently experienced such a moment when I was explaining some code I had written to another developer. Once I had finished my explanation they asked me a series of questions about why I did it this particular way as opposed to another. My knee jerk response was "because it's the best way" followed by an unspoken "that I am aware of".

The discussion continued and I soon learned that the method I was using was not only obsolete but was potentially dangerous because of changes in the underlying structure of the language I was using. Changes I was not only ignorant of, but which made a much more robust solution possible.

The method, involving collection classes, that I was using was one I had been using in one form or another for years. I was so comfortable with it, that I had ceased to question it, or look for alternatives. I had developed a blind spot when it came to that particular topic because I was so deep in my personal comfort zone that I subconsciously did not want to move away from it.

This is also an example of the benefit of pair programming, TDD and agile methodologies. To a lessor extent the same results can occur in any team environment. Looked at another way it is an example of why solo developers sometimes do not fare as well. Not having a team to bounce ideas off, or to have question and challenge you on assumptions and approaches can often lead to practices that become bad habits.

That is not to say that all solo developers progress less slowly or that all teams progress better. There are plenty of examples out there of "Toxic Teams" and solo Super Hero coders. But it is nice to be exposed on a daily basis to others points of view, experience and skills. You can derive a lot of the same level of benefit, albeit less interactively, by reading blogs, and participating in development forums all over the net.

But every now and then, solo or team member, you should stop, reflect, and refactor your own thinking process and assumptions. Weed out the things that no longer work for you, and try and replace them with things that do. Learn something new, test it against your own experience, if it seems to fit consider making a new habit to replace an older one!

Cheers,

Robert Porter


 
Categories: Agile | Programming | Ramblings | TDD


October 24, 2007
@ 01:51 PM

Ok, I know I promised I would post about but to be honest I am not sure I myself fully understand the difference or need. Mock objects are easy to understand, but I have yet to find two people that agree on the definition of Virtual vs. "regular" Mocks.

Wikipedia has entries for both Mocks and Virtual Mocks, but at least at the time I write this there was little to no content on the Virtual Mock entry. The main difference would appear to be that Virtual Mocks can Mock a concrete class, while normal Mocks are used to simulate the interface only.

More on this as I learn more. But my use of Mocks in TDD has been pretty much limited to interface level work. There is a huge and at times, nasty debate in the blogosphere relating to Mocks, particularly as they relate to coupling issues, Dependency Injection (DI) and issues. Which also ties into the growing debate on "design for testing", which means that you write your code to facilitate testing from the start.

I honestly don't have the required background to register a viable defensible opinion on all of these issues. What I can say is that using TDD and Mock's has enabled me to produce better quality software, faster than I ever have before. With fewer debugging sessions, and as an added benefit it tends to make me write code that is easier to refactor later to introduce new features etc.

One of my most memorable moments in my journey along the TDD path of discovery was when I had to add significant new functionality to an existing application that I had written. The application had existing tests, with probably close to 80% coverage.

I made the first round of changes, ran the tests, had two failures, refactored the new code to get the tests to pass, added a couple of new tests related to the new functionality, fired the tests one last time, all green! Turned the code, with confidence, over to QA and testing and was done! It was a personally very satisfying moment. Previously I would have held onto the code for at least another two or three days trying various combinations of simulations and debug stepping and then been still unsure of the state when I turned it over.

Mocks come in very handy for me when I want to decouple the system under test from dependencies that are expensive (Database calls, Web Service Calls), or ones that don't exist in any form except for production. (I have worked for clients that could not or would not set up a complete DEV/TEST/PROD triad of environments, and in some cases, some systems only existed as production instances.)

Remember, when you are testing and developing you are testing your code, not performing integration testing of the whole system. That comes later.

Mocks also come in handy for cases when you need to test your codes response to what is in essence a "black box call" to a component or system for which you don't have code, or don't have the access etc. In short Mocks help me focus on my code and the system under test and not someone else's.

In an upcoming post I will show some examples of how and when I have used Mocks. And attempt to explain the thinking I went through in deciding to use a Mock, and how to implement the Mock etc.

Meantime, keep the questions coming!

Cheers,

Robert Porter


 
Categories: Programming | TDD


According to Wikipedia a Mock Object is defined as:

In object-oriented programming, mock objects are simulated objects that mimic the behavior of real objects in controlled ways. A computer programmer typically creates a mock object to test the behavior of some other object, in much the same way that a car designer uses a crash test dummy to test the behavior of a car during an accident.

So a Mock object is in essence a replacement for a real world object or process. A Mock object has the same interface as the real objects they are standing in for. But these Mock objects typically simulate the actual operations of the real world objects. This means that instead of calling an expensive, in terms of time and complexity, object like a web service, they can simulate the call and respond in realistic ways without the overhead of database interaction or network latency.

This allows the unit tests being written against the Mock to focus on the actual behavior but without the penalty of the real overhead. In a fairly complex application with potentially hundreds of unit tests, speed of test execution becomes a real issue. Mocks help keep that interaction realistic but not punitive. 

Eventually in the testing of a system, the Mocks will need to be replaced by their real world counterparts, this is typically done in the integration or system testing phases of the project.

Mocks, Fakes and Stubs

Mocks are different than Fakes. A Fake is simply an object that implements the interface of the object it replaces, usually with predetermined responses to each method call. A Mock goes further in that it is often coded to contain it's own assertions, and track state perhaps as well. In this way a Mock can determine and respond appropriately if its methods are called out of order, or prior to some initialization call etc.

A stub is typically even simpler than a Fake. A typical stub for example, could be a boolean function call, that is replaced with a simple "Return True" line of code. The functions parameters are not examined or validated, every call to the stub simply returns "True".

Why use Mocks?

Among many other reasons to use Mocks, one reason comes to my mind from recent experience. We were testing a system that was time of day sensitive. Meaning that we needed to know during testing that several different portions of the system responded appropriately when the time of day was between certain time periods. With Mocks it was easy to provide this kind of functionality whereas with the real objects we would have had to reset clocks on 3 different systems, over and over, in order to achieve repeatable results.

Next post: Virtual Mocks


 
Categories: Programming | TDD


September 30, 2007
@ 01:23 PM

I recently posted a short blog on using TDD practices when working with Legacy code. In a comment to that post Mike Kelly raised a couple of questions/issues that I want to address.

Here is part of the comment Mike made:

One question I have, is how to apply atomic TDD methods, modules, to code that is not really designed for TDD?
For instance, if you had to support VB6, or COBOL, or some other language... not to mention scoping visibility...
I struggle at times just writing TDD code for my own code! I'd be interested to hear more on this topic...

TDD principles dictate that tests should be "Atomic", that is they should apply to a very granular area of code in the system under test. So how would we implement TDD in a legacy system especially one that TDD had never been used with before?

In a word, Mock Objects. Mocks become very valuable when you have to work with a system "at arms length" from the code. That being said, there are some issues with this approach. You are adding a layer of abstraction from the actual code under test, and if you are not careful you end up with test code that is too tightly coupled to the code you are trying to test which makes any refactoring difficult.

Mocks are not the end all be all by any means. In the .NET world it is actually fairly easy to add TDD support for languages like VB6 after the fact. Scope is certainly an issue. But since VB6 can call .NET assemblies via COM Interop you can fairly quickly put together a test class inside of the scope of a VB6 application. If there is any interest I can blog some examples on this with a project that I recently added TDD practices to.

I have not worked with any variant of COBOL since the early 80's when I worked on an IBM 360 system. So I can't comment directly on COBOL, but I would imagine Mocks would help here as well.

Next post, Mocks!

Cheers,

Robert Porter

Some resource links of interest on this topic.

Applying Test Driven Development to an existing application. - Eric Hexter's Blog

Test Driven Development, a Portable Methodology - Nancy Corbett

Why and When to Use Mock Objects

Jeremy D. Miller


 
Categories: Programming | TDD


Brad Wilson just posted some interesting new attribute usage information on xUnit.net here. And discusses an upcoming feature called [FreezeClock] which will solve an issue I have been having.

He explains [FreezeClock] this way:

Another one we'll do for CodePlex is one I call [FreezeClock], which uses our internal Clock class (a testable replacement for DateTime) which supports the concept of freezing the clock at a moment in time, and then unfreezing when the test is over. This is useful to ensure, for example, that some code under test is calling "Clock.Now", so that you can actually test the value they pushed in some arbitrary amount of time later by simply calling "Clock.Now" again. When we get around to doing that one, I'll make a blog post which shows the Clock class as well as our attribute.

There is another interesting tidbit, another extension called [AssumeIdentity]! Go read for yourself!

Cheers,

Robert Porter


 
Categories: TDD


September 26, 2007
@ 04:04 PM

First, let me be clear about what I mean by "Legacy" code. In most shops legacy refers to anything not currently under active development.   A program written a month/year ago for which development had legacyceased. At least this is the definition that I am dealing with for the purposes of this post.

We all know the feeling, something happens to cause a change to be made in an application or other component that has long been "just working". And now you have to wade in and get that crawly feeling of rummaging around in someone else's code.

The fears are common, and real, if you are unfamiliar with the code you are also unfamiliar with the original developers assumptions, the cross dependencies in the code base, even potentially external dependencies.

So you hesitate at each step, afraid to change anything for fear of introducing a bug, or outright breaking everything. Cause, you know, if you break it, you own it! Now and forever more.

FearOften the original developers are no longer easily reachable, either because they have been reassigned, moved on, left the building in a straight-jacket. For whatever reason when we as developers are required to delve into a "legacy" system it often brings a high level of tension along with it!

But it is something we all have to deal with from time to time. So how can we approach this task and minimize both the risk and the fear? In a word, TDD.

Test Driven Development is not just for shiny new development, it can be applied retroactively to existing code. And modifying a legacy application is the perfect time to introduce unit tests to an application that did not already have them.

If the code already had unit tests, and they are passing, you are way ahead of the game, but if not, adding them can be your salvation.  When I tackle a legacy project, at the very least I try and identify the portion of the code base I am going to be working with. Then I create a unit test module to test the existing code as is (and my assumptions about that code as well), and get them to pass before I change one line of existing code.

With that done, I can begin introducing changes with some degree of confidence that I am not going to *break* anything along the way, at least not without knowing about it. I begin my Red/Green/Refactor process until I have achieved the desired change, and all the tests are still passing.

This concept seems straightforward, at least to me, but for some reason most developers are reluctant to apply TDD concepts to projects that do not already have them. I am not sure why this is the case, but I know when I have done this I tend to sleep a lot better. Plus it adds real value for the next poor sucker that has to maintain this particular piece of legacy!

Cheers,

Robert Porter

Technorati Tags: , ,

 
Categories: Programming | TDD


I ran across a nice article by Mark Seemann on MSDN. It was published in the September 2007 issue of MSDN Magazine. In it he covers what he describes as the continuum relationship of Mocks, Dummies, Stubs, Spies and Fakes in Unit Testing.

The following diagram is from his article to illustrate the point:

Implementation Coverage

As you can see, each component has varying levels of implementation depending mostly on your needs etc. The article is worth a read!

Cheers,

Robert Porter


 
Categories: Programming | TDD | Agile


September 23, 2007
@ 10:39 AM

I would have to say that I have become a convert to TDD concepts. I have used NUnit, and mbUnit testing frameworks to varying degrees for some time. Now I use them daily and am working to increase my coverage in all my projects.

Since I primarily develop in the .NET Framework I have particular interest in the unit testing frameworks available in that environment. As I mentioned in a previous post I have currently settled on mbUnit as my unit testing framework.

xUnit is a new framework developed by, among others, James Newkirk and Brad Wilson. James was one of the original authors of NUnit and is now a Microsoft employee. Brad Wilson also works for Microsoft. Together they have created what looks to be a very well thought out testing framework.

xUnit is currently being hosted on CodePlex and is distributed under Microsofts Permissive License (The borgs version of Open Source).

The framework has already been integrated with TestDriven.NET, and has it's own console runner, but no GUI runner yet.

Roy Osherove has a series of posts about his view on xUnit, and both James and Brad have blogged about it as well. The first post of interest to me was this one, then check this one.

After reading all the various points of view on this topic here is what my take away is so far. xUnit is a conscious choice to re-invent a testing framework that is not just another port and extension of JUnit. It features design changes to bring it more in line with where the .NET Framework is, and is heading. Examples of this are the use of Generics and Anonymous Delegates in Asserts.

They have also removed a great number of what they consider extraneous attributes see the quote from James post below:

    • [TestFixture] was removed entirely, so tests can be anywhere.
    • [Ignore] is expressed using the Skip= parameter on [Test].
    • [SetUp] and [TearDown] are removed.
    • [ExpectedException] was replaced with Assert.Throws.
    • [TestFixtureSetup] and [TestFixtureTearDown] are instead expressed as implementations of an interface (ITestFixture).
    • Support for IDisposable was added for tests.

This kind of thinking and approach is long overdue in my own opinion. It will be interesting to watch as the project matures. I have begun playing with it myself and so far I find it a lot more intuitive than any of the JUnit derivatives I have used in the past.

While I like mbUnit I have always had to think harder than I feel I should in order to use it. I get results that are often exactly opposite what I was expecting, which means that I am obviously not understanding something. It is also difficult to get help with mbUnit, while it is not abandonware it does not have a very active community, posts to their list server often go unanswered for long periods of time. And the Google Group discussion forums are none to active either.

Time will tell if xUnit suffers from the same lack of community or not, but so far it looks promising! 

Cheers,

Robert Porter


 
Categories: .NET | Agile | Programming | Reviews | TDD


January 2, 2005
@ 12:41 AM

Hmmm