Saturday, 29 January 2011

A Guide to Test Driven Development in Flex – Part 1: Defining What The SUT Does

In the Introduction to this series of tutorial blog posts I described why I use unit testing and why I think that TDD is an especially good way to write both unit tests and the actual classes you’re testing – which I refer to as the SUT or System Under Test.

Before we write any code for either the SUT or the unit tests we need to think about what the class needs to do. For this we need some requirements for the application or component that we are building.

I have decided to write a reusable component that will popup when writing in a text field and allow you to select an entry to insert into your text. An example of where this would be used is in a twitter client. You would provide the component with a list of user names and tell it that the initial symbol is an @ symbol. You would then bind the component to a given text field. When typing in the text field if I typed @ my component would popup and display your list of usernames. As you type the list would filter and when you select an item from the list the username would be added to the text that you were typing.

So now we have a basic and not very well written requirement we can start to define what the component will do and what we need to test. I will be writing the component following the Presentation Model pattern so all of the logic for the view component will reside in the presentation model so that it’s easily testable.

First off we probably need to think of a name for the component. I thank that AutoCompletePopup is a pretty good name that goes some way towards describing what the class does. AutoCompletePopup will probably extend PopupAnchor and will have inside it an AutoCompleteComboBox which will extend ComboBox. This compositional approach will enable us to re-use the components in other ways in the future more easily. Amongst these view components we’ll also need our presentation model which we’ll call AutoCompletePM. Our test will be called AutoCompletePMTest.

We can create these two classes now. Usually they will both be in the same package but I usually have them in different source folders. Alongside the default src folder I create a test folder:

So far we just have 2 empty classes:

We now need to start defining what functions the SUT will perform and then create at least one test for each of these functions.

The SUT will perform the following actions:

open the popup when auto-completion is required

filter the list of available items based on text input

when an item is selected dispatch an event to insert that text into the text field

if the Escape button is pressed close the popup without inserting any text

As we can see this is going to be a fairly simple class. From this list we can start to define our tests. Each test should ideally test 1 function call or property update on the class and test that we get the response that we expect. We may well test the same function call multiple times for different situations and each of these calls should be made in a different test.

Lets start with the first function:

open the popup when autocompletion is required

This is still a slightly unclear requirement. What it means is that when the user types the startSymbol (for example an @) we want to open the popup. Let’s add an empty test that will test this situation:

This isn’t quite enough though. We also need to test that if we type anything other than the startSymbol the popup won’t open:

At the moment we’ve assumed that the popup will start off closed but we should make sure by testing the initial state of the PM after construction:

We’ve now got some initial empty tests but we still don’t have anything defined on the SUT. For the SUT to open a popup when a user types a certain symbol the SUT is going to need some properties and functions so that other classes can communicate with it.

To open the popup we can have a bindable Boolean showAutoCompletePopup property. The class also needs to know what the startSymbol is so we can define that as another property. It needs to know what is being typed in the text field so we can create a textEntryHandler method and it needs to know what is being typed in the popup so we can create another property called filterText:

We then follow these steps for the other requirements as well. When you finish you’ll end up with something like the code here.

By following this process we have now defined a small clean public interface for our class. We have our public properties and methods defined. A developer looking at these properties and methods should find it fairly easy to work out what the class does and how to use it.

The only thing that we have not defined yet is the events that the class will dispatch. You could do this now if you like but I usually do this later.