Cedric on Testing

I like how Cedric articulates his approach to testing:

Typically, I code a feature, iterate over it a few times and I reach a point when I’m pretty happy with its shape: it’s looking decent, it gets the job done and while there is obviously more work to be done on it, it’s mature enough that writing tests for it at this point will not be a waste.

Unit Tests are Tests

James Carr writes:

Unit Tests are NOT “tests” in the classical sense… they instead should be used to drive your design, to help you think about how the system you are writing should work, to illustrate functionality.

I disagree with the all caps “NOT”. I think unit tests are primarily for testing, and are particularly valuable for regression testing. I do find that writing tests as I write code influences and usually improves design, but they certainly are “tests”. The fact that tests can drive your design and illustrate functionality are often nice side effects, but they are not the primary reason I write tests.

He goes on to write:

If you ever find yourself running a code coverage tool after writing fresh code, step back and realize that you’re doing it wrong.. my suggestion is if you run a code coverage tool and find parts of your freshly written code aren’t covered, delete that code and try again.

Deleting and rewriting code is a bit too extreme for my taste, but I often do something similar. When fleshing out new work, I’ll often write new classes and interfaces, bounce ideas off coworkers, and rename / refactor heavily. Once I feel like I’ve found the right approach, I will sometimes comment out blocks of code, write a quick unit test (that fails), and then replace the code.

Roy T. Fielding on REST-*

Roy Fielding offers his opinion on the REST-* effort:

Quite frankly, this is the single dumbest attempt at one-sided “standardization” of anti-REST architecture that I have ever seen. It even manages to one-up the previous all-time-idiocy of IBM when they renamed their CORBA toolkit “Web Services” in a deliberate attempt to confuse customers into thinking they had something to do with the Web.

Ouch.

Ten Signs You Might be in Trouble

  1. You still use JDK 1.4
  2. When your build master goes on vacation, nobody is allowed to commit or compile (because nobody else knows how)
  3. Compiling on a developer PC requires a Word doc full of instructions filled with manual steps
  4. Your PC is the exact same configuration as the receptionist’s PC
  5. Incompetent programmers get demoted to “QA”
  6. Your code is locked in to a particular IDE and is unbuildable with any other IDE
  7. You have hundreds of TODO comments littered throughout the code
  8. So many tests always fail that nobody pays attention or even bothers to run them any more
  9. The compile + deploy + run cycle takes over an hour for each trivial change
  10. People laugh at you when you suggest GWT might be better than hand-coded Servlets and JSPs

Code Reviews

Mario and Mike posted their thoughts on code reviews, so I figured we should turn this into a full blown meme.

Have the Review

This is the most important step — far too much code sneaks through without any sort of review. If you know a code review is coming, I guarantee you will spend more time cleaning up your code.

Don’t be too Formal

One of the first projects I worked on many years ago had a formal code review process. We had specific forms to fill out, and huge lists of categories for things like “type of issue”. There were far too many choices, so nobody ever knew what to pick. In the end, having too many choices led to useless data. Plus, we all dreaded code reviews.

See it Run

I always ask the programmer to show the feature in action before we see the code, so we all understand what we are reviewing.

Break It

I try really hard to find ways to make the code fail. I’d rather find errors now than after deployment.

Avoid Duplication / Learn from Others

Without reviews, programmers work in relative isolation from each other. As a result:

  • They don’t learn from their peers, because they may not be aware of other approaches to similar problems in the code base
  • Code is duplicated, for the same reason

Having routine reviews is the best way I know of to ensure programmers really see and learn from each other’s code, and avoid writing the same thing over and over again.

Simplify

If I can think of ways to simplify code, I’ll offer those suggestions in a code review. Try to imagine looking at this code a year from now without the original programmer present. Like it or not, each line of today’s code will become tomorrow’s legacy code.

Fixing a Broken Atom Feed

File this under “mistakes and bugs” — my Twittch.com Atom feed was invalid. For each feed entry, I generate a unique ID roughly following these guidelines. I did not, however, include the date in the Tag URI, making my feed invalid.

