Stuart Thompson’s Tech Blog

Web 2.0 & Quality Development

Archive for May, 2007

Effective Meetings and Reality vs Negativity

Posted by stuartthompson on May 29, 2007

In a book that I’ve been reading recently, I came across the following sentence “Each time, I ask what the problem is, and we get to it immediately.  I like to keep a handle on all my [projects], and the problems are to be expected.  The time I worry the most is when there aren’t any problems.  That’s usually the result of misinformation or wishful thinking on someone’s part.” — Donald J. Trump, How to Get Rich, ISBN: 0-345-48103-8

This statement applies very well to software projects and yet the number of meetings I attend where anything but the truth is presented absolutely astonishes me.  Stubborn, blind denial of the actual forces at work and the actual state of the project is peppered throughout one-hour status meetings that accomplish little beyond irrepairably interrupting the momentum of the team.  I hate long meetings.  I also hate unnecessary meetings.  I hate most meetings in general.  There is nothing worse than attending a droning waste of corporate expense and momentum that is filled with long-winded pleasantries and editorials, each of which are masking the intent of the meeting and sapping the attendees energy.  Most meetings could be disposed of if more people took a commitment to the truth and reality of a situation and spent a little time working on their communication skills.

Meetings have their place.  Collaboration is an essential part of successful projects and it is often necessary collect all or some of the members of a team together to discuss important issues and share critical information.  However, most meetings achieve neither of these goals and can often cause a project to be pushed further from success by wasting essential forum time.  There are a few good windows within any project during which certain critical issues can be raised.  Wasting these opportunities will mean that any subsequent attempt to raise the issues will fall on deaf ears.  If you waste a busy executive’s time with waffle and whining, she will be far less likely to grant the team an audience in the future.  This goes not only for high-level decision makers but for every member of a team.  If the team writes off a scheduled meeting as a waste of their time, they are less likely to listen or contribute, merely showing up for their face-time before returning to their cube to continue the day.

This is where the fine line between negativity and reality must be walked.  Whining is equally as unproductive as masking the truth.  Presenting an endless list of unsolvable enigmas just makes the team sound like a poor fit for the project; they have no possibility for success so why bother to continue funding it.  Raising endless spin and sales talk to make the project sound like a flawless success will either raise real suspicion in a seasoned strategic executive or convince a less-aware manager that everything is fine, thus wasting the opportunity to solve real problems.  The most beneficial path for all concerned is to raise the honest issues and problems, undressed, with a clear understanding of what it will take to solve them.  An executive, be it the CFO of a fortune 500 company or a recently promoted tech lead that used to be a peer developer has a job to do just like every other team member.  Their tools differ in that instead of a development suite and available servers they allocate budgets and manage long-term risks.  It has been my experience that raising clearly identified problems with proposed solutions in short and focused meetings can work wonders.  Lay the problem out quickly and concisely at the correct forum and with the appropriate amount of research to answer any pertinent questions.  This to me is the essence of effective reality and it will eliminate the need for the other 56 minutes of a one hour meeting.  An agenda is *not* a good forum for the presentation of problems in detail, nor is it a sounding board for in-meeting sub-agendas and politics.  Simply including a line “Review current problems.” is perfectly legitimate, although many people balk at the inclusion of a problem review in a meeting and would much prefer to word it differently; “project status review” for example.  However, this does not adequately prepare the audience for the purpose of the agenda item and presenting problems with a project at that point might feel like an ambush.  Keep the agenda honest and professional and the meeting will be much shorter and much more effective.

Negativity is a poor contributor to any project.  We’ve all encountered it and I know that I’ve contributed in my time to it.  That doesn’t mean I don’t recognize it and don’t try to move past it and improve away from it.  However, there is a difference between negativity and reality.  I’m often painted on projects as the guy who constantly raises problems and is quite negative.  This bothers me as I generally consider myself to be a fairly positive and cheery person, but it gives me enough cause for thought to think about where the comments are coming from.  What I’ve found is that there is a mixture of genuine negativity at times, usually when I’m worn out on something, and a healthy dose of reality.  The negativity is just wasteful and needs to be removed, however I only ever see positive results from turning up the volume on reality.  Let me also qualify here that there is a difference between identifying and presenting legitimate problems with a project and simply being a whiner.  I’ve worked on projects with whiners and it sucks.  Raising legitimate problems with a project entails with it the requirement to present a proposal for a solution to the problems.  That’s where the power of reality in a project conversation comes from.  Unfortunately, it is easy to mistake one for the other and transpose the disadvantages of a negative attitude onto the genuine advantages of a realistic view of a project.

