When testing is not fun enough

Arseni Mourzenko
Founder and lead developer
176
articles
May 19, 2021
Tags: testing 7 quality 36 rant 34 productivity 36

On reg­u­lar ba­sis, some col­league starts com­plain­ing in an in­for­mal dis­cus­sion about the low qual­i­ty of some pro­ject he's work­ing on. It has to do with code qual­i­ty, or lack of tests, or both. Every time, I end up ask­ing why he doesn't add tests in the first place, and hear one of a few an­swers.

For per­son­al pro­jects, peo­ple of­ten re­spond that writ­ing tests is just not fun enough. Un­der­stand­able—while some TDD can be a lot of fun, there is a lot more to test­ing that can be plain bor­ing. I my­self have dozens of per­son­al pro­jects which have no tests at all, or ex­treme­ly few tests even when the code could be quite com­plex.

The “not fun enough” rea­son, how­ev­er, hard­ly works for the pro­jects done for an em­ploy­er or a cus­tomer. You're paid to do work which may not al­ways be fun. De­vel­op­ers, there­fore, re­vert to a few dif­fer­ent an­swers:

  1. No­body writes tests in my team. Why would I be the only one? Or a dif­fer­ent vari­ant: it's not the cor­po­rate cul­ture. Who am I to go against it?
  2. If I do tests, I spend more time ship­ping a fea­ture com­pared to my col­leagues who don't test any­thing, and so I look bad.
  3. Man­age­ment/stake­hold­ers need fea­tures fast. They can't wait for me to write tests.

Let's dis­cuss those three rea­sons.

Cor­po­rate cul­ture

Over my ca­reer, I've been to many places. I worked with amaz­ing teams and de­vel­op­ers much more skill­ful than I am, and I also worked in com­pa­nies filled with pro­gram­mers who don't know how to pro­gram. In every case I tried to be pro­fes­sion­al, that is, to de­liv­er test­ed, cor­rect­ly writ­ten, refac­tored code. No one com­plained that I wasn't fol­low­ing crap­py cor­po­rate cul­ture.

Cor­po­rate cul­ture is one thing; pro­fes­sion­al­ism is an­oth­er. Think about it this way: you'll spend maybe a year or two in a com­pa­ny, and then you'll go some­where else. The cor­po­rate cul­ture, you'll leave it be­hind. What you'll keep is (1) the skills you got, (2) the good or bad habits, (3) in some cas­es the source code that you will be able to show to a re­cruiter, and (4) the feel­ing that you did a great job, or the lack of there­of. Cor­po­rate cul­ture doesn't mat­ter—it's not your cor­po­ra­tion, and there­fore it's not your cul­ture. What mat­ters is what you did, per­son­al­ly. If you don't like it, ig­nore it.

There are cas­es where wrong cor­po­rate cul­ture is so strong, that you can't pos­si­bly ig­nore it. Ob­vi­ous­ly, if your salary is pro­por­tion­al to the num­ber of lines of code (LOC) you write per month, you can't imag­ine your­self refac­tor­ing the code base in or­der to get rid of twen­ty thou­sand LOCs: if you do it, you will have to give mon­ey to your em­ploy­er. In this sit­u­a­tion, you have to weight your chances to get a bet­ter job, and the im­pact this one could have on your ca­reer. Such com­pa­nies could dam­age your skills, your mo­ti­va­tion, and your rep­u­ta­tion; make sure you un­der­stand the po­ten­tial im­pact when work­ing there. Imag­ine you're a sales­man, and you are hired to sell stuff. In a mat­ter of days, you learn that the prod­uct you have to sell sucks, and that all the mar­ket­ing is a lie. You can stay and spend the next few years de­ceiv­ing peo­ple, or you can leave. If you leave, you'll have to look for an­oth­er job while hav­ing no in­come. If you stay, you'll have to look for an­oth­er job even­tu­al­ly, and “I worked ten years for a bunch of liars” may not be the best thing on your re­sume.

Fast, faster, fastest

Math time. Jeff and Mary are asked to im­ple­ment, in par­al­lel, the same fea­ture to a pro­ject as fast as they can. They work on dif­fer­ent repos­i­to­ries, so changes per­formed by one per­son won't af­fect the code base of the oth­er. They both have sim­i­lar skills, and sim­i­lar knowl­edge of the code base.

Jeff:

  1. Reads the de­scrip­tion of the fea­ture.
  2. Starts typ­ing right away.

Mary:

  1. Reads the de­scrip­tion.
  2. Goes for a chat with the stake­hold­er to clar­i­fy a few as­pects.
  3. Talks with a col­league about the pos­si­ble ways to im­ple­ment the fea­ture.
  4. Checks the code base and adds some tests on a part which was, for some rea­son, untest­ed and which will be af­fect­ed by the new fea­ture.
  5. Refac­tors the log­ic which was par­tic­u­lar­ly cryp­tic—it would be much eas­i­er now to add the fea­ture.
  6. Asks an­oth­er col­league to do a pair pro­gram­ming ses­sion with her to im­ple­ment the fea­ture.
  7. Makes a call to the stake­hold­er when she finds a thing which doesn't seem right.
  8. En­sures the fea­ture is test­ed.
  9. Asks her lead to re­view the change, es­pe­cial­ly the thing she's not sure about.

Ques­tion: who would de­liv­er first?

In fact, the an­swer de­pends of what we con­sid­er as de­liv­ered. Two hours lat­er, Jeff could com­mit his changes, and call it a day, con­sid­er­ing that the work is fin­ished. And then, maybe, the build will fail. But it doesn't mat­ter if we con­sid­er that the fea­ture is fin­ished as soon as the de­vel­op­er told us that he fin­ished it.