With only five comics published, I decided to make the feed 100% correct rather than leave it alone, which means changing the unique IDs for each entry. This will confuse newsreaders, as shown here in Google Reader:

Now each feed entry ID looks like this:

tag:twittch.com,2009-04-18:5

The date portion indicates when the tag: URI was “minted”, so it will always be 2009-04-18. Sorry for any confusion this causes in your newsreader.

Ban Software Patents

Remember in 2006 when patent troll Firestar sued Red Hat for patent 6,101,502?

These patents are bullshit.

On one side, you have an object model. On the other, you have a relational database. When programmers must bridge two different data models, we eventually write little code generators to help us automate the conversion and avoid mundane boilerplate code. In this case, the conversion is called ORM, or Object-Relational-Mapping. The concept is obvious, and is the kind of things programmers do all the time.

Unfortunately, people can patent these obvious ideas and sue each other, punishing companies and individuals who have the audacity to create successful products.

Now, another troll is suing Red Hat for patent 6,163,776. Guess what this patent is for? Yep, just like the last one, this is another ORM patent.

As far as I can tell, both of these patents cover the exact same technology. If the concept of ORM was unique — and it is not — there still shouldn’t be two patents for the exact same thing.

Dropbox, Live Mesh, Git

Back in December I blogged about Live Mesh. I was initially confused by the Vista installation experience, but Live Mesh worked OK on Leopard. After receiving some helpful comments from some Microsoft employees, I decided to give Live Mesh another shot.

Ever since then, I’ve used Live Mesh on two computers: my MacBook Pro at home and my Vista machine at work. My needs are pretty simple. I have a folder on each computer where I keep some e-books, plain text files with TODO lists and comic ideas, and various other important documents. Up until today, Live Mesh has kept these directories perfectly in sync. Just drop a file in, and a few moments later it shows up on the other computer.

Last night, however, I pushed it too far. I created a Git repository in my Live Mesh folder here on my Mac. When I arrived at work this morning, Live Mesh complained about a huge number of so-called “conflicts”. The conflict resolution was utterly confusing and I screwed it up completely. Every time I finished, it reported new conflicts. This was a disaster, everything was hosed.

So this evening, I disabled Live Mesh, went into Time Machine, and restored the files. This is the first time I’ve used Time Machine for a real recovery, and it worked flawlessly. Everything is back to normal.

Live Mesh Fail

Why would Live Mesh report conflicts? I can understand if these computers were sitting side-by-side and I was rapidly adding, removing, and renaming files. But this was not the case. Both computers were in sync, and I was updating on one computer only. This should have been a unidirectional sync without any conflicts. I guess this is what they mean by “beta”.

Live Mesh exists for one purpose: to share data between computers. Corrupting data is unthinkable. When conflicts do arise, the resolution procedure needs to be easy, and it is not.

Dropbox

So this evening I installed Dropbox, and I will use this instead of Live Mesh. The installation was effortless, even easier than the Live Mesh Leopard installer. Copying my documents and e-books went as expected, all simple drag-and-drop operations.

Next up, Git.

Git on Dropbox

Rather than creating a repository and working copy in the Dropbox directory, this time I wanted to create a Git bare repository in Dropbox. Based on this excellent article, I was able to accomplish this in a matter of minutes. Here are the steps:

  1. I already had a Git repository in ~/Documents/livemesh/myproject. Before doing anything, I ensured everything was committed.
  2. cd ~/Dropbox
  3. git clone --bare ~/Documents/livemesh/myproject myproject(this created a bare repository in ~/Dropbox/myproject)
  4. cd ~/dev
  5. git clone ~/Dropbox/myproject myproject(this made my Git working copy in ~/dev/myproject)

Now I can do my day-to-day work in ~/dev/myproject. After committing any new edits, I can type git push to send my changes to Dropbox. On the other computer, I can receive changes by typing git pull.

