Monday, January 12, 2015

The Art in Testing


Somewhere in the deep guts of a project you enjoy the "pleasure of unit testing." Typically the dead center looks like:

Approval of interface design
Various programming tasks
Unit tests
Software corrections from unit testing
System and stress testing

The nice thing about unit testing is that it gets so buried into the guts of a project that the managers don't pay much attention to it. Despite this however, the unit testing ultimately determines, unequivocally, the quality of your product.

Just because no one is looking doesn't mean that you should slack off from the unit tests. If your software is modularized, which on a larger project is most probably the case, then you can unit test as individual modules become available.

Earlier I discussed Artistic Test Harnesses, and how they not only allow for rapidly repeatable unit testing but also provide a failsafe for workarounds during implementation. Be sure to read that previous post to learn how to construct these useful utilities.

Recognize that Quality always involves work: there are no shortcuts to achieve it. It turns out that it is mostly the hidden, unmanaged, personal part of your work that primarily determines your long-term success.


Wednesday, December 10, 2014

More Artful Beauty


We must choose in a hundred little ways how maintainable to make our software. I wish to give you some guidance, some signposts: when you are deep in the trenches facing these hundreds of little choices, what key questions that you should ask yourself? By answering them whenever you are at a design fork-in-the-road, you will know which path to follow.

You can certainly go overboard on the maintainability spectrum. After all you do have a product to deliver. But a fair and reasonable amount of refactoring is necessary to allow the software to retain its value. So every time you roll up your sleeves and dive into the code, ask yourself these eight questions:

1) Got whitespace?
I like to see code blocked out into sections in a manner akin to how a writer blocks off paragraphs. I don't need your otherwise obvious comment lines in front of each section, just a plain intervening blank line lets me know that you are moving on to another train of thought.

2) Do you have to scroll right to read it?
If so then you are probably combining too many conditions in a single statement. Refactor into a nested "if" or if you're already deeply nested make a new function.

3) Can it have a better name?
Variables and functions should say what they do and do what they say.

4) If you were to place a debug checkpoint, what would be good to know here?
It sure compresses the coding when you do dataset.table.rows.columns[4], but it's a royal pain for debugging. If you're going more than two dots deep set a work variable for the object partway down.

5) Is your module getting too long? I chatted about appropriate module sizes in an earlier post.

6) Are the parameters that control the whole bailiwick commented at the top of your code? Are there too many of them in different places?
If you are gathering input parms from every conceivable source, maybe it's time to consolidate. You may even need to create an intermediate feeder object that collects and denormalizes all this stuff.

7) Are the logic sections... ah.... logical?
When I see nested "if" statements inside of case statements I cringe. Testing for not A or not B makes my eyelid quiver. Clean up your logic to test for eligible conditions (as opposed to ineligible conditions) and set intermediate Boolean flags.

8) Will you be able to understand this piece of code three years from now?
Perform the mental experiment of imagining that after you compile this into production, you won't see it again for another three years. Will you be able to understand what the code does? Leave yourself enough breadcrumbs to find a safe path back to understanding.

Yeah following these guidelines is a little more work, but as the saying goes: hey you can pay me now or you can pay me later.


Tuesday, November 4, 2014

The Art of Survivability


In the rough and tumble world of the development of corporate software most companies establish "checkpoints" to assure that their engineers don't get too far down the river before they realize that they needed a paddle (or an outboard motor). How they implement these inspections (with paperwork or process) varies greatly, but the overarching principles are standard. What a company needs from its software operationally in order to prevent a black-swan failure is:

1.       Scalability – developers need to demonstrate right from the start that each successive implementation will meet the *eventual* maximum usage envisioned (in terms of concurrent users and fully loaded database tables).

2.       Trackability – every release should document what changed or got added -- in a public location -- for everyone to see.

3.       Knowledge base – all modern software is so immensely complicated and rapidly changing that it is impossible to keep the technical documentation up-to-date.  Therefore to support maintainability at least two full-time Permanent (in-house employee) software developers need to know everything about any particular system.

4.       Operationally Repeatable – Production controls must exist to allow for the restoration and re-running of a system from any arbitrary point.

5.       Archivals and Deletions – You need utilities to remove old data to prevent the gradual quicksand degradation of performance that will  suddenly cause a cascade of timeouts.

6.       Implementation Rollback – anytime a major software change gets implemented you need a way to roll it back.

Those are the biggies in general philosophical terms. Yeah this list probably doesn’t help much down in the weeds for what documents or gateways to put in place, but it’s a good start for group discussions to get there.