I keep a journal of all of the meetings I’ve attended in my career, paying specific attention in my notes to those that violate their own potential efficiency.  I started doing this as a way of relieving the torrential boredom of being a participant in such gatherings, but have since kept it up and formalized the practice as it makes for some great material later on in projects when people stop to wonder where all their precious development time was spent.  There are several in which I noted down in the first few minutes of the meeting what the obvious cause of the meeting was before the presenter had even finished their long-winded introductions and pleasantries.  I would write things like “so they’ve just realized that [X] product and [Y] product can’t release together and that will hold up [Z], costing us an additional [A] development hours…finally!”  However, instead of just stating that fact in the opening couple of minutes of the meeting, an entire pomp and circumstance is observed to carefully dance around the outskirts of the truth, weaving tales and excuses around the real reasons for the problem.  By the time the point actually emerges from the sand, most people are clearly convinced that nobody did anything wrong, no mistakes were made, nothing really failed in the process.  The team simply ended in an unfortunate and unforeseeable situation that has caused the project to go over budget.  Everyone walks away having learned nothing and with absolutely no intent to change any part of the process in the future.

Everyone in the room knows that this meeting is 90% fabrication, 8% spin, and about 2% truth.  The fact that no project plan had ever been put together, that no strategic questions had ever really been asked around the integration of the two separate products are excused away in a whirlwind of great sales talk.  There are a few points I’d like to make before continuing.  This is not an actual recount of a meeting that took place, it is a fabricated situation that has been echoed on many projects in many forms over the years.  I’m not picking on any one particular instance here, rather I’m trying to lay the framework for an argument about the power of constructive problem identification.  By the time the meeting has concluded, so much has been said about everything that was done right in the project that no action items are taken away beyond “we have to push the deadline”.  The developers of the project quickly meet to figure out how to hack [X] and [Y] to work together for [Z], scope the work to fit the new deadline and then return to their cubes to work on it.  However, before we leave this case alone, lets travel back a few months to the originations of the project and look at some of the meetings that took place then.

A project was conceived.  A half-baked idea made its way into an executive summary in response to a sales idea that would solve problems with a current product line and ostensibly increase profits for the department.  The half-baked idea was cut and paste into a funding summary, approved, and then cut and paste again into the opening section of a requirements document.  A small development team was formed, the senior developer was named technical lead and people started to write code.  The tech lead knew that this was leading towards failure.  There was no formal project plan, the deadlines aligned with trade shows at which the company wanted to show off the product, and the requirements were little more than a half-baked paragraph from an executive summary.  Weekly meetings were set up with the department heads and the tech lead and a daily meeting was set up between the tech lead and his team of developers.  A build server was created and configured, source control was established into which a framework solution was added.  The tech lead spent a few restless nights thinking “how are we going to integrate with the other team’s product?” (a subtly stated requirement in the executive summary about ‘third-party integration’) and worrying about the fact that no-one had actually tasked the project out to verify the deadlines.  However, this is about the only point that isn’t raised in a meeting, instead the content is focused on the positive progress items and how much code has been written.

In the weekly meetings, a status report was delivered, and action items were created for “discussing third-party integration” and “formalizing a project plan”.  Integration was left to the developers and the creation of a project plan was little more than an exercise in ensuring lots of little tasks conformed in concert to the previously stated deadlines.  The tech lead wrote a few emails formally stating his concerns about the lack of integration planning and the lack of a realistic project plan, which were comfortably summarized by the department heads in more senior level meetings.  Having performed sufficient CYA, the project then continued unabated until it reached the inevitable conversation about slipping deadlines and integration problems.

We’ve all observed situations like this in one capacity or another, either as a developer, tech lead, or a department head.  Despite many opinions to the contrary, no single person is at fault in this situation.  However, this situation could have benefited greatly from a few well placed observations quite early on in the process.  The problem here is that no-one wants to be labelled as a whiner and as a result they will very often hold back the real issues that are burning in their minds and instead state rather pedestrian facts more appropriate for a written status report.  The worst part of this situation is the fact that no-one learns from it.  There are no action items taken away to improve the process in the future.  Nothing is learned from the process and so its failure does not even serve as a warning to others.

