|
|
|
||
|
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*) |
|
||
|
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. |
|
||
|
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! |
|
||
|
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):
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. |
|
||
|
(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:
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! |
|
||
|
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.)
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. |
|
|
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. |