Search code examples
tddagile

TDD: Where to start the first test


So I've done unit testing some, and have experience writing tests, but I have not fully embraced TDD as a design tool.

My current project is to re-work an existing system that generates serial numbers as part of the companies assembly process. I have an understanding of the current process and workflow due to looking at the existing system. I also have a list of new requirements and how they are going to modify the work flow.

I feel like I'm ready to start writing the program and I've decided to force myself to finally do TDD from the start to end.

But now I have no idea where to start. (I also wonder if I'm cheating the TDD process by already have an idea of the program flow for the user.)

The user flow is really serial and is just a series of steps. As an example, the first step would be:

  • user submits a manufacturing order number and receives a list of serializable part numbers of that orders bill of materials

The next step is started when the user selects one of the part numbers.

So I was thinking I can use this first step as a starting point. I know I want a piece of code that takes a manufacturing order number and returns a list of part numbers.

// This isn't what I'd want my code to end up looking like
// but it is the simplest statement of what I want
IList<string> partNumbers = GetPartNumbersForMfgOrder(string mfgOrder);

Reading Kent Becks example book he talks about picking small tests. This seems like a pretty big black box. Its going to require a mfg order repository and I have to crawl a product structure tree to find all applicable part numbers for this mfg order and I haven't even defined my domain model in code at all.

So on one hand that seems like a crappy start - a very general high level function. On the other hand, I feel like if I start at a lower level I'm really just guessing what I might need and that seems anti-TDD.


As a side note... is this how you'd use stories?

As an assembler I want to get a list of part numbers on a mfg order So that I can pick which one to serialize

To be truthful, an assembler would never say that. All an assembler wants is to finish the operation on mfg order:

As an assembler I want to mark parts with a serial number So that I can finish the operation on the mfg order


Solution

  • Here's how I would start. Lets suppose you have absolutely no code for this application.

    1. Define the user story and the business value that it brings: "As a User I want to submit a manufacturing order number and a list of part numbers of that orders so that I can send the list to the inventory system"
    2. start with the UI. Create a very simple page (lets suppose its a web app) with three fields: label, list and button. That's good enough, isn't it? The user could copy the list and send to the inv system.
    3. Use a pattern to base your desig on, like MVC.
    4. Define a test for your controller method that gets called from the UI. You're testing here that the controller works, not that the data is correct: Assert.AreSame(3, controller.RetrieveParts(mfgOrder).Count)
    5. Write a simple implementation of the controller to make sure that something gets returned: return new List<MfgOrder>{new MfgOrder(), new MfgOrder(), new MfgOrder()}; You'll also need to implement classes for MfgOrder, for example.
    6. Now your UI is working! Working incorrectly, but working. So lets expect the controller to get the data from a service or DAO. Create a Mock DAO object in the test case, and add an expectation that the method "partsDao.GetPartsInMfgOrder()" is called.
    7. Create the DAO class with the method. Call the method from the controller. Your controller is now done.
    8. Create a separate test to test the DAO, finally making sure it returns the proper data from the DB.
    9. Keep iterating until you get it all done. After a little while, you'll get used to it.

    The main point here is separating the application in very small parts, and testing those small parts individually.