Finding the correct opportunity to present observations of problems in a project can be hard.  It is almost as fine an art as putting corporate spin into a meeting to maintain smiling faces.  It might be prudent, however, to put some of the time and effort that was previously aimed at such spin into that art and to find the most effective and professional way to deliver the bad news.  Status reports are ill-chosen locations for such feedback unless it was directly solicited.  A crowded staff meeting is also a poor forum for information that most people in charge might not want to hear.  Next time you’re on a project with little to no requirements, no project plan, or a glaring flaming elephant that no-one wishes to acknowledge, try the following and see how it works.  First approach your project manager, tech lead, or department head, whichever you have the most “accepted” direct-report contact with and hence avoid going over someone’s head.  People in charge really appreciate knowing that their reports will raise problems to them first and give them the chance to save the day versus watching over their shoulder for the next dagger or e-bomb.  Schedule a short meeting with them (no more than five to ten minutes) and be sure to get to the point almost immediately to show that the time they set aside for the meeting is important to you.  Depending upon your relationship with them it may be sensible to preface with “I’d like to raise some observations to you that I have made about our project and get your feedback on them.”  That lets them know your angle and where you’re coming from with this, that its not just a social chat or salary negotiation.  Don’t prepare a ton of handout material or do anything fancy like haul in a portable projector.  A simple “I took a few notes” in your notebook will suffice.  Present the problems cleanly, without window dressing, and with both firm ramifications and potential solutions.  ”I believe that project [X] is not going to integrate cleanly with project [Y] because the interfaces have diverged.  This will hold up our launch and cause us to miss our deadlines.”  Present a copy of the project [X] interface, with which the manager is familiar, then presents the project [Y] interface that you have researched and highlight the problem areas.  ”I haven’t approached the project [Y] team yet, but I think they’ll run into a similar problem unless we collaberate.”  Don’t seek credit or place blame, this isn’t a career moving meeting, this is a way to make your project, and hence your life, much easier.  Try to establish within the team a feeling that they can talk to you about such problems and set a clear example of the format that is most useful, this will encourage the culture of the team to tend towards a more effective working habit.

What if the meetings themselves are the problem?
The issue I have raised the largest number of times throughout my career is that of wasteful meetings interrupting momentum.  Momentum is very important to me in a day and, once interrupted, can take some time to get going again.  If the purpose for the meeting can be fulfilled in another way, by the team’s culture of open honesty and clean, efficient communication then I have found that most managers are willing to replace daily meetings with weekly updates from key team members.  This is all down to a question of your own working taste and how your team works.  I’m not dictating whether morning meetings or daily stand-ups will work, rather that a clean presentation of a problem (even the presentation that a daily meeting is the problem) can often produce unexpected and great results.  I expect people working for me to get to the point quickly and cleanly and take up as little time in a meeting as is necessary.  Sometimes it is essential to gather team members together to resolve a pressing problem, but if the same can be accomplished via e-mail then simply write it up and don’t break my momentum for the day.

Where are we?
I started on the difference between negativity and reality and I want to conclude very quickly that I feel most failed projects have incorrectly tipped the scales in favor of negativity without meaning to; in fact through an ironic intent for good.  Although most teams start without much negativity, a lack of reality and the subsequent problems it brings soon lead to a very negative and defeatist vibe within the team.  As oversights (an odd word in most usage) are both seen clearly and ignored, deadlines become tighter, real issues are hidden from management and then become too large to reveal, and the team is beaten upon to finish a race they can’t win.  The lack of early reality leads to a heavier negativity as the project progresses and hampers any chance for expressing the reality of the situation.  Whereas by taking a firm stance early on to accept that problems will crop up and are nothing to be feared, a more realistic view of the project can be taken right from the start and those problems can be dealt with quite easily and effectively.  Choose your audience carefully, research the problem sufficiently, and present the problem without window dressing.  Establish a reputation for getting to the point and presenting well-researched proposals and you might find that facing the truth bears much richer fruit than hiding it.  As I stated before, I have been guilty of both negativity and failure to effectively communicate on many occasions.  As with everything, I’m trying to analyze the outcome of my decisions and actions, learn from them, and develop a better understanding of how to garner success in the future.  Every person in a team can improve the quality of a project and a commitment to clear and effictive communication of reality seems like a great place to start.

Posted in Meetings | Tagged: | Leave a Comment »

Assertions – No Need for Rocket Ships

Posted by stuartthompson on May 21, 2007

This article speaks briefly about refactoring and code structure, focusing on several stylistic thoughts that have crept up time and time again throughout my career as a software developer.  The art of software development has many facets, however many of the goals that distinguish great software from its counterparts are often ignored, even more often ignored unintentionally.  The quality of a piece of software lies in many more areas than its ability to fulfil a requirement or perform a task.  The development lifespan of most software spans far beyond the initial release, and often beyond the initial developer.  Sooner or later, someone else is not only going to have to read and understand your code, but also extend and enhance it in meaningful ways.  This someone may very well be you, but after several months have passed by it doesn’t really matter whether its a new face or the initial developer.  If the code cannot be understood and meaningfully digested then performing maintenance upon it and extending it usefully will come at a far higher cost than is necessary.  This leads to one of the additional goals of good software: a transparent, intuitive, and consistent structure that can be readily understood by someone other than the initial developer at a later date.

First, let me define in my own way what I interpret the qualities of transparent, intuitive, and consistent structure to mean.  From this you should be able to translate the meanings into your own understandings and gain meaning from the conclusions I draw and the ideas that I’m trying to present.

