Friday, 4 May 2012

Beware the Complacency Unit Testing Brings

One phrase that is always sure to raise the ire of any good honest developer when something breaks is:-

“well, it works on my machine”

This simple statement shows a complete disregard for any other sort of testing that you might need to do to ensure that your feature works correctly and is “done, done” not just almost done. But there is a new kid on the block when it comes to showing how little some people understand about software development that I’m beginning to hear with alarming regularity:-

“well, all the unit tests passed”

It seems that modern development practices have unknowingly created the Silver Bullet that Fred Brooks has always told us never existed! Apparently good unit test coverage and automated refactoring tools means that it’s highly unlikely that any bug would only show up during integration and system testing that those ideas are just old fashioned. Or, if not altogether outdated, then reduced to just a footnote in the product’s testing strategy on the basis that there is so much less value in them than unit testing.

Don’t get me wrong I can understand a genuine mistake caused by a seemingly unrelated change - accidents happen and it could be a fault of the design - but changing the configuration file for a service and then not even bothering to see if it starts up is just laziness. Yes, it does take time and effort to do more extensive testing in your sandbox but the feedback loop could still be fast and you won’t annoy your team mates when you cost them a day’s system testing because of a silly mistake.

The rule of thumb about not checking in code until the unit tests pass was designed to make you think about writing fast tests so that the barriers to testing are as low as possible, it was not expected to be used as a justification for short-circuiting the amount of testing you do.

My “Agile SQL Tweet” Slide

Before I put the PowerPoint slides for my ACCU conference talk on Database Development Using TDD up on my web site I agonised over whether to remove the 3rd slide or not. The slide in question just contains the following tweet from Allan Kelly:-

@chrisoldwood is the only person I know with a convincing Agile SQL story -- @allankelly

I felt that viewing the slide in isolation would only amplify the arrogance which could be attached to it and that wouldn’t have a positive effect. But at the same time I felt I should put up what was shown and accept that perhaps it may also raise the same questions that I had that caused me to put it in the first place.

The slide forms part of the prologue and was originally just a picture of myself to act as a backdrop whilst I spent a couple of minutes describing who I was and what I did as I’m not a database developer per-se, I’m mostly a C#/C++ service layer guy who has slipped into the SQL arena like many similar developers. As a consequence I have tried to work with the RDBMS in the same way that I would approach anything else, by using TDD and abstracting the client from the underlying implementation. So, rather than couple the client and database code tightly with client-side SQL[*] I have kept them decoupled to allow the database to develop (and therefore be refactored) independently where possible - I don’t expose public fields in my types[#] so why directly expose tables?

And then this tweet from Allan Kelly appeared. Until that moment I suspected I was the proverbial square peg trying desperately to fit into a round hole, but maybe, just maybe, I might not be barking mad after all. There are many benefits to TDD (and unit testing in particular) over and above proving the functional correctness of a piece of code, but I don’t understand why more people can’t see that.

So the slide should hopefully provoke a reaction that forces you to question what your database development tools and processes are and whether you’re getting the most out of them. If you are then great, it’s working for you, but if you have that uneasy feeling that you’re stymied at every turn because your database can’t evolve quickly enough then perhaps what you’re about to see (and hear, if you attended) will provide food-for-thought about what you could change.

Prior to this the most ‘positive’ reaction I’ve had to what I’ve been suggesting is:-

“I suppose it makes sense, I’ve just never seen it done like that before”

[*] I’m not just talking about explicit embedded SQL here where the SQL code is a string literal (or as a format string) but also where it is implicit as a by-product of a technology such as LINQ-to-SQL. One way or another the schema is likely to be too tightly coupled to the calling code and that means your database design will be harder to change as will remediating performance problems.

[#] Some would argue that a DTO (Data Transfer Object) does exactly that, but a modern RDBMS is so much more than just a data persistence mechanism. Use its power where it makes sense to.

Wednesday, 2 May 2012

My ACCU Conference Session - Database Development Using TDD

400_image

It’s been a busy few weeks as I’ve been preparing to present at the 2012 ACCU Conference in Oxford. This has become somewhat of a pilgrimage and for the second year running I’ve been accepted as one of the speakers; this time to talk about using TDD to develop databases. This was an excuse to piece together some of the ideas that I’ve been blogging about along with the experiences gained with my current client to present one way that can use tests to drive both the development and design of a database.

Session Details

The talk started by walking you through the pre-requisites needed to embrace TDD, such as your own development sandbox and looked at the primary testing mechanism[*], i.e. unit testing SQL. I also spent a fair bit of time covering the notion of a database’s public interface as I personally feel that the modern RDBMS gives you the tools to build an abstraction layer to help decouple the client from the data model to grant freedom of implementation[#].

Naturally I explained the principles of TDD and did a 20 minute live coding session to show how I would use them to develop a reporting style stored procedure. For this I used my own SS-Unit testing framework and SQL Server Express; switching rapidly between test code & production code. With the main body of the talk in the bag I turned to the opportunities that TDD (although really unit testing) opens up such as continuous integration, continuous deployment and schema refactoring.

The PowerPoint slides are available on my web site here.

Abstract

Just for the record this was the abstract that I submitted...

The modern day RDBMS is a complex product that offers so much more than just data persistence. The SQL language, with its vendor specific variants such as T-SQL, provides the ability to develop code in various forms to read, transform & write that data efficiently. This code requires constant testing right from its inception through its various incarnations until it is finally retired.

TDD is a technique that puts writing those tests at the front of the development process, whether that be because you’re writing new code or changing existing code. The knock-on effect of this approach is that your client-based perspective opens your eyes to potential variations in the implementation, and that is where the second ‘D’ in TDD turns from Development into Design. With a solid automated test suite and Continuous Integration under your belt too the world of refactoring opens itself up so that your database design can safely evolve.

This session looks at applying the same principles and disciplines used in other areas of system development to tame the ever increasing complexity that has arisen from the maturity of the RDBMS.

Photo

The above photo of yours truly comes courtesy of Mark Ridgwell. Here are the rest of his photos for Wednesday.

[*] TDD does not prescribe any particular type of testing but I believe that most people associate TDD with unit testing as it probably forms the lions share. I did point out that one of the benefits of a top-design and implementation is that you can start development with a system test and drill down from there.

[#] ORM tools like Entity Framework actually push you in the other direction which may be exactly what you want. But as I’ve said before, Enterprise culture has a habit of routing around nicely designed service layers and attempting to go straight to the heart of the data.