Stories about Software


Transitioning from Manual to Automated Code Review

Editorial note: I originally wrote this post for the SubMain blog.  You can check out the original here, at their site.  While you’re there, have a look at CodeIt.Right.

I can almost sense the indignation from some of you.  You read the title and then began to seethe a little.  Then you clicked the link to see what kind sophistry awaited you.  “There is no substitute for peer review.”

Relax.  I agree with you.  In fact, I think that any robust review process should include a healthy amount of human and automated review.  And, of course, you also need your test pyramid, integration and deployment strategies, and the whole nine yards.  Having a truly mature software shop takes a great deal of work and involves standing on the shoulders of giants.  So, please, give me a little latitude with the premise of the post.

Today I want to talk about how one could replace manual code review with automated code review only, should the need arise.

Why Would The Need for This Arise?

You might struggle to imagine why this would ever prove necessary.  Those of you with many years logged in the enterprise in particular probably find this puzzling.  But you might find manual code inspection axed from your process for any number of reasons other than, “we’ve decided we don’t value the activity.”

First and most egregiously, a team’s manager might come along with an eye toward cost savings.  “I need you to spend less time reading code and more time writing it!”  In that case, you’ll need to move away from the practice, and going toward automation beats abandoning it altogether.  Of course, if that happens, I also recommend dusting off your resume.  In the first place, you have a penny-wise, pound-foolish manager.  And, secondly, management shouldn’t micromanage you at this level.  Figuring out how to deliver good software should be your responsibility.

But let’s consider less unfortunate situations.  Perhaps you currently work on a team of 2, and number 2 just handed in her two week’s notice.  Even if your organization back-fills your erstwhile teammate, you have some time before the newbie can meaningfully review your code.  Or, perhaps you work for a larger team, but everyone gradually becomes so busy and fragmented in responsibility as not to have the time for much manual peer review.

In my travels, this last case actually happens pretty frequently.  And then you have to chose: abandon the practice altogether, or move toward an automated version.  Pretty easy choice, if you ask me.

Read More


Things Everyone Forgets Before Committing Code

Editorial note: I originally wrote this post for the NDepend blog.  You can check out the original here, at their site.  While you’re there, take a look around at some of the other posts as well.

Committing code involves, in a dramatic sense, two universes colliding.  Firstly, you have the universe of your own work and metaphorical workbench.  You’ve worked for some amount of time on your code, hopefully in a state of flow.  And secondly, you have the universe of the team’s communal work product.  And so when you commit, you force these universes together by foisting your recent work on the team.

In bygone years, this created far more heartburn for the average team than it does today.  Barbaric as it may seem, I can actually remember a time when some professional software developers didn’t use source control.  A “commit” thus involved literally overwriting a file on a shared drive, obliterating all trace of the previous version.  (Sometimes, you might create a backup copy of the folder).  Here, your universe actually kind of ate the team’s communal universe.

More Frequent Commits, Fewer Problems

But, even in the earliest days of my career, lack of source control represented sloppy process.  I remember installing the practice in situations that lacked it.  But even with source control in place, people tended to go off and code in their own world for weeks or even months during feature development.  Only when release time neared did they start to have what the industry affectionately calls “merge parties,” wherein the team would spend days or weeks sorting out all of the instances where their changes trampled one another’s.

In the interceding years, the industry has learned the wisdom of continuous integration (CI).  CI builds on the premise, “if it hurts, do it more,” by encouraging frequent, lower stakes commits.  These days, most teams commit on the order of hours, rather than weeks or months.  This significantly lowers the onerousness of universes colliding.

But it doesn’t eliminate the problem altogether, even in teams that live the CI dream.  No matter how frequently you do it and how sophisticated the workflows around modern source control, you still have the basic problem of putting your stuff into the team’s universe.  And this comes with the metaphorical risk of leaving your tools laying around where someone can trip over them.

So today, let’s take a look at some of the most common things everyone forgets before committing code.  And, for the purposes of the post, I’ll remain source control agnostic, with the parlance “commit” meaning generally to sync your files with the team’s.

Read More


Pulling Your Team Through a Project Crunch

Editorial note: I originally wrote this post for the NDepend blog.  You can check out the original here, at their site.  While you’re there, download NDepend and take it for a test drive.

Society dictates, for the most part, that childhood serves as a dress rehearsal for adulthood.  Sure, we go to school and learn to read, write, and ‘rithmetic, but we also learn life lessons.  And these lessons come during a time when we can learn mostly consequence-free.

During these formative years, pretty much all of us learn about procrastination.  More specifically, we learn that procrastination feels great.  But then, perhaps a week later, we learn that procrastination actually feels awful.  Our young brains learn a lesson about tradeoffs.  Despair.com captures this with a delightfully cynical aphorism: “hard work often pays off after time, but laziness always pays off now.”

The fact that we laugh at this indicates something interesting.  Whereas we learn most childhood lessons and internalize them (e.g. don’t touch a hot stove), we don’t learn all of them this way.  Procrastination falls into this latter category.  We learn its perils, but we do it anyway, for various reasons.