Transparecy
When I refer to code that is transparent I imply that its structure, style, and solution do not “hide” the thought processes behind that solution from any would-be reader.  Transparent code should go out of its way to present the ideas behind the solution without introducing any “magic” or “voodoo” that occurs behind the scenes.  Sometimes, the nature of a solution involves the use of such magic, often the most graceful solutions “appear” to have virtually no code at all.  However, as the developer of the code you completely understand at the time of writing “why” the solution is working and should, therefore, be able to provide sufficient transparency within that code as to explain its purpose and behaviour.  If a third-party process or disconnected workflow is accomplishing part of a task for your code (for example, the use of an HttpHandler to solve certain parts of a global web application problem) then add clear and concise documentation to the code about how that part of the solution is working.  Don’t leave it hidden behind the curtain.  Expose the fact that some other component is solving part of the problem at hand.  There is no need for brevity in comments and code-documentation.  Large comments do not increase the size of a compiled assembly and they are not included in the delivered solution.  Last time I checked, no-one was too worried about an additional 8K of comment text in a source code file stored in a development environment or source control solution either.  However, documentation is not the only facet of transparency.  The structure of any software solution often has an almost tastable opacity to it.  You can open up a code file in an editor and almost instantly smell and taste whether this code will lend itself towards easy reading (if you’re lucky), or a large heirogliphic decryption exercise (as with most projects).

Intuitive Design and Consistent Structure
These two facets of good software go hand-in-hand together.  Defining something as being intuitive is very difficult.  What is intuitive to one person may be foreign and misleading to another.  I have often presented solutions that I find to be incredibly intuitive and natural only to find that one of my respected peers has developed an equally valid and elegant solution in a completely different direction.  However, this disparity can easily be resolved through consistent structure.  Although the thinking behind a particular solution may be foreign and far from intuitive to me at first, I can learn about the approach and begin to develop an intuition for it as long as the structure of the overal solution is consistent.  In essence, you are training my mind to your way of thinking and with every method it becomes intuitive due to its consistent nature.  The solution itself becomes predictable, despite the lack of early intuition.  Here then, consistency is absolutely key to that training.  Switching tracks often in the solution, ignoring consistency, will interfere with this learning process and the chances are that the solution will never make intuitive sense.

What does this have to do with rocket ships?
Part of where this is leading is to discuss coding style.  I’m not taking about the age-old (and quite futile) discussions of whether curly braces live on the same line as a declaration, or whether variables need to be prefixed with a certain convention of coded letters.  That was covered in the section on intuition and consistency.  (It doesn’t matter how variables are named or where the brace lives as long as the style is consistent; it becomes intuitive quickly).  However, there are aspects of style that do make a big difference to the readability and “maintenance cost” of your code.  It is in this that rocket ships come into play, in my first example of coding clearly.  How many times have you encountered a code block that looks like this?

if (ctl != null) {
if (ctl.Text != String.Empty) {
if (shortName != “”) {
fullName = shortName + ctl.Text;
}
else {
string err = “Short name was empty.”;
log.Error(err);
throw new Exception(err);
}
}
else {
string err = “The control text was empty.”;
log.Warn(err);
}
}
else {
string err = “The control was null.”;
log.Error(err);
throw new Exception(err);
}

It doesn’t take long to figure out what this code is doing.  However, it can take a while longer to figure out what this code is meaning.  I can imply from the first construct that we don’t want to try to access the Text property of the variable ctl if it is null.  That’s a good safety check and it’s fairly clear from the first if statement.  However, it is not so clear what the rules around ctl.Text and shortName being empty actually are.  Is it invalid to change the variable fullName if both ctl.Text and shortName are empty.  That seems to be the case here, but it isn’t very clear and maintenance or bug-fixing on this code might encounter some ambiguity as a result.  Not only that, but we’ve already wasted valuable minutes guessing at the actual intent of the code.  Furthermore, ctl.Text is tested against String.Empty whereas shortName is tested against “”.  Was this intentional?  Can ctl.Text and shortName be null, but not empty?  This is also fairly unclear.  In fact, the only line of code that performs any real work is nestled away in one of the longest barrels of a rocket ship.  It takes a few moments to isolate the fact that the point of this code is to set a variable called fullName to the combination of shortName and ctl.Text.  This is the effect of “hiding” the solution I was discussing in transparency.  What if the code was structured like this instead?

// Assert that the reference to the suffix TextBox control is valid
if (txtSuffix == null) {
string err = “The reference to the suffix TextBox was null.  The value of the control cannot be retrieved and the full name will not be updated as a result.”;
log.Error(err);
throw new Exception(err);
}

