programmers quotes

February 19, 2009

Programmers who write tests get more time to program

Filed under: Java,Programming — Tags: , — Johannes.Brodwall @ 8:35 pm

I became a programmer so that I could spend time creating software by programming. I don’t want to waste my time managing low-quality code.

Does your code work the first time your test it out? Mine certainly never does. So if I hand over the code to someone else, I’m sure to get a bug report back that will take up my valuable programming time. This much is obvious to most developers. However, it also means that I don’t want to have to go thought a long manual test myself to verify my code.

The first thing I do when I’m starting on a programming task is ask myself: “How am I going to test that this actually works?” I know it has to be done, I know it will take up a lot of my time if I do a poor job of it, so I want to get it right.

A good way to start is by writing tests before you write the code. The tests will specify the required behavior of the code. If you write the tests with the question: “How will I know when my task is complete?” The chances are that not only will your tests will be better for it, your design will also have improved.

I’ve come to code bases that were otherwise good, but that required me to write a lot of code to support my tests. In other words: The code was overly complex to use.

For example, a system that is built with an asynchronous chain of services connected via a message bus might require you to deploy your code before you can test it. I’ve redesigned such code in a couple of steps that progressively reduced the coupling, improved the cohesion, and simplified the testing of the code:

  1. Allow the code to be run synchronously and in-process by a configuration change. The messaging infrastructure is no longer coupled to the business logic. The resulting design is both easier to follow and more flexible, in addition to being easier to test. However, testing still requires setting up a long chain of services.
  2. Refactoring my services to calculate the result they send to the next service by using a transformation function made the responsibilities of different parts of the code clearer. And I could test almost all the logic by just calling this transformation function and checking the return value.

When encountering a programming task, ask yourself: “How can I test this?” If the answer is “Not very easily” try to write a test anyway. The test will probably require a lot of setup and it may be hard to verify the results. These are design problems, not test problems. Use the information from the testing process to refactor your system to a better design.

May you achieve fewer bugs and spend all your days programming happily in a well-designed system!

Improvements to this text are very welcome.

Keep the build clean

Filed under: Java,Programming — Tags: , — Johannes.Brodwall @ 8:32 pm

Have you ever looked at a list of compiler warnings the length of an essay on bad coding and thought to yourself: “You know, I really should do something about that… but I don’t have time just now”? On the other hand, have you ever looked at a lone warning that just appeared in a compilation and just fixed it?

When I start a new project from scratch, there are no warnings, no clutter, no problems. But, as the code base grows, if I don’t pay attention, the clutter, cruft, warnings, and problems can start piling up. When there’s a lot of noise, it’s much harder to find the real warning that I really wanted to read among the hundreds of warnings I didn’t care about.

To make warnings useful again, I use a zero-tolerance policy about warnings from the build. Even if the warning isn’t important, I deal with it. If it’s relevant, but not critical, I still fix it. If the compiler warns about a potential null-pointer exception, I fix the cause, even if I “know” the problem will never show up in production. If the embedded documentation (Javadoc or similar) refers to parameters that have been removed or renamed, I clean up the documentation.

If it’s something I really don’t care about and that really doesn’t matter, I ask the team if we can change our warning policy. For example, I find that documenting the parameters and return value of a method in many cases doesn’t add any value, so it shouldn’t be a warning if they are missing. Or, upgrading to a new version of the programming language may make previously okay code now emit warnings. For example, when Java 1.5 introduced generics, all the old code that didn’t specify the generic type parameter would give a warning. This is a sort of warning I don’t want to be nagged about (at least, not yet). Having a set of warnings that are out of step with reality does not serve anyone.

View of Oslo

By making sure that the build is always clean, I will not have to decide that a warning is irrelevant every time I encounter it. Ignoring things is mental work, and I need to get rid of all the unnecessary mental work I can. Having a clean build also makes it easier for someone else to take over my work. If I leave the warnings, someone else will have to wade through what is relevant and what is not. Or more likely, just ignore all the warnings, including the significant ones.

Warnings from your build are useful. You just need to get rid of the noise to start noticing them. Don’t wait for a big clean-up. When something appears that you don’t want to see, deal with it right away. Either fix the source of the warning, suppress this warning or fix the warning policies of your tool. Keeping the build clean is not just about keeping it free of compilation errors or test failures, warnings are an important and critical part of code hygiene.

« Newer PostsOlder Posts »