Test Driven Development – Is it good or bad?

For short: BAD.

I’ve been thinking about this for a while and reading Michael Puleio’s blog [^] [^] has made me think even more about this.

What is often referred as Test Driven Development (TDD) is actually Test First Development (TFD), which is kind of stupid taking in account tools like Visual Studio 2005 Team Edition for Software Developers (and Professional when Orcas cames out).

Now that TFD is out of the way, my beef is with the Test Driven part (or Example Driven Development (EDD) if you like other flavors). Came on, is your software really being driven by the tests? Are you really writing software just to satisfy your tests? I’m not.

Test driven development also makes you design for testability instead of designing for funcionality, scalability and other such much nicer things. And if you use tools like TypeMock.Net, you can test almost anything without designing for testability.

My software development is driven by the need to comply with requirements. How am I doing it? Assisted by tests. So, I’m doing Test Assisted Development (TAD). (Should I copyright this?)

The Laws of Unit Testing

Reading this post from Michael Puleio’s blog I got to this post from Michael Feathers’ blog. In his post Michael Feathers doesn’t state what a unit test is, but what a unit test isn’t. And, sometimes, this is just enough to help a lot.

A test is not a unit test if:

  • It talks to the database
  • It communicates across the network
  • It touches the file system
  • It can’t run at the same time as any of your other unit tests
  • You have to do special things to your environment (such as editing config files) to run it.
  • Yet Another Way for Using the "using" Keyword

    There are two uses for the C# using keyword:

    1. The using statement:

      Defines a scope, outside of which an object or objects will be disposed.

      using (TransactionScope transactionScope = new TransactionScope())

      {

          // …

      }

    2. The using directive:

      The using directive has two uses:

      1. To permit the use of types in a namespace so you do not have to qualify the use of a type in that namespace:

        using System.Text;

      2. To create an alias for a namespace or a type:

        using Text = System.Text;

        using SB = System.Text.StringBuilder;

    At the last MVP Global Summit, Mads dared the C# MVPs to came up with another way for using the using keyword.

    Taking Mads on his dare, here is my proposal: use it on LINQ.

    There is some kind of non-determinism (from the developer’s point of view) in the code generated from LINQ queries.

    Let’s take, for example, this class:

    public class MyList<T> : List<T>

    {

        public IEnumerable<T> Select<TResult>(Func<T, TResult> selector)

        {

            return null;

        }

    }

    Let’s take an instance of this class and reference it with two variable of different types:

    MyList<string> ml = new MyList<string>() { “one”, “two”, “three” };

    IList<string> il = ml;

    The way the C# compiler expands queries depends on the variable being used.

    This query:

    var qm = fromin ml

             select s.ToUpper();

    will expand into:

    IEnumerable<string> qm = ml.Select<string>(delegate(string s)

        {

            return s.ToUpper();

        });

    And this query:

    var qi = fromin il

             select s.ToUpper();

    will expand into:

    IEnumerable<string> qi = System.Linq.Enumerable.Select<string, string>(il, delegate(string s)

        {

            return s.ToUpper();

        });

    What if I wanted to explicitly use System.Ling.Enumerable.Select on ml but using the query syntax?

    A nice way to do it would be:

    var qm = fromin ml

             select using(System.Linq.Enumerable) s.ToUpper();

    Just like table hints on TSQL.

    Getting MethodInfo using LINQ

    At the last MVP Global Summit, Mads showed me and Rich a way to get the MethodInfo of a method in a strongly typed way using LINQ. Here is how you can do it:

    public static class TypeHelper
    {
        public delegate void Method();
     
        public delegate void Method<TArg0>(TArg0 arg0);
     
        public delegate void Method<TArg0, TArg1>(TArg0 arg0, TArg1 arg1);
     
        public delegate void Method<TArg0, TArg1, TArg2>(TArg0 arg0, TArg1 arg1, TArg2 arg2);
     
        public delegate void Method<TArg0, TArg1, TArg2, TArg3>(TArg0 arg0, TArg1 arg1, TArg2 arg2, TArg3 arg3);
     
        public static System.Reflection.MethodInfo MethodInfoOf(System.Linq.Expressions.Expression<Method> expression)
        {
            return MethodInfoOfInternal(expression.Body as System.Linq.Expressions.MethodCallExpression);
        }
     
        public static System.Reflection.MethodInfo MethodInfoOf<TArg0>(System.Linq.Expressions.Expression<Method<TArg0>> expression)
        {
            return MethodInfoOfInternal(expression.Body as System.Linq.Expressions.MethodCallExpression);
        }
     
        public static System.Reflection.MethodInfo MethodInfoOf<TArg0, TArg1>(System.Linq.Expressions.Expression<Method<TArg0, TArg1>> expression)
        {
            return MethodInfoOfInternal(expression.Body as System.Linq.Expressions.MethodCallExpression);
        }
     
        public static System.Reflection.MethodInfo MethodInfoOf<TArg0, TArg1, TArg2>(System.Linq.Expressions.Expression<Method<TArg0, TArg1, TArg2>> expression)
        {
            return MethodInfoOfInternal(expression.Body as System.Linq.Expressions.MethodCallExpression);
        }
     
        public static System.Reflection.MethodInfo MethodInfoOf<TArg0, TArg1, TArg2, TArg3>(System.Linq.Expressions.Expression<Method<TArg0, TArg1, TArg2, TArg3>> expression)
        {
            return MethodInfoOfInternal(expression.Body as System.Linq.Expressions.MethodCallExpression);
        }
     
        private static System.Reflection.MethodInfo MethodInfoOfInternal(System.Linq.Expressions.MethodCallExpression methodCallExpression)
        {
            return (methodCallExpression == null) ? null : methodCallExpression.Method;
        }
    }

    Usage is also very simple:

    static bool F(string s)
    {
        return !string.IsNullOrEmpty(s);
    }
     
    static void M1()
    {
    }
     
    static void M2(string s)
    {
    }
     
    static void M3(string s1, string s2)
    {
    }
     
    static void Main(string[] args)
    {
        MethodInfo fi = TypeHelper.MethodInfoOf((string s) => F(s));
        MethodInfo mi1 = TypeHelper.MethodInfoOf((string s) => M1());
        MethodInfo mi2 = TypeHelper.MethodInfoOf((string s) => M2(s));
        MethodInfo mi3 = TypeHelper.MethodInfoOf((string s1, string s2) => M3(s1, s2));
    }