// Assert that a suffix has been provided (this is not an error, a short name alone will suffice)
if (Strings.IsNullOrEmpty(txtSuffix.Text)) {
string err = “The suffix TextBox does not contain a value.  This is not an error, but no suffix is available to append to the full name.”;
log.Warn(err);
}

// Assert that a short name has been provided (this is an error, a suffix alone is not allowed)
if (Strings.IsNullOrEmpty(shortName)) {
string err = “A short name was not provided.  A full name cannot consist of a suffix alone, the operation will be aborted.”;
log.Error(err);
throw new Exception(err);
}

// Update the full name
fullName = shortName + txtSuffix.Text;

Here, the rather ambiguous ctl has been renamed to txtSuffix.  Again, the naming convention is immaterial as long as the pattern is consistent throughout the project.  However, it is always useful to name variables in a way that presents a little more data than the misleading ctl.  More importantly, the code has been refactored into a series of assumptions rather than a single nested contortion.  The same logical checks are still being performed, but the rocket-ship-shaped (they always remind me of the side-scrolling video game Defender; like rocket-ships pointing from left to right) gourdian knot of if statements has been disbanded.  By separating out the thoughts into individual blocks of code, the assertions that the developer is trying to make are presented to the reader much more clearly.  It is useful for me to think of writing code in the same manner as writing project documentation or an article for a magazine, trying at all times to make it readable, engaging, clear, and succinct.  A comment can be added to each of the assertions to explain the reason for its presence.  While the nested if statements could have been commented, the refactored structure of the code allows for more meaningful placement of these comments as each assertion cleanly stands alone.  It is no longer unclear in which order the events will occur or what the statechart for this code would look like.  It’s not that such information couldn’t be derived from the nested if statements, but when you charge by the hour for your work, every minute is valuable.  The error information being written to logs or reported in exceptions has been expanded to give a more verbose explanation for the decisions that the code is making.  This not only aids in debugging and system maintenance, but also makes the code itself inherently more readable.

This is but the simplest of examples where a minor restructure effort and a little thought to naming and logging has made a section of code vastly more readable and transparent.  I know from personal experience (as I’m sure you all have come across too) that there are far deeper nested if statements lurking throughout code you will be one day asked to maintain.  Perhaps you wrote it, or perhaps you’re the lucky one that just gets to fix it when it breaks.  Either way, it serves as a great reminder to pay heed to code quality when you are debugging a problem in production on a Friday night at 8pm with little end in sight and you isolate the problem down to a one-thousand line, twelve level-deep nested gourdian knot that just threatened to take away your weekend.  It’s very easy when coding to think that because it’s intuitive right now, that your code will always make instant sense to you.  That almost certainly won’t be the case once several months have passed by and it certainly won’t be the case when someone other than you needs to understand and maintain that code.  After writing a method or structuring a class, take a second to think just how transparent and consistent the code really is.  Does it fit with the convention used in other parts of the project?  Are there any “magic” methods or tricks that make something work that won’t be quite as intuitive in a few weeks time?  Do the log messages (<rhetoric>you do use log messages, right?</rhetoric>) give ample meaning to the actions of the code?  Most importantly, can the code be refactored now that the final solution has been hashed out?  Nearly every method I write can be refactored in some way or another once I’m finished.  I would never deliver a speech without reading, editing, and refactoring several times.  Code shouldn’t be any different.

But…good code documents itself!
Rubbish!  I’ve heard this statement countless times in the context of similar discussions.  I argue instead that familiar code documents itself, and often only for the period of time for which you’re working on it.  I know parts of the Linux kernel that are absolutely outstanding pieces of code.  They have been refactored and architected many times over by some of the smartest developers on the planet.  If you stripped out all of the comments and presented just the raw lines of code, would that really be self-documenting?  Would the deepest parts of the mutex queue management library be instantly clear to all who gazed upon them simply because the code is so amazingly awesome?  Doubtful!  It is true that a consistent and transparent code structure can remove the need for a lot of excess documentation, however it does not mean that helping someone along with a few insightful comments is simply a waste of keystrokes.  In any solution worth charging for, the design and final implementation of each method will have been thought about many times.  There should not be any code that simply exists because it has always been there, and fairly early on in the development life-cycle a good body of code will be developed that remains essentially unchanged throughout the lifetime of the project.  It makes sense that methods with such longevity that have been so carefully crafted and positioned just so within your code are therefore worthy of a few lines of documentation and logging to affirm their presence.  With a combination of forethought, refactoring, consistent day-one logging, and an investment in comments and documentation, there is no reason that transitioning code from one developer to another should incur any unnecessary cost.  Given that most code will be refactored or maintained at some point in its life, I can guarantee that the time investment up front is worth it.  QA and support will adore the additional logging, the customer will appreciate the ability to release patches and updates on schedule, and any future developer suckered with having to work with your code in the future will be thankful that at least one other person out there took the time to make their day a little easier.  The global quality of software increases or decreases with the next method you write.  Make it count.

