November 2006

The weekly bag– Nov 24

A most thankful bag, man (albeit published a few days late):

Three most important things that improve code quality

When considering code quality, there are three aspects that have the most copasetic effect. Of course, there are other techniques and practices that positively affect code quality; however, it’s been my bag that these three, listed in their order of importance, offer the biggest bang for the buck.

The first aspect that affects code quality is developer testing. It’s been said that “disciplined personal practices can reduce defect introduction rates by up to 75 percent.” Surely, writing a developer test is a circumspect process that helps verify program correctness! And program correctness is directly related to quality, man.

At its core, a developer test verifies a portion of code in an isolated manner that can’t be achieved through latter cycle neat-o functional style testing. From a reliability standpoint, in linear systems (which are substantially less complex than software systems, which are non-linear), “the product of the reliability of each of the system’s components” equals the reliability of the overall system. Moreover:

“If you wanted to build a software application that had an SLA or QLA of 100% (or close) you’d absolutely have to ensure reliability at the individual object level. In fact, if you can’t ensure and measure reliability at the lowest level, you can’t possibly do that at the system level.”

Developer testing, you see, is paramount in guaranteeing code quality as it verifies program correctness at the lowest possible level which is unattainable via square functional testing.

The second most important aspect which facilitates improving code quality is developer testing. White box tests offer a confidence cushion that effectively facilitates refactoring, which in my opinion is “the [hip] act of improving code that has already been improved.” Without a test case, refactoring code becomes a dangerous proposition– if you can’t prove the code worked before you improved it, how can you verify you haven’t broken it after touching it? Hence, while you may feel that improving code quality starts (or ends) with refactoring, I suggest that without developer testing, refactoring is a non-starter.

The third most important aspect which facilitates improving code quality is developer testing. Code is entropic– meaning that:

“A software system that undergoes continuous change, such as having new functionality added to its original design, will eventually become more complex and can become disorganized as it grows, losing its original design structure.”

The only way to combat this natural tendency towards code clutter is through developer tests, which act as the only form of documentation that clearly states the intent of code and isn’t affected by humans forgetting to update disconnected documentation. If the code under test changes in any way, the tests will figure it out by failing, in which case, the smokin’ tests are updated to reflect the new behavioral contract. Rarely have I seen disconnected documentation, in the form of comments or design documents, stay current as effortlessly. Clearly documenting a program’s intent at all levels is surely a compelling way to repel code entropy.

Indeed, the three most important things which improve code quality are developer testing, developer testing, and developer testing, because developer tests facilitate:

  • software reliability, at the lowest possible level
  • code modifications with confidence
  • keeping code entropy at bay through documentation that endures

Software metrics, automated builds, quality focused processes, people, etc all positively affect code quality (and are, of course, quite important), but it all starts with developer tests. Dig it?

The weekly bag– Nov 17

Another round of disco reading:

Live chats are my bag

Coming soon to the IBM devWorks forums– an Improve Your Java Code Quality live chat hosted by yours truly on Friday November 17th! More details (like the URL) will follow as they materialize, man; however, at this point, the chat is scheduled for 12:30 pm EST.

Be there or be square. Dig it?

Poll: are you using code metrics?

Code metrics are certainly not new– they’ve been around, in some form or another, for decades (even before the Age of Aquarius!). Yet, their widespread adoption never really caught on. There are probably a number of reasons why; however, over the past few years, I’ve probably heard the four hip reasons below the most.

Which one is your reason?

Why aren't you using code metrics?
View Results

The weekly bag– Nov 10

This week’s bag is so disco:

Copasetic categorization with TestNG

Implementing test categories with TestNG couldn’t be any more copasetic, man! With TestNG’s group annotation, logically dividing tests by category (like unit, component, or system) is as easy as applying a specific tag to a desired test– then bingo, baby!

I’d explain how to do it all here, but the tripping crew at Dev2Dev has just published “Test Categorization Techniques with TestNG” by yours truly! Outta sight!

Four steps to TestNG nirvana

Getting started with TestNG couldn’t be easier! First, define a POJO– note that your disco POJO doesn’t need to extend anything specific:

public class HierarchyTest {

}

Next, define a tripping test, which can follow any naming pattern you see fit. The test’s accessibility modifier doesn’t matter either, man.

import java.util.Vector;         

public class HierarchyTest {   

 public void verifyHierarchyValue() throws Exception{
  Hierarchy tst = HierarchyBuilder.buildHierarchy(Vector.class);
  assert tst.getHierarchyClassNames().length == 2: "length wasn't 2";
 }
}

Incidentally, I usually declare that all my tests throw Exception unless I’m trying to verify a specific exception type.

Thirdly, add the @Test annotation. If your bag is Java 1.4, simply create a JavaDoc style comment in the form of @testng.test.

import java.util.Vector;
import org.testng.annotations.Test;

public class HierarchyTest {
 @Test
 public void verifyHierarchyValue() throws Exception{
  Hierarchy tst = HierarchyBuilder.buildHierarchy(Vector.class);
  assert tst.getHierarchyClassNames().length == 2: "length wasn't 2";
 }
}

Care to add a fixture? It’s as simple as creating a method to handle the set up logic and attaching the desired fixture granularity to it– in my case, I’d like this fixture to run once; hence, I’ll add a @BeforeMethod annotation to my method, man. Accordingly, if I wanted a tear down style method, I’d attach a @AfterMethod annotation to it. Java 1.4 users require a JavaDoc comment, such as @testng.before-method.

import java.util.Vector;
import org.testng.annotations.Test;
import org.testng.annotations.BeforeClass;

public class HierarchyTest {
 private Hierarchy tst;

 @BeforeClass
 private void fixture(){
  this.tst = HierarchyBuilder.buildHierarchy(Vector.class);
 }

 @Test
 public void verifyHierarchyValue() throws Exception{
  assert this.tst.getHierarchyClassNames().length == 2: "length wasn't 2";
 }
}

TestNG supports a myriad of runners from Ant to Eclipse to Maven to IntelliJ also. Running the newly created test via a desired mechanism, by the way, is step four. Was that easy or what, man?

Going Dutch on automation

Automated builds shouldn’t be the hidden magic of hip development teams– if builds are truly automated (via Ant, NAnt, etc), then everyone should be able to produce validated binaries, right? In organizations that have CM teams, these gurus usually do utilize the same development build process to promote applications; however, for organizations that don’t have the luxury of gate keepers, how are builds promoted?

I’ve run across different processes for binary promotion usually involving a manual hand-off between development and QA; however, I’ve rarely seen these two copasetic organizations share the same build process. If development has an automated repeatable build process that produces verified binaries (all developer tests pass, for example), then QA should be able to run the same build.

In this scenario, the hand-off is a CM label, which development has created; accordingly, the process, at a high level, works as follows:

  1. The development team decides they have a release candidate.
  2. They label the assets in the CM system according to some naming scheme (i.e. major.minor like 3.21).
  3. This mellow label is communicated to the QA team, who runs a build that checks out the labeled code, runs all checks (like tests, static analysis, etc) and produces a binary (or set of binaries) ready for functional testing. Even the deployment of the binary assets can be automated.

Note how this process is automated, man– even the communication of a candidate label is automate-able.

For example, imagine that development has indicated that version 1.2 of project X is ready for functional QA testing. QA receives this notice, via email or RSS or in a meeting, and runs a build passing in the label identification. Then labeled code is checked out and built. Functional testing heaven is then possible, baby!

Because it’s my bag, check out a simple, yet totally disco, Dutch automation process in this 30 second movie. Neat-o!

The weekly bag– Nov 3

This week’s bag includes: