Saturday, October 20, 2018

Take a Chance

An image of the Earth as taken from the north pole (approximately). It's shaded so that the California timezone is at meridian. Around the Earth is a ring of green circles. Hanging just above California is a red circle.

It was late and Samantha was at work, again.

Her phone buzzed, faintly vibrating against the desk and dancing in her peripheral vision. It was probably her husband, texting to find out when she would be done for the fiftieth time.

She couldn't be distracted. It was an intermittent problem and she was finally able to reproduce it. She was on the scent.

One more Ctrl+Click and she'd find that damn NullReferenceException.

What she saw was repellant. She recoiled both mentally and physically.

"Fucking Kramer," she murmured. "What the fuck is this?"

Sam looked around to make sure nobody had overheard her disparage a coworker. At InterIntraCo, one could do no wrong except in making another feel uncomfortable.

She was safe.

The code was bizarre; a long, winding stretch of nonsense inaugurated by the following abstruse comment...

// Fix timezone bug from Sunday

What "timezone bug"? Which "Sunday"?

Kramer was the worst programmer on the team. He showed up at ten thirty. He left at five. His code made no sense and nobody could ever seem to draw any connection between what he did and a requirement.

His code was so bad that nobody minded his short hours. Most people on his team wished he would leave earlier.

This time, he really stepped in it. There was a proxy class for a data store, which was responsible for storing and retrieving audience-member data for IntraInterCo's line of online marketing products.

Before Kramer's "fix", there was this method...

public Audience GetMember(string token) {
  string document = store.FindById(token);
  return JsonCodec.FromJson<Audience>(document);
}

After Kramer's "fix", this is how the code read...

public Audience GetMember(string token) {
  string document = store.FindById(token);
  if (document.LastUse.TimeOfDay > TimeSpan.FromHours(23) &&
    document.LastUse.TimeOfday < TimeSpan.FromHours(1)) {
    document.Hardware = null;
  }
  return JsonCodec.FromJson<Audience>(document);
}

Samantha slammed her clenched fist on the desk and repeated her lament. "What the fuck?!?"

The entire system was dependent on an Audience having its Hardware property be populated. Nobody checked that Hardware wasn't null because, until then, it never was.

She ran her fingers through her long, dishwater blonde hair.

"Fuck that guy," she muttered.

Click. Hold. Drag. Delete...

The cure for all Kramer's code, she mused.

A few seconds later, a green bar told her that it was safe to check in her code. She did so with one hand while grabbing her phone with the other.

On the elevator to the parking level, she texted Jack to let him know she was on her way.

Twenty minutes later, she was home and asleep. It stands to reason, she didn't notice the phone buzzing in her purse, quietly letting her know she broke the build.

On Monday, when she arrived for work, she found out what happened.

None of the unit tests failed when she made her change but an integration test was no longer passing. She always got to the office last, so everyone else had been dealing with it all morning.

Sam's cheeks flushed red.

"All the tests passed," she said.

Her coworker, Fred, laughed and said "Don't worry. We've already figured out what happened."

'What was it?"

"Kramer."

Samantha shrugged her request for more.

"Five weeks ago, he wrote some weird code. Here", said Fred. "Let me show you."

The code was in a distant part of the system that used an Audience object...

public int GetIdentificationConfidence(Audience audience) {
  var confidence = 0;

  // snipped

  if (audience.Hardware != null) {
    if (audience.Hardware.Type == HardwareType.Mobile)
      confidence += 10;

    if (audience.LastUse.TimeOfDay - DateTime.Now.TimeOfDay <
      TimeSpan.FromHours(-1))
      confidence -= 25;
  }

  // snipped

  return confidence;
}

"I see," said Samantha. "I'm assuming nobody knows why he wrote that, least of all him. So what was the 'Timezone bug from Thursday'?"

"When he checked that in, everything was fine. Most of the time, this doesn't get hit. The Sunday before last, one of the integration tests hit that code just wrong. The setup stuff happened right before midnight and the assertion stuff right after."

A grim smirk crept over Samantha's face. "...and it just happened to be one of the confidence score tests."

"Yeah... So his 'fix' was basically to make sure his code doesn't run in the 11:30 nightly. You took it out and just happened to get hit by the same timing issue."

"So how did you fix it?" asked Samantha.

Fred chuckled and said, "The same way you fixed the null reference exception, on Friday."

Samantha jerked a little nod of acknowledgment.

They both made their pleasantries and began to drift toward their respective desks. After a few steps, something occurred to Sam.

"Wait a sec," she almost shouted. "Why did he call it a 'timezone bug'?"

Fred laughed and answered, "Oh right! That's the best part. What happened, two Sundays ago?"

Samantha shook her head.