This one makes the “Stuart Thompson’s Top Ten Peeves” list in code reviews.

Posted in Programming | Tagged: , , | Leave a Comment »

Focusing on Falsifiability

Posted by stuartthompson on May 7, 2007

I recently came across a passage regarding the different ways of establishing belief for hypotheses and found myself thinking about an all too common area of missed opportunity in software quality assurance. It reads:

“All swans are white- until you reach Australia and discover the black swans paddling serenely. For science built on induction, the counterexample is always the ruffian waiting to mug the innocent hypothesis as they pass by, which is why the scientific method now deliberately seeks him out, sending assumptions into the zone of maximum danger. The best experiments deduce an effect from the hypothesis and then isolate it in the very context where it may be disproved. This falsifiability is what makes a hypothesis different from a belief- and science distinct from the other towers of opinion.”

from “Chances are…adventures in probability”, Michael Kaplan & Ellen Kaplan (ISBN-13: 978-0143038344)

This paragraph started me thinking about whether or not the quality assurance and software testing practices I have observed on several recent software projects are being quite as effective as they could be. Software quality, not unlike project documentation, is too often treated as an unnecessary evil within most software projects; a purely expense item whose perceived value and importance noticeably depreciate across the lifetime of the project. Amongst the first items to be cut from the list of software deliverables, some development teams have a hard time getting management to agree to have adequate quality assurance cycles within the project plan at all. Of course once the project has launched and is in production, quality could not be any more at the fore-front of everyone’s mind. This is because it is not until the first time critical data is lost or a production line is halted that the real value of testing and quality assurance is seen. Software is visible and prototypes have buttons that can be clicked and controls that can be manipulated. Testing leaves only a void on the timeline and a hole in the budget; and when was the last time you saw a QA person giving a corporate demo? The problem here is that the value of quality assurance is not tangibly communicated until it is too late for any corrective action to be taken.

I talked to a friend of mine who has been a software quality architect now for several years and despite the lack of value for his role continues to enjoy his work and perform his job with the utmost commitment to excellence. I asked him about the difference in the projects where QA has been valued from the beginning of the project. His answer didn’t form into useful information for me until the last couple of days. My friend felt that if the QA engineers had a clear understanding of the project and its direction from the beginning of every release cycle that they could better create and craft appropriate test plans and be seen as adding value right from the beginning of the project. With a clear understanding of what the software was actually trying to do, his team was able to provide useful feedback to the developers even within the first couple of release cycles. This information was able to help shape the software designs and decisions made by the developers and became itself a tangible deliverable within the project. Such visibility of the contribution they were making became an integral part of the release planning. Instead of simply “filing bugs” from day one (which is little more than an inconvenience to a developer who “knows it isn’t working yet”), they were able to leverage their knowledge of the project’s direction to get away from the typical bug-tracking path and focus more on actually testing.

To paraphrase the contribution outlined above, the QA team had ceased to be a bug-filing machine and had migrated into validating assumptions and testing concepts; providing a tangible output for their work that influenced the course of the project.

Exhaustive testing certainly has its place and I for one am a very large proponent of code-coverage, standards adherence, and testing to a high-level of detail. However, when was the last time that a bug filed in the first release of a mid- to large- size software project had any relevance to the final version of the software that was actually shipped. Certainly there are some simple errors that can be fixed by a developer within certain software sprints, but it has been my experience that subjecting incomplete alpha-builds of software to rigorous testing simply results in proving that indeed the software is not yet ready for release. Rather than taking the typical software reaction of performing QA at the end of the software cycle, I propose the integration of QA at different levels throughout the software development process.

Software testers do just that; they “test” things. However, the role of a software tester has become very divorced from that of a software engineer to the great detriment of many projects. Quality assurance engineers are often left in the dark about project requirements and are often brought in towards the end of a project and asked to “bang away on it” for a while, filing bug reports of their findings. Ultimately, several of the “high-priority” bugs are patched within the software to make it limp less noticeably and the product is pushed into production. This is neither satisfying for the bewildered quality assurance engineer performing the banging, nor for the developer who uses the appearance of such bugs to account for the “problems with late changes in requirements.” There are many tasks that a quality engineer may perform, especially early on in the project, that do not involve blindly banging away on something.

