Building A Web-App 103: Managing Your Project

"What?", exclaimed the happy dolphin with a tear in her eye. "Part three of the endless saga of building a web-app? About time!"

In order to keep our Odontoceti friends happy, please read on to find out about how best to train your project to jump through hoops and other humiliating things (sans-PETA).

Part Three - Managing Your Project

Once more into the breach dear friends! The Pragmatic Programmers once wrote that "programmers are constantly in maintenance mode". Because of that, managing a project and it's code can be one of the most important factors that influence it's lifespan. If you don't have a way of tracking changes, recovering from disasters (caused by those pesky developers and those pesky computer things themselves), preventing death-march style feature creeps and other nightmares, then you're project (and your development team) is probably not going to survive for that long. You should probably also rush out and purchase a copy of Ship It!, or The Little Book of Calm. or something...

All misguided attempts at humor aside, go and buy Ship It - it's very informative and chock full of ways to help you retain your sanity, whether you are a developer, manager or client.

In developing our invoice system I had it easy - I had no team to manage, and I got to set the features. However, once it reached the point where it was possible to do some basic tasks with the system, it became necessary to work out what needed to be done next. As such, a TODO list was written up of what I wanted to see next - tasks such as adding authentication, a more serious set of unit tests, moving the system into SVN, emailing invoices and the such. Keeping track of what needs to be done is a crucial part of any project, regardless of size. Ship It! refers to "The List" frequently, and for good reason - if you don't know what you're building, how are you going to know when you get there, or when you are going in the wrong direction?

Of the tasks I set out for myself, placing the project into Subversion was the first of those tasks to be done, as it would make working on the system in dribs and drabs (usually after midnight on random evenings) far easier to manage. It also meant that I was able to sleep safe in the knowledge that I actually had an off-site backup. Subversion can help to force you to break up complex changes into a set of smaller, yet functionally complete parts. For example, you might add in a new feature over a variety of commits, with the final one putting it all into action. Each commit can be only a short dash of work - a technique some people seem to find handy in getting work done.

Coming back to the system we've been developing, it didn't take long for each small TODO item to be crossed off - more tests arrived in r24, authentication was finally committed in r27 (just over a month since the first mockups were drawn), fine-tuning of the invoice details in r43, and a whole host of other minor tasks. The advantage of having "The List" is that when you find something that needs to be done, you jot it down on the list. You can reassess it later if it really should be on the list, but at least you have captured it. Most importantly, it doesn't silently sneak in and divert you from that task that you have already been working on for the past half an hour.

Finally, The List also makes it possible to see when a new feature fits with the purpose of the rest of the application. In our case, when I stumbled upon the ATO's code to validate whether an ABN is valid or not, a quick glance at the list showed that it was probably something we could do with.

If The List tells you what needs to be done, tests tell you when you've actually completed them. In the invoice project, unit tests were written to test all of the major logic used in the models. For example, we test whether the dates given to our new Invoices are actually calculated correctly, whether Invoices that have been paid are closed off correctly, whether some of our more complex relationships correctly take notice of flags in calculations and a whole host of other functionality.

Although I haven't had a chance to play with Test Driven Development quite as much as I might have liked to, what tests I have used have saved my bacon a couple of times in this project. In the first case, there was an issue with using MySQL on the laptop (where I'm developing the system) and SQLite3 on our server (where I'm deploying the test and production servers). You see, SQLite3 was saving some of our foreign keys as an empty string (or 0, or something), rather than NULL as I had assumed. This was causing us all sorts of problems when SQL conditions were "invoice_id IS NULL". Our tests caught this on the live system when they didn't get what they expected and screamed blue murder. Beef up the relevant tests to detect the breakage, fix the code, test again, and commit.

The second time tests saved my smokey pork was only recently. I had decided that as that both the BillableCharge and SubscriptionCharge models had common code, it made sense to extract that out into a Charge superclass. Not a hard process, but since when has that stopped anyone from screwing it up? I inevitably ended up copying non-common code out into the Charge class, meaning that the model I copied the code from continued to work, but the other was quite, quite broken! Tests caught that fairly quickly, and until that point I had absolutely no idea anything was even wrong! A quick backpedal to put the specific code back in it's right place, add more tests to catch the case more thoroughly, re-test and commit.

You would be surprised at how easy testing your code can be, given all of the suitable test libraries out there for a whole host of different languages. Even broad tests are better than no tests.

So, after all of that you're now up to speed with my adventures building the new GMM invoicing system. What's up next? Hopefully some integration with some really good simple time tracking software that I know of, some PDF output goodness (woo! FOP beta goodness!), more reports, and other goodies. There's plenty more to be done, but it's more than enough for me to no longer need to fire up OpenOffice every time I have to invoice someone.

If you're lucky enough to be receiving one of our freshly pressed invoices, please let us know what you think - we're always open to feedback and comments about our new toy.