"Daylight savings time," said Fred. "Spring forward." He raised his eyebrows as he added "Kramer."

Samantha snorted and replied "Kramer."

(continued here)

Friday, October 19, 2018

The Product Pee-Pee Dance

A person standing on one leg, holding their knees together, jittering around. There are two sentences: "RELEASE!" and "RIGHT NOW!"

It's urgent. It's emergent. It's the end of the world!

Get it out now. Right now. No. Now's too late. Get it out then.

I call it the "product pee-pee dance", where an organization hops from foot to foot until they push a product out to production, whether it's ready or not.

Thursday, October 18, 2018

Be Careful with the Word "Just"

People cower before a giant robot, bristling with weapons. One person says "Don't worry. It's just some metal and stuff."


I hear these kinds of claims a lot...
"It's just UI logic."
"That's just database-connectivity code."
This is generally as a preamble to an argument that the code in question can't or should not be tested.

The word "just" sometimes is used in its true meaning. That is, sometimes you have a method that really does just do some small thing that's unduly expensive to test.

Most of the time, the word "just" hides something else. Often the phrase "that's just X" really means "I can't imagine how to separate everything in that method that's not X from X."

One might be tempted to call this "just"-ification.

It's okay to have some of your code not be covered in tests. You just shouldn't feel the urge to explain yourself when you do. It should be self-evident that a method or class is just glue code to some peripheral component.

If you find yourself explaining to someone else - or to yourself - that a block of code is just something, make sure you take a beat and verify. Is it really "just", or is it "just"-ification?

Wednesday, October 17, 2018

Mistrust Squared

Three charts: A line with a marker in it that says 20%. Two perpendicular lines with markers through each and a square that says "4%". Three perpendicular lines with markers that define a cube and the label "0.8%".


Let's say you're testing process/infrastructure/pipeline is something in which you have 80% confidence. That is when you run your tests (however you run them) you think you have a four out of five chance of finding any given problem.

Sometimes, people want to do multiple test passes in order to reduce risk. For instance, if your chances of finding a problem are four out of five on the first pass and four out of five on the second pass, then it stands to reason that the chances of it being found are 24 out of 25 if you do two passes.

Tuesday, October 16, 2018

It's Okay to Talk with Product about the Outcome of Engineering

Two similar situations where a mechanic explains what's wrong with a car to a client. In the first, the mechanic descends into techno-babble (which literally devolves into babbling). In the second, the mechanic explains the effect on the client (fixing a problem will take a long time because he has to order a tool from Europe).

The hard-cast roles I often see in a newly-turned-agile organization tend to drive some unproductive ideas about how people should communicate. Specifically, regarding what not to communicate.

Sure, you don't want to bore a freshly-minted product owner with technical details but the goal is nothing to do with boredom. Instead, it's about signal-to-noise ratio.

Technical details are the purview of an engineer but the outcomes of technical choices have ramifications that are unquestionably business-facing.

Consider the following (made-up) report from an engineer to a product owner.
I did it the right way. I noticed there was a Strategy pattern indicated by the problem. So I took care to properly-encapsulate the variation and extract the common part away. I made sure I wrote a full suite of tests because I'm a test-driven developer.
Here's an alternative way of saying the same thing.
I did it the right way. There are currently several options and I made sure adding or subtracting choices won't have an undue cost, later. I also made sure that nobody will be able to break this functionality without us finding out immediately and fixing it before it has a chance to become a real problem.
Imagine you are a product owner with no technical knowledge. Which of those sounds better to you?

The answer should be "the latter".

For one thing, there's nothing technical in it. For another, the first report sounds like it's about a developer's sense of pride. The latter is a clear delineation of the real costs and benefits involved in doing things the right way. It's information that is useful to the product owner.

That's the key. It's okay to talk about technical matters with nontechnical people. If you have the impulse to do so, there's probably a good reason. There's something you are trying to communicate that is actionable or meaningful to them.

Just make sure the message is focused on the part that will be interesting to its recipient instead of expressed in the way you find most appealing or convenient.

Monday, October 15, 2018

Benefits of Focus

Two alternate cases where a person is blocked by a stone barrier. In one case, someone is using a laser to cut through. In the other, someone is using a spotlight with no appreciable effect.


Earlier, I mentioned that the done-centric culture of a truly Agile organization is largely about focus.

Focus has a lot of positive benefits and I'm not going to get into all of them.

Here's a short list, that is good enough for this blog entry.
  • It highlights impediments by forcing them to be seen as part of the workflow - if you can't switch focus, it's harder to "look away" from a problem.
  • It makes large batch sizes more obvious.
  • It minimizes knowledge loss in the course of a task.
  • It discourages work on less important tasks when more important ones are done.
There's probably an entire series of blog entries about the importance of focus.