This returns me to the paragraph above and thinking about how classical and quantum science theories are tested. Certainly the minds that attempted to locate flaws or incorrect assumptions in some of Einstein’s theories of quantum mechanics (Einstein himself being one of them) had an intimate knowledge of the system they were trying to break. Further, they focused upon certain key assumptions that were underpinnings to the general overall theory and tried to find flaws there. It is much easier to verify and validate a small assumption than to assault an entire framework in one go. This probably leads the mind towards thoughts of unit testing and test-driven development as a whole, however if I might I’d like to divert for a moment and categorize those practices as another form of exhaustive testing; albeit one more commonly linked with software developers. Rather, consider that the importance was not the unit size of the piece of software being tested; rather the knowledge of potential flaws that led Einstein (or Podolsky/Rosen) to create a particular thought experiment that attacked a very specific part of the theory. Here, the importance falls upon the knowledge of which parts of the framework to test and in which specific ways. It is in that single aspect I feel most software quality efforts fall short. If I were to attempt to disprove the general theory of relativity, I would stab wildly in the dark testing the most basic assumptions that had more than likely already been tested by the original developer of the theory many times during its creation. Yet this is precisely what happens in many software quality assurance efforts. As a software developer, I have to test and debug my code many times during the natural creation cycle of that code. I go through countless cycles of testing it in many known ways to ensure that it functions in the way that I expect. Despite this, I know these same tests are going to be repeated many times over by an under-informed QA team during a time in the project where time is most limited. The problem doesn’t stop there however, as many developers could cite areas within the system that they feel are potential weak points. This information simply never makes it to the QA team and so they are left up to their own instincts to “find” the bugs within the software.

Consider a different approach, especially early on in the project life-cycle, that involves quality assurance engineers testing simple premises. It is common within software projects for a development team to settle upon one or more patterns that are appropriate for their solution. These aren’t formal software patterns such as the oft-abused factory, more the employment of a particular data-binding technique or a decision about the structure of a data access layer. As soon as the overall system architecture has been constructed there are weak points that begin to identify themselves, areas where the developers aren’t entirely happy with the solution at hand but can’t think of another way to solve the problem within the time and materials budgets that have been set. These areas are perfect for the initial attention of the quality engineers. Just as developers must ramp up on certain technologies for a project, so too must quality engineers. I can’t count the number of times a development team becomes short-tempered with a quality assurance team because they don’t understand why a Foo control behaves in a particular way, conveniently forgetting the struggles they had with the Foo control when first learning it. Had the testing team been present throughout the learning phases of the project, they too would have had the chance to learn about the intricacies of the Foo control, probably learning its quirks from another perspective and providing additional value to the team as a whole by sharing their experience from the end-consumer side of the software.

This brings me to my point (to cut a short story long as might be said) about focusing on falsifiability. The most valuable testing of any system seeks out the worst ruffians (bugs) that are waiting to mug (crash) that system, exposing them early enough in the development life-cycle to have an actual impact on the direction of the project. These most vile flaws are often the most insidious and will appear to deliberately hide from an unsuspecting team until the worst possible moment. Developers are not looking for these flaws. They are focused upon the solution to the problem not on whether their solution will fail. They have knowledge of the potential existence of such flaws but fully intend to code around the problem in a manner robust enough to hold off any coming assault. However, quality engineers are paid exclusively to seek such problems and alert people to the coming calamity while there is still time to avoid it. In order to do this they must know where to look and must focus upon the most uncomfortable parts of the solution, the parts where assumptions fail and things go wrong. It is in this that better communication and more shared knowledge is needed and it is in this that developers have a duty to include their quality personnel and expose to them their deepest fears. Due to the overly oppressive nature of most software deadlines and the expectation that software is a finitely-provable art, most developers would rather tear off a limb than tell the world about every part of their proposed solution that might fail. However, it is in doing just such a thing that a higher-quality product is built and a more robust solution is delivered. After the software launches successfully and proves itself aside from other failing products, developer and tester alike will be held aloft in the minds of product managers (and in some cases users) for having the diligence and skills to deliver. It is in focusing upon the areas of maximum danger, by actively striving to falsify every assumption within the solution that a truly successful software project is born.

Posted in Quality Assurance | Tagged: , , | Leave a Comment »

.NET CLR in SQL Server 2005

Posted by stuartthompson on May 4, 2007

Of recent interest to me has been the ability to deploy user-defined managed functions, stored procedures, and other objects to SQL from within Visual Studio 2005. With the .NET CLR in SQL Server 2005, these managed functions can be written and deployed from within Visual Studio, even as part of an automated build process. In wanting to investigate this further, I’ve decided to write a few articles on how this technique is used and on how it may be useful to you. When I first heard about the ability to (essentially) deploy .NET assemblies into SQL Server and then have SQL Server make managed calls to them for use in queries I was skeptical, thinking this was yet another lost solution embarking upon a life quest for a problem to solve. However, several examples have since been drawn to my attention regarding the usefulness of this solution in exposing features of the richer .NET languages for use in advanced queries.

