Archive for February, 2008

Testing, testing

Wednesday, February 13th, 2008

There’s a lot to be said for test driven development. Next to documenting the code, testing is the other bane of a developer’s life that prevents them from moving on and doing other, ‘more interesting’ work. All the better then that the approach to writing code should include the writing of test cases. Write some code, write a test case, make sure it passes, then OK, move on to the next bit. You build confidence in the existing code as you add to it.

Done this way testing doesn’t need to be all that boring. And one of the keys to this is the structure of the code you test. Listen carefully when you ask why testing is a bind and what you’ll find is that developers don’t necessarily mind writing test code, its the work in setting up the right data for the test cases that takes the time. And then updating it as the system evolves. What is happening here is that the unit test exercises an entire monolith of code which in turn requires more detailed configuration than just the one class being tested. And because so much code is being exercised, a change in any area can result in tests in other areas failing. And so the myth that testing is time consuming is perpetuated, because the unit test isn’t a proper unit test.

Producing testable code doesn’t take much additional foresight and in a way is connected to one of the key tenets of OO design – correct assignment of responsibilities. If classes are small and tightly focussed then they are easier to test. Likewise methods – are your methods properly decomposed and does each method have a single clearly defined purpose? If the answer is ‘no’ then you are building code that is harder to test. Moving up a level, you should be designing components with clear and clean interfaces, and using standard techniques such as the Business Delegate pattern to minimise coupling between them. Which, in turn makes it a relatively simple matter to implement component stubs to support the isolated testing of classes, which in turn wipes out much of that data set-up issue.

In short, difficulties in testing OO code can often be ascribed to the structure of the code. Here is a list of points to consider:

  • Write many small, focussed classes rather than fewer, big classes.
  • Restrict methods to performing a single purpose – decompose ruthlessly.
  • Refactor shared/duplicate code into super-classes or helper classes as appropriate.
  • Don’t expose private methods unnecessarily just to make testing easier – use something like the PrivateAccessor class from the JUnit Addons project.
  • Create interfaces for components to allow simple stubbing.
  • Avoid static methods wherever possible.
  • Use the Business Delegate class to minimise coupling between components.
  • Use JUnit to build tests, and Emma to check your coverage

And as I’ve touched on Emma, an excellent tool which allows you to see, line by line, which code has been tested and which has not, I shall finish by briefly discussing test coverage. How much of your code should you test?

Your quality department would probably say “100%” but unless you’re working in a high-risk area (for example, fly-by-wire flight systems for airliners) then you probably won’t have the resources to do this. My take on unit testing is as follows:

  • Don’t write unit tests for bean getters and setters (I’m assuming here that your getters and setters do only that, and contain no complex processing), but do make sure they are exercised.
  • Don’t write test cases to demonstrate that assertions are thrown correctly (you are using assert, aren’t you?).
  • Maximise test coverage on your framework code (errors here will affect your system across the board)
  • Prioritise test coverage on your functional code. Focus on the more complex, riskier and shared code first.
  • If you are back-filling tests on code that has already shipped, focus on those areas causing the most disruption to your customer or support team.

If you’ve written small classes with tightly focussed code, it is actually quite difficult to get your coverage beyond 90% anyway, and the cost of completing those few extra percentage points will, for most situations, far outweigh the benefits.

Next time, the importance of the method contract.

Welcome to the Software Engineering Blog

Friday, February 8th, 2008

Welcome to the Surfsoft Cnsulting blog. Maybe it’s my age (I am over 40 after all) but in the last few years I’ve occupied senior positions in development teams where I’ve spent significant amounts of time trying to educate people not just in how to write code well, but how to undertake the whole software engineering process properly. Development is 80% engineering process and 20% technical skills – a good engineer will pick up new skills quickly and so knowledge of sound engineering practice is extremely important but usually under-rated.

Writing code is, to many developers, the most enjoyable and creative aspect of their work. Many of us, and I’m as guilty as the next person from time to time, rush through design in order to get to the fun bit. However there is a lot more to producing a successful piece of software than just cutting code. My intention in this blog is to share my own experiences and offer advice and suggestions to allow people to better understand and operate within the software engineering process, and to ultimately produce better quality software. Aside from that I will also be blogging about general tech/geek things close to my heart but not necessarily directly relevant to software engineering, but hopefully of some interest.

Before I start blogging in earnest I’d like to tell you a little about myself. You can find out about my career by viewing my public profile on LinkedIn so here I shall focus on the technologies I’ve used, and am using, rather than who I’ve worked for and when.

At Coventry Polytechnic (now Coventry University) I studied Information Systems Engineering and learnt Pascal and C, and assembly language (Z80, 6502, 6809 and 68000) although I already had good knowledge of Basic and assembly language (Z80 and 6502) from school and my trusty ZX81. During my Masters degree (Real Time Electronic Systems at Bradford University) I also studied Ada and Occam.

Between 1988 and mid-1997 I worked with Pascal, Fortran, Cobol and C, along with Ingres and a bit of Sybase on Unix and VMS systems. Between 1997 and 2001 I worked exclusively with Oracle – PL/SQL, Forms and Reports, and from 2001 I have worked exclusively with Java, J2EE and Oracle and MySQL databases. Many languages, several operating systems and a multitude of software engineering processes and configuration management systems.

As far as methodologies go, Waterfall and RAD (Rapid Application Development) reigned until I moved to Java, where iterative development and the RUP (Rational Unified Approach) were initially the mainstays of my development processes. Iterative development still rules but for the last couple of years I have also been working in SCRUM environments.

At this point I should make it clear that everything posted here is my own, personal viewpoint. I am not attempting to represent the views of my current, or any past, employer, and nothing I post should be taken as a criticism, explicit or implied of any of my employers.

And finally… I’m not a brilliant diarist, so please don’t expect regular postings. Lots of postings, yes, but there will be gaps.