Commenting, Testing, and Instrumenting Code
Let me start by saying it is a matter of pride with me to write as few lines of code as possible to solve a problem. Less is more. Unfortunately due to some whacky hyper-organizational need lines of comments count as lines of code. (I know not really.) And, some weird wiring in my brain thinks comments are unsightly; I just think comments look ugly. For that reason I try to write tight, refactored code, with very few lines per function and well-named functions. No abbreviations, no weird prefixes, just whole, plain, simple nouns and verbs. Herein lies the rub: this is wrong thinking. Not only is it wrong thinking to avoid comments "because the code is self-documenting" which in part is plausible, but it is wrong thinking to "forget" to complete unit tests, and it is wrong thinking to instrument code. Here are my ramblings on the subject.
Every single thing that has to be encapsulated in code has to be expressed. In the physical world we take so much for granted but try cataloguing your surroundings in a single room, your office, or cube. Ambient lighting, heat, size, shape, color, materials, smell, furniture, appliances, and devices. Then, try to catalogue all of the interactions that may occur: your phone rings, you receive an email, the TV channel needs changing. On and on and on. The more complete you need to make the catalogue the more complicated the catalogue-state and behaviors-will be. In software we have to do this every day. If something's state and behaviors have to be expressed then we have to write code. The only thing we can take for granted is existing code we might use. Here is the problem: expressing classes, state, and behavior is done from the inner workings of one's mind and each of our minds is an individual (frightening) place. How someone else thinks is likely to be confusing to everyone else. The other reality is that someone else, somewhere, eventually is going to end up owning your code, and your brain droppings are going to seem screwy. I know, the truth hurts. The best code in the world written by you is going to seem like schlock to everyone else. The only partial palliative is whole sentences, paragraphs, comments that explain in plain language what everything is doing. And, spell check the comments too. (Why doesn't Visual Studio have a spell checker?) If you aren't commenting-and you aren't requiring your programmers to comment-then you are leaving a mess for someone else later.
Since NUnit (or JUnit) showed up there is no acceptable reason for not writing unit tests. Your code is going to change. Your requirements are going to change. Your bugs are going to need to be fixed. Without unit testing you are in effect saying that either a) we will manually inspect all code to make sure a change over here hasn't broken something over there, or b) we aren't really testing everything because we don't care that much. The first position is inefficient, unrealistic and unacceptable. Posture a is fallacious. Posture b is unacceptable, or "not caring" should be unacceptable. If it is okay to accept an unrealistic lie that everything will be manually inspected or that no one really cares then you shouldn't care when the project fails. It will.
Many projects have a QA period, but manual Q&A while nice is inefficient, seldom properly comprehensive, and should never be done as the only means of accepting an application. Automated unit tests should be required. Let's call our programmer Ted. Ted makes a change. Ted runs all of the unit tests in your suite. If a test fails then Ted broke something and Ted should be expected to figure out why his change broke everything else. Without unit tests all Ted knows is that maybe his code works and maybe the code compiles. Testing to make sure everything still works after a change is regression testing. Code should actually have inspections, walkthroughs, Q&A, and regressions testing and as much of it as possible should be automated.
"In the context of computer programming, instrumentation refers to an ability to monitor or measure the level of a product's performance, to diagnose errors and writing trace information." Instrumenting code can be accomplished by adding copious trace statements, using timing measurements, perhaps configuring a command line -trace or -debug switch to help diagnose and track what is going on internally. If you are lucky your code will get deployed and used in the real world. Eventually users will break it ways that you didn't expect or imagine. This is going to happen (assuming your get to deployment). It may be impractical or impossible to pull the application back into the shop and crack it open. An ability to depend on the existence of your instrumentation code post deployment is going to be hypercritical.
What do I think of code that isn't commented, unit tested, or instrumented? Not very much. What do I think of a project's chances for success if the discipline to incorporate these elements of development into a project aren't present? Not very good. Four of five projects are over budget, not feature complete, buggy, and lucky if they ever see the light of day, and most projects that are done on fixed bids are money losers. The absence of project discipline is an unacceptable factor in poor software quality, and the remedy is like a ripe piece of low hanging fruit.Commenting, unit tetsing, and instrumenting code is the low hanging fruit of project discipline. Don't leave honme without it.