The first of these areas is that of regular expressions. Earlier this year, I came across an article describing how calls to the .NET 2.0 RegEx classes could be wrapped in a managed function for use in the where clause of a SQL query. My ears (eyes) perked up at this, for the idea of using regular expressions to match data in queries could add a massive amount of power to my SQL toolbox. Even better, because the call would be to the .NET classes, we already know that I’d be able to pre-compile the expressions if needed as that is a feature of that implementation. The rest of this article walks through a simple example for creating a C# Database Project in Visual Studio 2005, deploying a managed function developed in that project, and then writing a query to use that function for RegEx matching within the WHERE clause. For those interested in more information, the original article can be found here: http://msdn.microsoft.com/msdnmag/issues/07/02/SQLRegex/default.aspx.

Creating a C# Database Project in Visual Studio

First, open Visual Studio, then select File->New->Project. In the New Project dialog, expand the Visual C# node and select Database, then choose SQL Server Project from the list of templates. After the project is created, a dialog named Add Database Reference will ask for the specification of a database connection to work with for this project. This connection is used to deploy the project to SQL Server. Select a connection from the dialog or create a new one by clicking Add New Reference. I’ll assume for the brevity of this article that you either have a SQL database or can create a new one and that you can establish a database connection to it. Next, right-click the new SQL Server Project and select Add->New Item. Choose User-Defined Function from the Add New Item dialog and name it whatever you like; I used the class name RegexUtilities.cs in the test project I wrote for this article. This will add a snippet of code in the class that is a template for the function. Replace the entire contents of the code window with the following:

using System;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using System.Text.RegularExpressions;
using Microsoft.SqlServer.Server;

public partial class UserDefinedFunctions {

[Microsoft.SqlServer.Server.SqlFunction]
public static bool Match(SqlChars searchString, SqlString regexPattern) {
Regex regex = new Regex(regexPattern.Value, RegexOptions.Compiled | RegexOptions.IgnorePatternWhitespace | RegexOptions.Singleline);
return regex.IsMatch(new string(searchString.Value));
}

}

The code here is a very simple wrapper around the Regex.IsMatch method and is adapted from the source code supplied by David Banister is his original article. I’ve cut a couple of things down for simplicity. Two parameters are passed to the method named Match: the string to search and the regex pattern to use in the match. The first line of the method creates a new compiled Regex object from the supplied pattern. The second line of codes returns a Boolean that indicates whether or not the supplied searchString was matched. First build the project with Ctrl+Shift+B and then right-click over the project in the Solution Explorer pane and select Deploy. This deploys the managed function to the SQL server you specified in the database connection for the project.

Now it’s time to test the function out in a query. First, let’s take the Social Security Number example and check that everything made it across OK. Open SQL Server Management Studio and connect to your database, then open a New Query window. Now type the following into the new query window:

select dbo.Match( N‘123-45-6789′, N‘^\d{3}-\d{2}-\d{4}$’ )

You should receive the following error:

Msg 6263, Level 16, State 1, Line 1

Execution of user code in the .NET Framework is disabled. Enable “clr enabled” configuration option.

This is because we have not yet enabled a state within SQL server that is disabled by default for security reasons. CLR code obviously wields great power and, as such, the ability to execute that code within the SQL process gives any would be malicious code a very nice process under which to run, and in an authenticated context. To run our example then, we must first instruct SQL server to allow CLR code to execute. This is achieved by running the following SQL within a query window:

sp_configure ‘clr enabled’, 1
go

reconfigure
go

A confirmation message should indicate that the ‘clr enabled’ option was changed from 0 to 1. It indicates that RECONFIGURE should be run to install the change, hence the second SQL statement in the snippet above. Now we are ready to execute our Social Security Number example again. This time you should receive a single result for (No column name) with a value of 1. This indicates a match and was reported as a literal with no column name because of the structure of the statement we ran. Change part of the statement’s left parameter to be an invalid social security number and re-run the example to see that a 0 is received (indicating false) this time instead.

Now the real purpose of this article was the use of Regex in a WHERE clause and for this pick a table that contains a string column. Now construct a SQL statement similar to the following:

select dbo.Match(C.[First Name], N‘^\w{8}$’), C.[First Name]
from C Customer

The statement above displays two columns of data, the first containing the result of the regular expression call, the second containing the customer first name. The regular expression in this example has been simplified to match words of eight characters in length (an oversimplification of the actual syntax, I know, but sufficient for the purposes of this article). Any customers with a first name of eight characters in length will be accompanied by a 1 in the left-hand column, the others with a 0.

That’s it for this article. A quick demonstration of how managed functions in SQL Server 2005 can open the power of the .NET class library for use within SQL.

Posted in .NET Framework, SQL Server | Tagged: , | Leave a Comment »