Woozle Wuzzle
My Epitaph

So as to not be behind the curve, I had recently picked my epitaph:

Here lies Rob. It's tough to blame him now that he is dead.

I attribute the inspiration to the Reuters story Tractor Driver Dies Under Load of Manure. (And yes, the title is fitting for me too. *grin*)

Negative Testing

I have been bit more than once when developing an application where all of my tests ran green yet the application still failed. This situation is inherent in basic Code Unit Test First methodology when you gloss over the details. I have met many developers that will recite "Write a unit test for the desired new capability. Write the code for the functionality. Run the test and if it succeeds then you're done." but will miss the very important "run the test first before the functionality code is written and make sure that it fails". (Never Writea Line Of Code Withouta Failing Test)

But ensuring that the test fails without the desired functionality does not ensure that the test will fail when the desired functionality is broken in some other manner. Let's look at an example:

When a particular piece of functionality is missing an exception is thrown. A unit test is written to explicitly check for this thrown exception and fail when it is found. When the new functionality is added the exception is not thrown and the test succeeds.

Is this particular unit test meaningful or useful? If a common failure mode is known to be that the functionality is not present (say, that the functionality is loaded dynamically at runtime) then the test may be deemed useful. If the functionality's presence can be determined by other means such as compilation errors, then the test is not particularly useful.

What is important to note in this case is that other failure modes of the functionality must be exploited. Enter negative testing. Negative testing (based on the methodology that you follow) is "showing an error when not supposed to and not showing an error when supposed to" or "showing that software will fail and that the failure is handled in a specified manner". Rather than having a lengthly posting about negative testing, the paper entitled A Positive View of Negative Testing is a great read. Understanding the subtleties of positive and negative testing is important to ensure that your unit tests are providing the sturdy safety net that you're relying on.

Regression Tests

How many times have we heard:

Unit tests provide a sort of safety net which "[allows] you to refactor at any time without fear of breaking existing code, so you can constantly improve the design of your program"

But those of you that are familiar with testing know that this is nothing but a regression test:

A regression test is "a testing technique consisting of the repetition of a test after the work product under test has been iterated. Regression testing is used to identify any defects were inadvertently introduced (i.e., to determine if the work product has regressed) since the previous test."

I cannot honestly say that I have ever heard "safety net" tests called regression tests. Why is this? Are the more aglie methodologies trying to separate themselves from the more heavy-weight methodologies by using a different nomenclature? Are there people out there believing that they've discovered something new?

Send your thoughts!

Managing expectations

It is common for the relationship between development and management to be tenuous. Both are like good fighters circling each other, testing for weaknesses. The moment that a weakness is found: whammo! And it's usually the developers that are down for the count.

As a developer the way that I typically win the fight with management is by effectively managing their expectations. When a project starts out, I set very clear expectations on an initial deliverable. This is not what most would consider to be a milestone. This is something typically much smaller. It is this piece of documentation or it is showing them that few buttons and fields working on a web page. Now here's the important part: I meet that expectation. After the first expectation is met, another is set, and, guess what?, I meet that expectation too. This goes on again and again and again. Within a few weeks management has become more amicable when it comes to negoitating terms.