So far Git has been far easier than I imagined, therefore I am kicking myself for not learning it sooner. Since I’m rambling, I’ll point you to git-osx-installer, which makes Git installation trivial on OSX.

Graphics Help!

I need to apply some sort of transformation matrix to convert a rectangle as shown here:

The web is full of examples that show rotation, translation, and scaling. But I’m not sure how to do the above transformation, or even what it is called.

Can someone help me figure this out? Maybe just point me to a web page that shows some example equations along with a few pictures. The Wikipedia Transformation Matrix article shows a lot of the math, but without pictures, I’m not sure which of the equations are applicable.

To Slide…or Not To Slide?

Each month, the folks I work with have a Java Lunch. A volunteer gives a 1-hour tech talk on something Java-related, but we’ve also had talks on ANTLR, Ruby, Groovy, and many other technologies. These lunches are fun, informative, and a good way to get free pizza.

I signed myself up to present in November — I plan to show some advanced Swing concepts. There are many reasons to give a presentation:

  • Giving a presentation to your peers is one of the best ways to learn something.
  • A speaking engagement provides a hard deadline, forcing you to get something done.
  • Presentations can be a good way to spread some knowledge.
  • Public speaking is a great career move.

But I already know Swing really well…and I don’t really need a deadline for this. Here is my real motivation:

  • I want to improve my presentation skills.

I want to push the envelope a bit and expand my repertoire beyond PowerPoint with bullet points. I want to learn how to give dynamic presentations that make people say “damn, that kicked ass!” (yep, I stole that from Kathy Sierra). I want them to feel this way because they learned something within the 1 hour time constraint.

Mistakes to Avoid

I think I am a good speaker, but I certainly can improve. Here are some mistakes I (have made and) plan to avoid:

  • Do not include an introduction slide. This wastes precious time because people in this audience already know who I am and what the topic will be.
  • Do not include an “outline” slide. With only 60 minutes, why waste 5 minutes describing what I am about to talk about? I’d rather use my time talking about Swing.
  • Absolutely do not include a “History of Swing” slide. Technology history lessons put people to sleep.
  • Don’t make everything “beginner level”. Far too many technical presentations cater to rookies and are boring. This is particularly true when the audience is a group of consultants who know Java inside and out.

Things That I Would Like to Do

  • Show working code snippets throughout the presentation.
  • Show real working Swing examples.
  • Keep the pace up. We only have an hour.

The goal of a 1-hour presentation is not to teach people details. It is to spark people’s imagination, show them what is possible, and to give people a kick in the pants (or perhaps point them in the right direction) if they are interested in pursuing the technology further.

No Slides?

One idea is to skip the slide show completely. Instead of slides, I could show a series of small Swing examples: real, running programs. After showing each example, I can switch over to an IDE, pointing out the most important code snippets. Small fonts can be an issue, but IDEA makes it easy to zoom in.

Other OCI employees have given presentations in this style and it works very well.

Bullet Points

Most presentations fall into this category, and I refuse to do it this way any more. I will not have a series of slides with bullet points.

Lots of Slides

This is an option I never considered until seeing Archaeopteryx: A Ruby MIDI Generator, via Alex’s blog.

That presentation does show some working code along with a real demo. But the bulk of the presentation consists of hundreds of slides. Giles burns through the slides at a frenetic rate, and the results are phenomenal. I have never seen or given a presentation remotely like this.

What Should I Do?

I feel like I should take one of two avenues. Either go all demo+code, or go the “super fast paced slide show” approach. I must admit, the super fast slide show approach appeals to me for these reasons:

  • It is completely different than what people are used to
  • If done well, it can be extremely entertaining
  • It’s a big challenge
  • It may avoid awkward context switching as I constantly switch back and forth between code examples and demos

That last bullet is important to me. A lot of speakers spend too much of their hour stumbling back and forth between demos, the command prompt, and their IDE. Perhaps if I put everything into a fast-paced, well scripted Keynote presentation, I can avoid these context switches.

What do you think? I just placed an order for slide:ology, perhaps that will inspire me.