Or we can con­sid­er a fea­ture as fin­ished when it ac­tu­al­ly works as ex­pect­ed in pro­duc­tion, and match­es the orig­i­nal re­quire­ments. And here, I doubt Jeff would win over Mary. I even bet that Mary will ship the fea­ture by the end of the day, while Jeff would still be work­ing on it weeks lat­er, be­cause he would have to solve all the mis­un­der­stand­ings be­tween him and the stake­hold­er, fix all the re­gres­sions he in­tro­duced, re­work the code sev­er­al times un­til he gets it in a work­ing state, etc.

In some com­pa­nies, stake­hold­ers don't grasp the no­tion of de­liv­ered. Some­thing may make them think that Jeff's de­f­i­n­i­tion of done is the cor­rect one, and there­fore Mary is not do­ing a good job. It takes time, and it re­quires a good skills in pol­i­tics, to make the stake­hold­ers to un­der­stand what's right, and what's wrong.

In most com­pa­nies, how­ev­er, stake­hold­ers don't even think about the de­f­i­n­i­tion of done. They don't care. They want their fea­tures, they want them to be fin­ished yes­ter­day, and they want them to work as ex­pect­ed. In those cas­es, there is no need for spe­cial skills in pol­i­tics to ex­plain that Mary is do­ing great, and Jeff is not.

Dead­lines

Even­tu­al­ly, there is a dead­line to meet, such as a re­lease an­nounced pub­licly. Or a giv­en fea­ture is re­al­ly im­por­tant to the loud­est stake­hold­er, and so you need to ship it fast if you want the guy to shut up and stop both­er­ing every­one.

How­ev­er, ship­ping code that doesn't work has more of­ten than not the op­po­site ef­fect. The loud­est stake­hold­er doesn't shut up, and starts com­plain­ing even loud­er that the fea­ture doesn't work. And the fact that your com­pa­ny for the first time didn't miss a dead­line doesn't pre­vent it from los­ing all cred­i­bil­i­ty by ship­ping a piece of soft­ware which crash­es as soon as it starts.

Usu­al­ly, stake­hold­ers pay your salary. This makes one think that what­ev­er the stake­hold­er de­cid­ed is an ab­solute truth. The re­al­i­ty is slight­ly dif­fer­ent. Stake­hold­ers do de­cide things, but they don't de­cide how you do your job: it be­longs to you to do it pro­fes­sion­al­ly.

Imag­ine that you're in a plane for a busi­ness trip. You're in a hur­ry: in three hours, you have an im­por­tant meet­ing in Los An­ge­les: you have to be there, no mat­ter what. Un­for­tu­nate­ly, as the plane is ready to take off, the pi­lot tells that the flight would be de­layed. In fact, some flight con­trols don't seem right, and it is un­safe to fly un­til the is­sues are fixed. You're an­gry, and you don't hes­i­tate to ex­plain to the flight at­ten­dant how are you dis­ap­point­ed with the air­line. Af­ter all, you're a pay­ing cus­tomer, and it's your choice to avoid this air­line in the fu­ture. Now, would you pre­fer the pi­lot to take off and see if the plane crash­es or not, or would you rather pre­fer if he does what he is sup­posed to do by the pro­to­col, that is, keep the plane on the ground un­til he's ab­solute­ly sure that it is per­fect­ly safe to fly?

Stake­hold­ers know about pro­gram­ming as much as we know about planes, and as pi­lots have pro­ce­dures, so do we have our own pro­ce­dures. As pi­lots need to be sure the plane is safe to fly be­fore tak­ing off, we, de­vel­op­ers, have to be sure the code we re­lease is de­cent enough and won't crash.

As a cus­tomer who's pissed off by a de­layed flight can de­cide that he would avoid the air­line in the fu­ture, a stake­hold­er may be pissed off be­cause the fea­ture haven't been de­liv­ered on time, and fire you. This is a very con­crete risk, but what one shouldn't for­get that the al­ter­na­tive can also have some nasty con­se­quences. De­vel­op­ers have been fired af­ter de­liv­er­ing bro­ken fea­tures, and hav­ing the boss storm­ing in be­cause you shipped on time some­thing which also de­stroyed your cor­po­rate data­base is not fun at all.

There is rep­u­ta­tion in­volved too. It should be quite chal­leng­ing to find a job af­ter you have been fired for break­ing some­thing. It should be much eas­i­er to find one af­ter you have been fired for be­hav­ing pro­fes­sion­al­ly.

Con­clu­sion

It all comes to the fun fac­tor. Many de­vel­op­ers don't en­joy test­ing. It's not fun. It's not as fun as pon­der­ing five hun­dred lines of code in an af­ter­noon, draft­ing some su­per com­pli­cat­ed al­go­rithm which makes you proud (es­pe­cial­ly if none of your col­leagues can un­der­stand it). This is wrong, but un­der­stand­able.

The fact is, de­vel­op­ers don't want to ad­mit that they don't test code be­cause they don't en­joy it. And so they find ex­cus­es. The best way for an ex­cuse is to move the re­spon­si­bil­i­ty to some­body else. “They told me that I don't need to test” sounds just per­fect: I, the de­vel­op­er, would rather do a good job, but some­body else who pre­tends that he can de­cide what I do told me that I shouldn't do a good job. Good try, but the fact is, if test­ing was fun, you would be test­ing no mat­ter the cor­po­rate cul­ture, no mat­ter how fast your col­leagues ship fea­tures, and no mat­ter what stake­hold­ers tell you.

So, please, go add some tests. Now.