(What's ironic, for me at lesat, is this is what I believe that XP is trying to promote with its tight involvement with the clients and its short development cycles. Unforunately for me, I had to develop this methodology on my own over the years.)

For those that may have missed it, let me emphasize again what is going on. By setting expectations and by consistenty meeting those expectations, the tenuous relationship between management and development becomes more amicable. Effectively, development builds and earns managements trust. Only through this earned trust can development begins to dictate its own terms. (I call this "Managing the Managers".)

A quick illustration: when developers and management first meet, there is no trust between them. Management tends to be the dominant force since it tends percieves development to be "working for" management. As a developer how can I say "well, we think that your time estimates are off by a factor of 'n'" without any proven trust or track recond? You must also factor in the fact that the management team may have been bitten in the past by developers so there's already an uphill battle. (Yes, it may be that management has been bitten as a result of their own mis- or over-management.) Only after consistently and continually setting and meeting expectations and by establishing a degree of trust is it much more palatable to go to management and say "We believe that the timelines you have established are invalid. This new timeline is what we believe is more realistic. We can back up this estimate with the fact that we have defined timelines in the past and have consistently met them."

You may have also noticed by now that this stream of small deliverables shows management clear progress. There's no confusion as to the state of the project. This does wonders for reducing management's anxieties.

A few tricks that I use to gain trust faster (I hope that there are no managers around and I hope that people will understand my intentions and not misconstrue them):

  • It is possible to placate management by delivering some of their "dream" ideas early in the project. If you have a manager that likes purple hippos, then put some purple hippos on the web page. If you have some manager that really wants something that you know is dumb, just add it. (Remember: we're talking about small deliverables. We're not talking about adding that new e-commerce functionality that they've wanted!) This will go a long way to gaining their favor. Loosen up the relationship early if you can and as necessary.
  • Work a little harder on the first deliverables and pad the time a bit more so that on just a few of them you deliver early. It's just a cheap and dirty way to quickly provide the perception that the development team is trustworthy. This will certainly help with a very icy relationship.
  • I hesitate to mention this trick because I know it will be misconstrued by some, but a few of these deliverables can be orthogonal to the actual development efforts if there is a tactical situation that can be exploited. If there is a particularly icy relationship that needs to be warmed up quickly and if there is an opportunity to make a quick win then weigh the risks and try it as necessary. I'll leave it at that.

I now need to stress that this does add quite a bit of management overhead on the part of the development team. Accurately defining small deliverables and ensuring that these deliverables are met while ensuring that the deliverables are in line with the goal of finishing the project can be quite taxing on the development lead. It can consume quite a lot of their time.

I also need to stress that it's very easy to "fall from glory" in the early phases of a project by missing a single expectation. One item that I cannot emphasize enough to teams is clear and early communication about a missed deliverable. Telling management that you're going to miss a deliverable that is expected either the same day or the day before does nothing to paint you in a good light. It simply shows them what they already believe: that you have no ability to effectively plan and anticipate problems. If you know that you're going to miss a deliverable then tell them! Just don't say: "Hey Bob! We're going to miss the deliverable" and leave it at that. Say: "Hey Bob! We're going to miss the deliverable for these reasons, here's when we're going to deliver on the deliverable [or, alternatively, here's the items that we're going to deliver], and here's what we're going to do next time to not miss the deliverable."

Finally, you must continue to manage the relationship even after it has become amicable. I have seen a few projects where the developers have achieved a decent relationship by following what I've outlined here and then they stopped setting and meeting expectations. The relationship can quickly return to its original state. Management is very much about "what have you done for me today". If there's no "today" to frame some request then you quickly fall out of favor.

Persistence frameworks

(Please note: "Persistence tools / frameworks" used throughout this entry refers to Hibernate, JDO, iBATIS, SDO, etc. I'm not considering JDBC to be a persistence tool for this entry.)

The risk associated with the persistence tools is very high given the state of flux that the industry is in (especially with EJB 3.0 coming out in the "near" future). Remember that choosing a technology isn't just based on the cost to implement it today. It is based on the total cost which also includes all of the facets of maintenance and change.

If I had a project that had a persistence component and I knew that I was going to be actively developing and maintaining it for at least 2 years, I would likely use JDBC. Let's look at some of the factors involved in my decision:

  • The persistence frameworks are all going to change significantly over the next two years especially with EJB 3.0 coming out. The same goes for the various query languages that they expose.
  • New persistence technologies may come out that replace the incumbents redering them effectively dead. (I'm concerned less about this with Hibernate than I am with, say, JDO. But that's just a gut feeling based on the number of people using it, exposure, etc.) If IBM does what I think it will do with SDO, for example, then the space will change dramatically.
  • The learning curve with most of these persistence tools is very high. Some may poo-poo this, but if you do anything beyond "just the basics" then you're investing a LOT of time learning, debugging, and posting on forums. *grin*
  • The maintenance efforts and risks for the persistence tools are not well understood. Given that the tools themselves are still in flux, the techniques and skills needed to maintain the tools and associated code are also changing.
  • JDBC, for the most part will remain unchanged. It is a known quantity with known risks and the maintenance efforts and associated risks are well understood.
  • There is no "specialized training" associated with JDBC. I don't have the "hit by a bus" problem with JDBC that I have with the other persistence tools.

My job as a development manager is to produce software with the lowest total cost and the lowest risk. To me, JDBC is still the clear winner for the cases that I stated earlier.

I should point out that if you're prototyping an application, working on certain types of one-off application, or working on a application with a severely limited lifetime then the RAD aspects of the persistence tools may work to your benefit.

If you disagree, let's hear it!

Bets

When in a competitive business environment under the strains of the triple constraint (time, resources (cost) and scope), you have to minimize the risk and minimize the TCO (total cost of ownership) while maximizing the ROI (return on investment). But how do you determine the risk?

I commonly use a "bets" model for helping developers work with and understand risk. I ask: "What bets are you making to use this technology and what bets does the company make when using this technology?" It's common that developers will not be able to list the large bets. That's OK. If you're not familiar and accustomed to thinking in these terms then you can't be expected to do it well.

Let's try an example exercise using a fictional product called WonderWidgets. What are some of the bets that you're making if you use WonderWidgets in your project? (This list is by no means exhaustive. If you think of a bet that I'm missing, let me know.)

  • Does WonderWidgets meet the needs (requirements) for your project? If your needs are not well known then this bet may become very large. Is there sufficient documentation (traditional docs, blog entries, forums, etc) for you to know if WonderWidgets meets your needs? All of this needs to be added up and a bet made.

    You can certainly divide this one big bet up into its constitutients if you feel more comfortable.

  • Is there anyone on the project (or at the company) that's familiar with WonderWidgets? If not, big bet. This ropes in the "hit by a bus principle", the time to learn, the total learning curve, etc.

  • Following along the same lines as the previous point: the company would be making a big bet by using a technology at the core of its application that is likely to be understood by only a single developer (i.e. the "bit by a bus principle").

  • Are there working examples available (anywhere) that outline most of what you're trying to do with WonderWidgets? If not, big bet. This touches on some of the same points as the previous bets: how do you know if WonderWidgets can do what you need it to do? Having examples will help mitigate learning time and determining applicability.

    Notice that I didn't just say "are there examples of code using WonderWidgets". There are two common siutations that you have to be aware of:

    • Are there examples that run under the current version of WonderWidgets?
    • Are there examples that address your particular project's needs?

  • Do you understand the impact that WonderWidgets will make on the rest of the software / architecture / team? If not, you're making a bet. This component has a lot of factors that come into play such as understanding how invasive WonderWidgets will be on the rest of the software.

  • Take a look at the time between releases and the number of defects per release of WonderWidgets. If the time's too short then things are changing too fast to possibly keep up. If the time's too long then you may have a defect that wont be fixed for a long time. Same goes for defect rates. Bet accordingly.

  • How active is the community around WonderWidgets? If there's a large active community with lots of people that can and do answer questions then this may help mitigate one of the previous bets. If not, you've got a bet.

  • It's possible for open source software to just dissolve. You're always making a bit of a bet with these projects. (Yes, the same can be said for commercial software. And yes, there are ways to determine how big of a bet this is based on the size of the open source communitiy surrounding the project (ditto with commercial software)).

    For example, I was on a project where a bet was made on jStateMachine. The license changed and the developers got scooped up and are working elsewhere (or whatever actually happened). At the end of the day the team was stuck with a dead piece of software that was critical to the architecture. Luckily there were mitigating factors for this bet (i.e. an alternative).

I should point out that by no means is the list of bets static. It can and will change with time. You may add bets as they come up, remove some if they are proven false, and change the "size" of them (e.g. if the lead developer on an open source project that you're using was hired by a company that consumed most of their time, your bet for using the project just got bigger). Just keep a record of these bets. (No, this doesn't need to be some huge document that you need dedicated resources to maintain. It may be as simple as a "notepad" file that you keep on your desktop if in a small company / project.)

Looking at the bets, you should choose WonderWidgets based on your ability to find enough mitigating factors to make those bets tolerable. What's tolerable? It depends on the situation and the people involed. If you have a highly agile team (not necessarily in the XP sense of the word) then it may be able to adapt to a lost bet effectively in which case you can absorb and replace the loss more easily.

Just remember that you don't want to have too many components with large bets on them (mitigated or not). It may be fine to have a single large bet component if you have no other unmitigated bets. If you have a large number of components with bets (mitigated or not) ... look out! There may not be time for you to absorb losses from a number of lost bets. For example: You choose to use both jStateMachine and WonderWidgets. You mitigated each by having an alternative and by architecting the app such that you could "easily" place in the alternative. Both jStateMachine and WonderWidgets disappear (or have large bugs that are deemed "not important" or whatever). There's time and resources available to replace one but not the other. Now what? You made intolerable bets.

In order to keep teams happy and to keep up "innovation", I typically allow one large bet (with suitable mitigating factors) per project. This is tolerable for an average team.

Creative Commons License Unless otherwise expressly stated, all original material of whatever nature created by Rob Grzywinski and included in this weblog and any related pages, including the weblog's archives, is licensed under a Creative Commons License.