As someone in the software industry, I suspect you can appreciate this.  Even if you diligently get out in front of all of your work, your organization may not follow suit.  So I’m sure you’ve seen your fair share of so-called “crunch time” over the years.  Crunch time occurs when you put a disproportionate amount of effort right before an important milestone.  Kinda like waiting until the night before the due date to write a 10 page essay on To Kill a Mockingbird.

Today, I’d like to talk about surviving these crunches.  How can you navigate them to come out on the other end with your team’s morale intact?

Beware the Death March

For argument’s sake, I’ll draw a fine line.  Crunch time and the so-called “death march” can seem like the same thing, but I submit that they differ importantly.  Crunch time involves working hard in a spurt to succeed.  Death marches involve working hard indefinitely with a high probability of failing anyway.

The first step for pulling a team through a crunch is to ensure that you’re not instead dispatching them on a death march.  If your organization has the unfortunate habit of getting itself into death marches, you have serious problems on your hands that transcend the immediate future.  At an organization like this, I’d recommend looking for escape avenues and hinting to others that they might do the same.

If this sounds bad or like the height of disloyalty, I suggest a bit of perspective.  Your organization is about to ask you to burn yourself out on an indefinite timeline for something that will probably fail.  Unless you’re a masochist, what about that warrants your loyalty?

Read More


Choosing an Acceptance Test Framework

Editorial note: I originally wrote this post for the Monitis blog.  You can check out the original here, at their site.  While you’re there, take a look at their monitoring solutions.

I can still remember writing my first automated tests in a professional setting.  Notice that I didn’t say unit tests, and for good reason.  At the time, some 14 years ago, I hadn’t heard of unit tests.  Instead, I simply automated the process of manually testing my software.

This may sound somewhat facile, but it actually speaks to core principles in the programming profession.  As a relatively inexperienced programmer, I understood the importance of testing my work.  I also understood the importance of automating manual, error-prone process.  And so, of my own accord, I examined and then automated my previously manual testing efforts.

Don’t get me wrong.  By doing this, I reinvented a wheel simply because I did not know of its existence.  Folks had created automated unit test frameworks for this exact purpose.  Had I known, I could have better spent my time learning and using these things.  But, in spite of the waste, I did learn something.  I learned that, under the covers, test frameworks just represented yet another instance of automating an important manual process.

What is User Acceptance Testing (UAT)?

I led with a tale about unit tests because testing software components applies to everyone that writes software.  I mean, you always test your own software, even if you don’t think you’re doing so.  Whenever you compile, you test your code to see if it compiles.  Granted, you aren’t executing the most sophisticated, high-value test known to man.  But you are performing a test of sorts.

But what if we look beyond our own dev boxes a bit?  What if we look at other forms of testing?

For almost any software that we write, other stakeholders will perform other sorts of tests.  These stakeholders includes users or user-proxies, who perform an activity known as user acceptance testing (UAT).  In its simplest incarnation, this involves users or their proxies using the software and evaluating whether or not they find it acceptable.

This can come in various shapes and sizes.  In some cases, actual users perform formalized beta tests, perhaps for pay.  In other cases, someone from the QA group might do a quick run-through and give a thumbs-up or thumbs-down.  But whatever happens, these tests capture the user’s experience and perspective.

Read More


Weaponized Mastery, Autonomy, And Purpose

Years ago, I published a post called How to Keep Your Best Programmers.  In it, I discussed what drives programmers out of jobs and what keeps them happy.  This discussion touched heavily on the concepts of mastery, autonomy, and purpose as important motivators for knowledge workers.  If you want to keep skilled programmers, you can’t just throw money and bonuses at them — you need to appeal to these other forms of motivation.

This post became quite popular and has remained so over the years.  I think the popularity results from the resonant idea of wanting our lives and careers to mean more than just a paycheck.  We want to be proud of what we do.

Since my own discovery of it years ago, I’ve seen frequent reference to these motivators and to Daniel Pink’s talk about them.  People use it to explain the difference between work that pays the bills and work that deeply satisfies.  More and more, we exhort our employers to appeal to mastery, autonomy, and purpose.  And more and more, they seem to do it, to our benefit and that of the industry at large.

But with this trend, I’ve noticed an interesting and unanticipated side effect.  People can appeal to autonomy, mastery, and purpose to enrich our lives, but they can also do so to manipulate us.

Mastery, autonomy, purpose -- they make us happy, but they can mesmerize us.

Mastery, Autonomy, and Purpose as Vices

To understand how that works, consider our desires in a different light.  Consider what happens when you take them to extremes.

We enjoy getting better at things (mastery), but that can lead to obsessive behavior.  I think most of us can relate, at some point in our life or another, to playing way too much of some kind of stupid video game.  We know it wastes our time and that we should probably delete it, but… just… one… more level.  Mastering the game drives us even when we know it wastes our time.

We also enjoy autonomy, but chasing that can lead to problems as well.  Have you ever known someone serially unemployed because they bristled at the thought of anyone telling them what to do?  Some people with that demeanor become entrepreneurs, but some become angry criminals.

And purpose as a vice can be, perhaps, the scariest of all.  Think about the phrase, “the ends justify the means.”  What is this if not a statement that purpose trumps all?  As long as you’re chasing a lofty enough goal, it doesn’t matter who you step on to get there.

We can chase mastery, autonomy, and purpose into problematic territory.  But other people can also use them to chase us there.

Read More