This post originated from an RSS feed registered with .NET Buzz
by Udi Dahan.
Original Post: Behavior Specification, the next generation of unit testing
Feed Title: Udi Dahan - The Software Simplist
Feed URL: http://feeds.feedburner.com/UdiDahan-TheSoftwareSimplist
Feed Description: I am a software simplist. I make this beast of architecting, analysing, designing, developing, testing, managing, deploying software systems simple.
This blog is about how I do it.
After practicing unit testing for over two years, refactoring (as in with unit tests) for about the same, and TDD for over a year, I've finally found out how it really should be done. I'm working on an article that'll explain this in greater detail. The result is this:
Two assemblies, one for the interface, one for the implementation, "tests" go in the interface assembly. For example:
Interface project: Udi.Collections
File: IStack.cs
Content:
public interface IStack
{
void Push(object o);
object Pop();
int Count { get; }
}
File: StackBehavior.cs
Content:
public class StackBehavior : BehaviorSpecifier<IStack>
{
[Behavior]
public void First()
{
int count = this.thing.Count;
object o = 1;
this.thing.Push(o);
Assert.AreEqual(count + 1, this.thing.Count);
object result = this.thing.Pop();
Assert.AreEqual(o, result);
Assert.AreEqual(count, this.thing.Count);
}
}
public class Stack : IStack
{
#region IStack Members
public void Push(object o)
{
list.Add(o);
}
public object Pop()
{
object result = list[list.Count - 1];
list.RemoveAt(list.Count - 1);
return result;
}
public int Count
{
get
{
return list.Count;
}
}
#endregion
private IList<object> list = new List<object>();
}
***
Then, right click on the implementation project, and select 'Verify Behavior'. The results appear just like regular tests run with TestDriven.net.
Some reasons why this is better:
1. Tests (behaviors) are dependent only on the interface, which reduces the cases where developers will have to refactor test code as a result of implementation changes.
2. Should a new implementation come along, we can reuse the tests already written with zero effort.
If you'd like to give this a try (using .net 2.0), leave me a comment and I'll send you the plugin for TestDriven.