I am searching for a new TDD example


I am looking for a new example to demonstrate Test Driven Development. In the TDD book that Alexei and I wrote we demonstrated TDD using a Stack. For a copy of the chapter see http://workspaces.gotdotnet.com/tdd. We felt that this was a good example to demonstrate how to do TDD. Since then we have received some feedback from people who bristle at the Stack example because most people don't write Stacks and want an example that is closer to what they work on day-to-day. 

However the difficulty comes in when trying to do something real-world is that you end up explaining the problem more than the process. This is why I felt the Stack was a good example because very little problem description is needed and most of the time is spent focusing on the issues related to TDD. The other issue and one that I feel is more compelling for changing the example is that I would like to have an example that demonstrates collaboration between objects.

So your task, if you wish to accept it, is to come up with an example that does not take a great deal to explain, demonstrates collaboration between objects and could be done concisely in 3-4 hour demonstration.

Thanks for your help in advance.  

 

Comments (31)

  1. Sweet Book Man. Just love it.

    How about a simple banking application where you can add money, withdraw, have different accounts etc.

    There will be good tests to make sure that when you deposit and then withdraw you should have some consistency to that. Also things like compound interest would be cool to test.

    This is the most basic application I can think of from the top of my head. Something for a introductory programming class.

    Doing those easy problems will help foster the use of testing earlier on for new comers to programming which is always good 🙂

    Hope this helps.

  2. Lasse says:

    How about a parser of some sort? Something like the calculator example from Herbert Schildt’s "The Art of Java"?

  3. Jeff Julian says:

    A simple Customer / Product example would be great. I would load it from a database using the provider model, showing the test fixtures for the Data Access Block, DataProvider, data management layer, and your component layer. Sounds complex, but if you have a database-centric application(web|win) and want to implement TDD, this is what you have to do and no one show you how to do it.

    BTW…After you write the 92+ test for the PAG Data Access Layer, make sure you add it to the DAL project. This would have been very beneficial for me.

  4. Jeff Lewis says:

    I’ve been meaning to write-up a TDD example of how to authorize a credit card via Authorize.NET.

    If you beat me to the punch, all the better. I’d even be willing to share the source of the component that I sell to make things easier…

    Let me know,

    jeff-at-consultutah.com

  5. David Hayden says:

    I used TDD for the first time when building a custom shopping cart for a client. Everyone gets the concept of a shopping cart, and you can make it as simple or complex as you want given your time constraints.

  6. Wes Shaddix says:

    Create a class that authenticates users against various active directories. It should validate that the username/password is valid and also support retrieving the groups (roles) that the user is a member of. You may or may not have access to a test environment with an AD present (so would you recommend Mocking some of the ADSI interfaces?)

  7. AndrewSeven says:

    This is some stuff I wrote when I was starting to do some TDD, but I never quite got around to finishing the article.

    http://weblogs.asp.net/andrewseven/articles/213082.aspx

    The code is not great, it was an adventure in test.

    If you think it might be interesting, I can send you the zipped solution.

  8. Write a Forms application that does simple asynchronous actions, like a timer (start, stop, show duration) whith some mouse tracking, etc… The codebase of the application should not exceed 100 lines

    🙂

  9. senkwe says:

    How about a game of tic-tac-toe that runs on the console. I’m thinking the objects involved could be the board "drawing" objects, player objects, scorecard etc…

    And I guess later on you could show how much easier the resulting code could be extended to form the basis of a simple WinForms based tic-tac-toe game 🙂

  10. James Snape says:

    We always ask one of two design questions in interviews as they are short and well known:

    1. Video Shop Rental System – You have tapes and DVDs containing films, you can reseve films and for the extra mile we add tape depreciation (max number of times a media can be rented)

    2. Lift Control – Number of floors, call button vs up/down button, Number of lifts etc…

    Regards,

    James.

  11. Joe says:

    I’ve always found it interesting when testing/mocking within web applications. So how about some (tricky) tests for some functionality that interacts with the HttpContext? Perhaps a function that retrieves something from the Session and displays the contents on a webform? This need not be a test that actually makes a request – so no need for ASPNUnit – but you would need to retrieve objects from the Session. It’s not brain science but it would introduce some interesting nuances to TDD within web apps.

    Really enjoy your posts – keep them coming. Some more insights into TDD in VSTS would definately be appreciated.

  12. One nice sample I did recently while testing for code coverage is a "four function" calculator with a % sign, memory and a repeating equals key, but it doesn’t really have any inter object collaboration.

    Another alternative might well be a ATM machine, talking to a backend database. Everyone knows that interface well but it has the advantage of forcing a pile of "abort" and "transaction unroll" into your code.

  13. Bob Flanders says:

    It’s always a pain to come up with "an example that is closer to what they work on day-to-day", but probably a significant percentage work on data retrieval, manipulation and update applications.

    So… how about a "generic" example, showing TDD when building objects that represent a data store. Use a simple data source like demographic data (Name, Address, Date Of Birth, etc.) I think a lot of readers could relate to such an example.

    We were writing these types of objects and associated test so often, we wrote a code generator that would look at the structure of the data source, build the object representing that source and the baseline tests for that object.

    Best regards…

  14. I’d prefer to see an example using a database. An example that springs to mind is an order system. Because for me I love the concept of TDD but I am struggling to work with it currently as most of my projects involve dataclasses that interact with SQL Server and I just can’t seem to write good unit tests.

    By the way your book is great!

  15. Allan Halme says:

    How about some form of adaptation of the Automotive Work Order presented as an example in "Elements of Service-Oriented Analysis and Design" at http://www-106.ibm.com/developerworks/library/ws-soad1/.

    I would imagine that you could simplify this as much as you wanted, or add complexity — but it’s a domain with which most people are familiar as clients or customers, and you can vary the scale of the complexity of your model and implementation quite a bit.

    Regards,

    allan

  16. Roy Osherove says:

    When I teach people TDD in a hands on lab, I usually start in a very simple example:

    1. A simple Calculator with 1 or two simple Addition and division operators.

    2. Add more features to the calculator:

    2.1. Some logic to throw a custom excpetion when zero is passed in to some method.

    2.2 Make a method that recieves a file and sums up all the numbers inside it and returns the result.

    2.3 make the format of the file variable: delimiters suddenly change, or are added to the file format.

    2.4 Make the Calculator write out an XML file with the numbers and the result.

    the idea here is to keep the tech stuff VERY simple and focus on technique. This way people are eased into TDD without too much fear. The farther we go along with 2.x features we need to refactor the code better. For example: a parser class and a OutPutWriter class could be added. and so on..

    No Database!. it’s about technique, not technology.

  17. Darrell says:

    What about a "Bookmark" library. That way you could have Add and Delete bookmark functionality, creating folders, moving bookmarks, copying bookmarks, etc. Again, everyone would understand the domain, since everyone at least uses a browser, and you can take it as far as you want. For example, folders could be represented as Bookmark Collections or as simple containers and could be nested. Bookmarks would have different responsibilities, etc.

  18. Darron says:

    How about a connection string dispenser that takes a namespace, resource and returns connection strings (or connections for that matter) ready for use with the DAAB?

  19. Kevin Dente says:

    I have to disagree with RoyO on this one – I think include database access in the example would be a very good thing. Or, more generally, showing interaction with external objects. It’s is one of the tricker (and yet most common) aspects of TDD for beginners, and would be a good thing to demonstrate. One of the problems I’ve seen with TDD adoption is that when people get stuck on tricky TDD issues (like dealing with external systems or UI), it’s easy to bail out and return to the old ways, especially if it’s early in the TDD evaluation cycle.

    As for suggestions, I’ll throw in a vote for a TDD UI example – maybe a simple dialog box. That requires interacting with the Control classes of the framework, and most people understands the basics of dialog boxes.

  20. I have had the same problem with my TDD presentations at various UGs and conferences.

    I used to demonstrate TDD to the audience by building a custom sorter with them (System.Collections.IComparer implementation – http://www.aspalliance.com/461) since it felt real world and showed the evolution of some reasonably complex code (TDD triangulation technique). The problem was that it involved reflection to sort on business object properties and some of the audience struggled with the code which detracted from the TDD techniques.

    I have since changed the example to a simpler more typical real world application – an ASP.NET based employee search. The audience easily relates to this topic and the code is simple – the biggest problem is time since it involves NUnit, NUnitAsp and initializing a test database instance. Most corporate developers probably always use a database in their applications so it is difficult to avoid as it is likely to be their first hurdle when beginning TDD. That example takes at least 2 hours which makes for a long presentation when you add the theory (slides) portion too.

    I didn’t like the Stack example in the book for the reasons you state … I have never needed to write a Stack in my career so it felt too academic (although it *did* demonstrate TDD effectively).

    Good luck finding a new example! I am keen to see what you pick. 🙂

  21. rido says:

    The Database stuff is covered enough in your book.

    I’ve been promoting TDD in a 15 people team for a year, and our experience about ‘real world’ testing always involves external resources that are easy to use but not easy to test in isolation.

    Here are some challenges to TDD !!

    Authentication based on X509 Certificates

    Http Client with Retry Logic

    Integration with external Web Services

    Task Scheduler

    Interoperabilty (COM<->Java<->.NET)

    regards

    :rido

  22. I just did an app as a part of a TDD and OO mentoring and consulting gig that parsed fixed length text files. It turned out to be a great TDD experience where I was able to demonstrate micro-incremental development and evolving code. The goal was to create simple business objects that would encapsulate a row of fixed length text data (and ultimately to write a reader that would pull data from a file and feed it into the parsing objects).

    The example worked really well because we could start with a simple test fixture that has a string member (called “rowData” or what-have-you), and write test methods that asserted that certain values were located at certain indexes on the row. The simplest test fixture looked like the following:

    [TestFixture]

    public class RowFixture

    {

    string rowData = "1JimNewkirk";

    [Test]

    public void Id()

    {

    Assert.AreEqual("1", this.rowData.Substring(0, 1));

    }

    [Test]

    public void FirstName()

    {

    Assert.AreEqual("Jim", this.rowData.Substring(1, 3));

    }

    [Test]

    public void LastName()

    {

    Assert.AreEqual("Newkirk", this.rowData.Substring(4, 7));

    }

    }

    This was before we even had a target class to test. Next we identified some repetition that we wanted to encapsulate. Rather than have to invoke String.Substring(), we decided to encapsulate these calls, which led to encapsulating the row data:

    public class Row

    {

    private string data;

    public string Id

    {

    get{return this.data.Substring(0, 1);}

    }

    public string FirstName

    {

    get{return this.data.Substring(1, 3);}

    }

    public string LastName

    {

    get{return this.data.Substring(4, 7);}

    }

    public Row(string data)

    {

    this.data = data;

    }

    }

    With the fixture:

    public class RowFixture

    {

    string rowData = "1JimNewkirk";

    Row row;

    [SetUp]

    public void CreateRow()

    {

    this.row = new Row(this.rowData);

    }

    [Test]

    public void Id()

    {

    Assert.AreEqual("1", this.row.Id);

    }

    [Test]

    public void FirstName()

    {

    Assert.AreEqual("Jim", this.row.FirstName);

    }

    [Test]

    public void LastName()

    {

    Assert.AreEqual("Newkirk", this.row.LastName);

    }

    }

    We then tackled the duplication of calls to Substring() by creating a ParsedField class:

    public class ParsedField

    {

    private readonly int startIndex;

    private readonly int length;

    private readonly Row row;

    internal int StartIndex

    {

    get{return this.startIndex;}

    }

    internal int Length

    {

    get{return this.length;}

    }

    public string Value

    {

    get{return this.row.Data.Substring(this.startIndex, this.length);}

    }

    public ParsedField(int startIndex, int length, Row row)

    {

    this.startIndex = startIndex;

    this.length = length;

    this.row = row;

    }

    }

    And the fixture:

    [TestFixture]

    public class ParsedFieldFixture

    {

    [Test]

    public void Value()

    {

    Row row = new Row("1");

    ParsedField parsedField = new ParsedField(0, 1, row);

    Assert.AreEqual("1", parsedField.Value);

    }

    }

    Which caused us to create the Data property on Row:

    public string Data

    {

    get{return this.data;}

    }

    We then changed the Row class to use the ParsedField class:

    public class Row

    {

    private string data;

    private ParsedField idField;

    private ParsedField firstNameField;

    private ParsedField lastNameField;

    public string Data

    {

    get{return this.data;}

    }

    public string Id

    {

    get{return this.idField.Value;}

    }

    public string FirstName

    {

    get{return this.firstNameField.Value;}

    }

    public string LastName

    {

    get{return this.lastNameField.Value;}

    }

    public Row(string data)

    {

    this.data = data;

    this.idField = new ParsedField(0, 1, this);

    this.firstNameField = new ParsedField(1, 3, this);

    this.lastNameField = new ParsedField(4, 7, this);

    }

    }

    We ultimately refactored the tests to reuse the Row instance through inheritance, made the Row abstract and created a TestRow with the specifics, etc. It was a good way for me to teach TDD and OO in a context that the developers could identify with, without getting into data connections, etc.

    The framework later evolves to use strongly-typed readers, type discriminators, and all kinds of simple yet complicated things for a non-OO person to whet their OO appetite with.

    I’ll be using this example in some upcoming presentations on TDD in my area of the world this fall.

    Cheers!

    (And I too love the book… one of the best books on programming – period – since Refactoring. Much thanks from me and my team!)

Skip to main content