DaedTech

Stories about Software

By

Fight or Flight

As software developers, or, more broadly, as techies, we are extremely fortunate. So many people want to give us money and jobs that we find it annoying. Let that sink in for a moment. A serious first world problem that we all share is how many times per week people cold call us to ask us to interview for other jobs. That’s our strange reality and, as someone who graduated with a CS degree right into the teeth of the dotcom bubble bursting, I can tell you that it isn’t the worst problem that one could have. Still, it’s shaped our collective outlook on work and, in my opinion, is pushing us toward free agency in which developers eventually stop having even the pretense of long associations with companies.

But what if you don’t want free agency? What if you don’t want to deal with the hassle of resumes and interviews involving silly brain teasers and other indignities? You can just ignore the recruiters in the short term, but is the writing on the wall for complete deterioration of the traditional association between developers and (non-consultancy) employers? I’ll get back to that.

My girlfriend told me a story once about a guy she had dated years earlier. They were driving down a highway when they came upon a guy broken down and with a flat on the side of the road. He looked like he could use some help. The ex-boyfriend, apparently in an inexplicably foul mood, took note of this situation, leaned out his window while driving by and gestured obscenely at this hapless and now bewildered motorist who was doing absolutely nothing but having a bit of bad luck. This random act of meanness, my girlfriend told me, was the exact moment at which she knew the relationship wouldn’t work out. They dated for a bit after that, but apparently from then on it was pretty much a matter of running out the clock until the inevitable, awkward conversation. It wasn’t as if in that moment she thought “that’s it, this is over” nor was that by any stretch the only problem with the relationship, but it became a defining Moment — a catalyst.

I think there’s a Moment like this in every job that you leave: being passed over for a big promotion, hearing an official announcement that you’re going to be switching everything to VB6, being verbally abused by a superior in a group setting, etc. It’s The Moment at which you know that it’s over and the rest is just details and formalities. I can think back to every job that I’ve had and remember this Moment (or perhaps 2-3 viable contenders) with amazing clarity. In this day and age, few programmers practically think that they’ll be somewhere until retirement, but the idea of leaving the company is some nebulous, abstract, future concept when they start, and it remains that way until The Moment. And then it becomes clear, concrete, and, while still in the future, not far off. Your departure is no longer a class in source code but an instantiated object in process memory just waiting to be triggered and exhibit real, actual behavior.

But what if you don’t want this? What if you’re not interested in moving around and don’t want a long list of one year stays on your resume? After all, if you’re a job-hopper, The Moment is like an old friend beckoning you onto a greener pasture. But if you’re content and more of a permanent worker type, The Moment is probably depressing and terrifying. So how do you avoid it?

Well I certainly can’t give you anything bulletproof, but I can sum it up with a simple mantra that you can hang onto when you’re contemplating taking a job: find a place worth fighting for. Maybe you’re a big advocate of green technologies and you find a job working for a solar panel manufacturing company. Maybe you really like Legos and you go work for Lego. Maybe you go work somewhere that all of your friends work and you’re invested in the camaraderie. Whatever the case may be, you have to find a reason that you’d fight to stay there. If you have that, then The Moment becomes one of galvanization and thrown gauntlets (within reason — if it’s something like harassment or a pay cut, all bets are off) rather than the centerpiece of a future story about why you changed jobs, anyway. When those Moments come, like a random driver with rage issues — and they will come — it’s fight or flight. And if you’re not willing to fight, it’s going to be flight.

By

Imagine a Process Regression

I was recently out to dinner with some friends that are fellow techies, and we were talking about software development methodologies. One of them, who works in a shop that practices pretty true-to-form Scrum, was talking about how management via the product owner was starting to put pressure on them to produce certain, lower point estimates during the planning poker game. He said that it struck the younger team members who’d only worked there as extremely strange and that he personally felt that the powers that be were sort of trying to steer them to a more “waterfall-ish” style. I had a random thought and, rudely, burst out laughing during his anecdote which was, in no way, intended to be funny.

The thing that I had thought of, I explained to my confused friends, was how incredibly weird and counter-intuitive moving to a waterfall development methodology would seem to his teammates who had come into the software development world knowing only Scrum. It’d be like coming home one day and telling your family that you were through buying soap because from now on all you needed was some lye, some elbow grease and the river on the other side of town. Of course, there would (and has been) culture shock going from Waterfall to Agile, but that’s mostly born of a kind of “that’s an impossible pipe dream” mentality. Going the other way has more of a “you want to do what…. and why?” vibe.

Think of this. You’ve never known anything but a disciplined agile approach to software. You have an automated build and deployment setup. Every time you check in code, the build executes, unit tests are run, and the code is pushed to a test environment for exploratory QA and validation of user stories. Checkins are frequent, collaboration is ubiquitous and refactoring and cleaning the code is something you do on a regular basis. Once every other week, you ship the code and it’s no big deal. The (business) day after shipping, you and the team collaboratively plan what you’re going to do for the next two weeks, trusting that someone is prioritizing the work you wind up doing toward a larger technical product/vision. Your users see regular progress and give you regular feedback, creating a tight communication loop and eliminating surprises. And, if the users change their mind about the features they want or don’t like what you’ve done over the last two weeks, you simply spend the next two weeks steering methodically back in the right direction. But don’t worry, that’s all about to change!

Forget about all of that bi-weekly shipping nonsense. We’re going to ship once, as far as we’re concerned. A second shipment is by no means a given because frankly, the first one is rather likely to fail and anger the users. So, let’s not concern ourselves with anything but the first shipment. For the first month or so, we’re going to gather the requirements for the project. We’ll skip through a meadow, plucking them off of the beautiful flora and placing them in our baskets. That’ll be a good month. At the end of that month, we’ll tell our users that they’d better be sure that our endless array of diagrams and thousands of statements about what the software “shall” do matches exactly what they want because once we move onto the next phase, there’s no going back or changing their minds without either expensive change requests or lawyers.

Next up comes the design phase. This is the part where we spend a month figuring out how to write all of the code that we’re going to write over the next several months, but without actually writing that code. While this may sound nuts, the reason that we have to do this is because the labor is going to be divided up in such a way that everyone will kind of go off into their own silo and write code for months prior to an extended “integration phase” where our architect, Dr. Frankenstein, assembles the various individually created pieces into a reasonable attempt at a piece of software and then attempts to breath life into it. In order for that task to be as minimally gruesome as possible, a lot of planning is needed.

The next phase is implementation. Implementation phase is where we start coding and the previous two months of ‘work’ become completely irrelevant. Everyone codes in their silos until integration time. Some attempts are made at early integrations, but those are abandoned when it’s discovered that they are time consuming and the project managers are worried about the fact that they’re already behind schedule. Everyone will then pray that somehow we make up the time that we’ve gotten behind at integration time, but, who are we kidding? That’s not going to happen. The next phase will ideally be the testing phase, but we won’t have time for that. Instead, we’ll start the death march phase, where everyone works 14 hour days, 7 days a week up to the deadline.

Then, my friend, we ship. Tada! Ooh, that wasn’t supposed to happen. Heh, heh, weird. I’m sure the rest of it will be fine if I just — ooh, yikes. What do you mean this screen doesn’t look at all like what you were picturing? Heh, heh, maybe we can reschedule this demo. This is the phase where the thing we chucked over the wall, behind schedule and with a minimum of testing, blows up in our faces. After another month or so of death march following the release, we manage to wrangle the software into a state where, while the source code looks hideous, it’s at least stable and no one is screaming at us anymore.

There, doesn’t that sound better than the one where you’re shipping software every two weeks and not working 90 hour weeks to make up for the fact that you’re not actually very good at predicting the future? But of course, I kid. It was just an interesting exercise for me to think of how the world would seem going from agile to waterfall. Agile methodologies are inherently developer-centric when done correctly. Developers like quick feedback, routine shipments, and process automation because this makes for sustainable, incremental progress. The main complaining I hear from waterfall developers isn’t that agile doesn’t sound good — it’s that it sounds too good to be true. Usually it’s things like “we couldn’t do agile because we’re a shop that does _______” where the blank is some excuse that isn’t actually reasonable unless the company is shipping Mars Rovers. So if you’re already doing agile — you’ve already seen how well it works — going back would seem certifiably crazy. And, you know what? I like that there’s a generation of developers out there that think Waterfall is just a bed time story that the old timers use to scare the newbies into behaving.

By

Basic Protections on Your Mobile Devices: A Stitch in Time

Today’s post is going to be one where I’ll regale you with a rather ridiculous tale of woe, relief, and redemption. And, it’s my hope that you can learn from my buffoonery just as I did, but without the part where you’re a buffoon.

It’s a story that starts out simply enough. I have a phone and a tablet, both of which are Android devices. With the last Android phone I had, I set up a pattern verification for login, but about a year ago, I got a new phone and never bothered. I also got a new tablet and never bothered with it, either. So, two devices, no security to prevent access to anyone who happens to find them, and no plan of action in case I lose them. My security is just me not losing them or having them stolen, which has actually historically gone pretty well. So, it always will, right? But wait, the plot dumbens.

Today, I went to the gym, which is what I do most days. I’m fortunate enough to have a gym in the same building as my office, and, due to the fact that the gym locker room is one of the weirdest and most annoying places on Earth, I typically have a process flow where I change in my office and go to the gym. So, I did that, leaving my office with my keys, wallet, and tablet in tow. I use the tablet to watch Pluralsight videos while I jog on the machines. After working out, I left the gym, changed in my office, got a bite to eat, and went home.

When I was ready to start thinking about bed earlier tonight, I noticed that I didn’t have my tablet in my gym bag or my laptop bag that I’d brought home. Checked the car, and nope. Guess I left it at the office. Or the gym. Ruh roh. Nah, couldn’t be. I must have left it at the office. Just to make myself feel better, I called the gym, and they told me that they hadn’t seen it. Good, must be in my office. Or… crap. I realize that I’m not going to be able to sleep without solving this mystery, since my tablet has no security and is synced up with all kinds of stuff that I don’t want people accessing. Why, oh why, didn’t I secure the tablet? Oh well, I’ll just drive the half hour to my office, see it on my desk, and feel better. Grumble, grumble.

I get to my office, half an hour later, and have trouble with my keycard for some reason. Luckily, the night custodian knows me and was there to let me in (the fact that the night custodian knows me means that I should probably think about scaling back my hours). I go upstairs, unlock the door to my office and there on my desk is… no tablet. It’s also not in any of my chairs, bookshelves or other places in there that I might have tossed it. It’s almost midnight, I’m back at work, and someone has taken my tablet. I start googling, and fast. I found this site, called Android Device Manager, which is pretty awesome. It lets you see where any of your devices are and, if you’ve set it up, it lets you lock or wipe them remotely. Too bad I hadn’t set it up. The only option I have is to send a loud, five minute “ring” to the tablet, but this app can’t locate the thing anyway, so nevermind.

I also found this “Android Lost” site along with a companion “Jump Start” app that you can use in tandem to remote install something that allows you to wipe the device. Whoah, seems ripe for abuse, but whatever, I’m desperate. No go, however, because it can’t seem to locate the tablet on wifi anywhere and I had already in a panic changed my google password and disabled twitter. Not much, but it was a start. But, it also seemed like it would now prevent me from engaging this option since my google store credentials were different. Oh well, I’d change my google password back. But, I discovered I couldn’t, unless this dude on the internet was to be believed and google caches exactly 110 old passwords before it lets you roll them back over. I can picture him laughing once every evening at each sucker that stumbles on that link and spends 45 minutes changing google passwords 110 times.

I was screwed. I sent one last “ring” signal to my lost tablet, locked my office, and wandered down toward the gym, which had closed at 11, to see if I could hear the thing or something, notwithstanding the apparent lack of wifi connection. When I got there, I couldn’t hear any joyous tablet noises, but the door was open for some reason, so I just went in. I was alone except the usual bad gym music that’s always blaring — something about a drum that, mercilessly and cruelly to the ears of anyone not in love with autotune, “won’t stop beating.” Given my despondence and general distaste for gym-garbage-pop, I so desperately wanted it to stop beating for just a second. Nonetheless, I wandered over to the elliptical that I had used and there, lo and behold, was the tablet, exactly where I’d forgotten to collect it when I was hurrying out of the gym.

Wow am I lucky. I almost didn’t go back to work. I almost didn’t make it into the building because of a key malfunction. I have no idea why I was able to wander into the gym, unsupervised, over an hour after closing and just help myself to whatever was in there, but I was. And now I have it back, and all it cost me was having to change my Google password and my Outlook password.

But I’ve learned my lesson. Phone and tablet now require a pattern swipe to sign in. And both devices are completely configured for remote wipe via the Android Device Manager. If you’re on Android, set both of these things up right now, I beg you. It will take you literally 20 seconds if you have your phone and a browser with you. If you have iThings or Microsoft stuff, I’m sure there’s some equivalent that you can find. It’s oh-so worth it, and you won’t realize it until you’re hit with that sinking feeling. Do yourself a favor, and avoid the late night drives and scrambles to change passwords and whatnot. If you go this route, you’ll just be kicking yourself for losing a few hundred bucks and not wondering what horrible things “you” will have broadcast over email, text message, and every social media platform on Earth by the time the dust settles.

By

Notes on Writing Discoverable Framework Code

A while back, I found myself plugged into working on a rather large .NET project. The project had been going on for a while, and I was helping out only in terms of implementation manpower; architectural decisions had long since been made. And, in fact, some of the architectural decisions had pre-dated the project altogether. There was a “framework” that these guys were using for the purpose of rapid implementations. The idea was that developers could sort of slap this framework into place and make a few tweaks to have new applications rather than having to take more time to write the code. This wasn’t especially effective, but that was the goal.

As I used (and kind of battled with) this framework, something bothered me about it that I couldn’t put my finger on at first. But as I worked with it, I started to figure it out. The framework wasn’t discoverable in the slightest and thus fought against its own goal of rapid ramp-up and development. I actually put a placeholder in my drafts folder all of those moons ago wherein I made notes about how to make a framework discoverable. I never wound up bothering to make suggestions for improvements to that framework since, luckily, it was the last time I had to use it. But I’m trying to reduce the number of unpublished drafts in my folder, so I figured I’d offer up the suggestions to the world at large so that maybe some of you reading can get some value out of them.

What Do You Mean, Discoverable?

In the last paragraph I used a word without defining it, so I’ll correct that here. To understand what I mean, ask yourself the question, “how do developers discover how to use code?” 10 years ago, the most common answer to that question would have been “read the documentation.” Ah, the bad old days. I remember doing some Linux kernel programming using a library called RTAI, and I had these binders full of documentation on the API. They described in detail what each of the hundreds of parameters for dozens of functions were and what they meant. You certainly couldn’t tell from the names of these things — they were abbreviated, cryptic, and unclear.

The API itself lent few obvious clues about how to use it, and documentation was necessary for understanding. This is an API that is not discoverable. Discoverability is the degree to which you can figure out how to use something simply by playing with and examining it. For instance, if some API had a method called “Connect_To_The_SQL_Server_Database_Using_The_Following_Connection_String(string connection_string)”, you’d be dealing with something highly discoverable; you know how to use this without doing anything but looking at the code.

Developers have a variety of strategies for discovering how to use code. Reading documentation is probably the most traditional and established method, and one with which most experienced developers are familiar. However, let’s be frank — it’s also kind of a bummer. When you’re coding, you just want to write code via experimentation, trial and error. Having to lug out a big binder and pore through it, parsing jargon-heavy text is definitely a fly in the ointment. And while I’ve seen a lot of people express the sentiment, “you have to fight through the burn or you’re not a real programmer,” the fact of the matter is that when something is drudgery, attention spans wander and productivity decreases. So while reading documentation is the most established way of discovering code, it’s also the least effective, typically.

By contrast, the most effective manner of code discovery is use. Developers start using an API in whatever way seems most intuitive to them, typically using tools like Intellisense or word completion. They have some class they’ve declared an instance of in their IDE and they type the variable name and then a period and then they see what the auto-completion tool gives them by way of options for methods. There are other ways for developers to discover APIs as well, such as reading the code when it’s available, pairing with the code’s author, discussing the code with others, etc. But by and large, discovery through experimentation and clarity of purpose is most effective.

So the important question for architects, API authors, and framework providers thus becomes “how do I make my stuff discoverable for the developers that will use it?” Here are some suggestions.

Favor composition over inheritance

Inheritance is one of the main facets of polymorphism and boy oh boy was it popular in the late 1990’s and early 2000’s, especially in Java-land. I recall working on and with inheritance hierarchies that were 10 deep before any useful functionality emerged. Inheritance was one of the best ways at the time to avoid code duplication, but we, as an industry, learned the ugly downside of this approach: confusing non-discoverability.

There is nothing quite like getting a bug report that your code isn’t working and then taking a look to see what went wrong. You look at the source control history and see no record of any change that would explain the bug. None of the classes that your class is using have changed. Is it a bug in the GUI technology or database driver or something? Nope. Turns out, someone checked in a change 3 levels above you in the inheritance hierarchy and suddenly your class behaves differently. /Sigh.

When you use composition (the practice where your class uses other classes or implements interfaces), this sort of mysterious behavior in your classes is eliminated. If your class’s behavior has changed and you haven’t changed it, you know that one of the things that you’re using must have been changed. Eliminating or minimizing inheritance gets rid of a source of confusing possible changes.

Favor few parameters over many

This is relatively straightforward, but avoid using a lot of parameters with your methods. The fewer the parameters, the fewer the amount of things that callers of your methods have to understand and remember. This is a “Golden Rule” kind of situation. When you find the method you want to use by name, but it takes 12 arguments, do you think to yourself, “perfect — just what I want!” or do you think to yourself, “ugh, why me?” Well, users of your API/framework are no different. Consolidate the parameters you require into objects if need be — this will still be easier to understand for clients of your work.

Be judicious with overload methods

Method overloads are a powerful tool, but use them sparingly. It’s nice to offer your clients options, but it’s easy to offer them too many options. Applying the “golden rule” concept from the previous section, imagine if your code autocomplete tool shows you the method that you want, but there are 20 different parameter lists. Ugh. Which one to use? This isn’t discoverable anymore because you’re going to start googling or reading documentation or something. If there’s only one option, you’re simply going to use it and move on.

Favor early binding over late binding

One of the nastiest facets of the framework that I mentioned in the introductory section of the post was rampant late binding. Late binding is a scheme where relationships are resolved at run time rather than compile time. A common example of late binding would be a scheme that uses reflection to resolve names of fields in code to strings and to sync them with values on a form. So, if you have a Customer object with a “Name” property, you use reflection to get the string “Name” and look for a matching string on the form to which to write that value. Contrast this with a scheme where you simply have a strongly typed form object and you assign a value to its “Name” property. In the former scheme, mis-typing the property name results in a confusing runtime exception whereas in the latter scenario, the code won’t compile.

Programmers understand non-compiling. It’s one of the first feedback schemes you learn with a new language and you’ll very quickly understand why the compiler complains at you. So when something doesn’t compile, it’s quick and easy to figure this out and fix it. But if something fails weirdly at runtime as with a late binding scheme, it becomes hard to figure out what’s wrong. And, more importantly, it’s very frustrating. Part of discoverability is that it’s easy to understand why the right things work and the wrong things don’t. Late binding makes this understanding far more difficult for people working with the code.

Fail as early as possible

Very closely related is the concept of failing fast and early. An important concept for programmers is a tight feedback loop — a minimum of time between when you take an action and see the result of that action. A framework that creates negligible lapses between action and reaction is a discoverable one because users can quickly understand what works and what doesn’t. If there’s a lag between action and reaction, things are harder to figure out. This is a big problem with late binding, but it would also apply to a framework that’s slow running or slow to build as well.

Make screwing up impossible

Perhaps most important to discoverability is to make screwing up as hard as possible. Have clients of your code “fall into the pit of success.” This means taking whatever steps are possible to disallow doing the wrong thing. If a class Car in your framework requires an Engine in order to work, force people using your framework to pass Engine to Car’s constructor so that if they don’t, the code won’t compile. If they pass null, throw an exception. Contrast this with a behavior where the code makes passing in an engine optional and simply limps along and maybe throws a null reference exception somewhere if it’s missing. The latter approach is confusing — you’re communicating through your API that the Engine isn’t needed, and yet you’re failing everywhere it’s not present. You’re creating a minefield for your users rather than a pit of success, and consequently making your stuff really non-discoverable.

By

Programmers, Teach Non-Geeks The True Cost of Interruptions

Interruptions are one of the biggest sources of inefficiency for programmers. Now, to be fair, they’re probably a big source of inefficiency for everyone, but relatively speaking, they’re worse for programmers. To understand what I mean, let’s take someone whose job is in sales. A lot of the day is probably spent on the phone or in transit to and from meetings. In a given meeting or while reviewing notes prior to a meeting, an interruption to a sales person means time spent dealing with the interruption, a shake of the head, and a “where was I… oh, right.” For a manager, the day is often just a series of never-ending interruptions. In a management capacity, I find it common to sit down at lunch, still not having done the first thing I planned to do that day. Paul Graham has an excellent article about the different natures of the day for managers and for people he calls “makers,” a group that clearly includes programmers.

For a programmer, an interruption is oh-so different. There you sit, 12 calls into the call stack. On one monitor is a carefully picked set of inputs to a complex form that was responsible for generating the issue and on the other monitor is the comforting dark theme of your IDE, with the current line in the debugger glowing an angry yellow. You’ve been building to this moment for 50 minutes — you finally typed in the right inputs, understood the sequence in which the events had been fired, and got past the exact right number of foreach and while loops that took a few minutes each to process, and set your breakpoint before the exception was triggered, whipping you into some handler on the complete other end of the code base. Right now, at this exact moment, you understand why there are 22 items in the Orders collection, you know what the exact value of _underbilledCustomerCount is and you’ve hastily scribbled down the string “8xZ204330Kd” because that was the auto-generated confirmation code resulting from some combination of random numbers and GUIDs that you don’t understand and don’t want to understand because you just need to know what it is. This is the moment where you’re completely amped up because you’re about to unlock the mysteries of what on earth could be triggering a null reference exception in this third party library call that you’re pretty sure —

“HI!!! How’s it going? So, listen, you know that customer order crashing thing is, like, bad, right? Any chance I can get an ETA on having that fixed?”

Interrupted

DAMNIT!!!!

The project manager just startled you while you were getting ready to hit the next instruction and you hit “step over” instead of “step into!” He’s droning on and on about the importance of himself or the customer or something that you’re not listening to because you’re trying to control your rage at having lost all of your debugging context while also starting to think ahead to how you can get back to the point you were at in maybe 30 minutes instead of 50. But it’s no use. PM’s boss sees PM talking to you, walks over, and now there’s a full-blown discussion about the Initrode account going on next to your desk, loudly, complete with ridiculous buzzword BS bingo and sports metaphors about “closing out the game in the endzone” or something. By the time the dust settles and you’ve been Six-Sigma-ed into submission by 3rd degree black belts, you know that you’re going to be ordering a pizza and doing this again at 7 PM after everyone else leaves so that you can have some peace and quiet to work. All you can do is shake your head in sad disgust and wonder, “what on earth does 8xZ204330Kd mean and why did I write that down?”

But here’s the real insult-to-injury moment. When you try to explain to the PM how insanely destructive to your productivity that interaction was, he snorts at you and tells you not to be so melodramatic. He wanders off, wondering why programmers are such overdramatic prima donnas. Your non-techie peers just don’t get it, no matter how many times you try to make them understand. When part of your job is walking around all day demanding status updates and having the same demanded of you, it’s easy not to understand how different the programmer’s work paradigm is. I’ve been on both sides of it, and now that I spend a good portion of my day doing planning and overhead activities, I have to fight the impulse to drop by the area where my team sits and interrupt them regularly to get a piece of information so that I can put it in some email or add it to a list of resolved issues. PMs, managers, etc. all have real problems, many of which involve attempting to provide timely support to partners, clients, or internal staff, and issues and problems are interruptive, by their very nature.

Well, worry not, because I think I have a way that you can actually demonstrate to them just how devastating interruptions are to your productivity compared to, say, theirs. In other words, here’s how to make someone understand that, for you, an interruption isn’t just a delay after which you can get right back to work but a complete total of your efforts up to that point. Here’s how.

Invite the PM/manager/sales/whatever person to sit at his desk and tell him to humor you. Open up notepad and type a series of 3 or 4 digit numbers in sequence, like so:

123
234
345
543
432
321
999
888
777

Now, tell him to add those numbers in his head. He can look at the screen and talk/whisper/mutter to himself, but he can’t write anything down and he can’t type anything. He may laugh. Tell him that you bet him lunch he can’t get it done in five minutes, only getting one shot at getting the answer right. Maybe he’ll stop laughing and get to work.

Sit down, curl your hands behind your head and give him half a minute or so. Listen to him muttering. Then, get out your cell phone and call his office line. If he ignores it, ask him if he’s planning to answer it, since it could be important. He’ll grunt and mumble something about having to start over.

Give him another 30 seconds or so and say, “So, harder than you thought, huh? Which number are you on? You know which number always gets me? 333. Something about that number. Or maybe it’s 221. Or anything that adds to 9,365. Numbers, amirite! Oh, crap, sorry, you were concentrating. I’ll be quiet.”

Give him a minute. Pull out your phone and start talking loudly to no one on the other end, simulating a call. Start reciting imaginary phone numbers. Look sheepish and apologize.

Give him another minute. Blurt out that you’re low on work today, and ask him if he still wants you to add those three things about the four or five other things to six or seven of the upcoming performance presentation slides, and, oh, geez, numbers again, your bad.

Give him yet another minute. Then tell him that he’s only got 20 seconds left. Or is it 30? Maybe 25. Whatever the case may be, he’s getting into crunch time. Oh well, you guess he failed. Thank him in advance for lunch, but offer to let him keep his lunch money if he promises to stop constantly doing what you just did to him while you’re trying to code, which is a lot like keeping track of numbers all day in your head.

By

Intro to Unit Testing 9: Tips and Tricks

This, I’ve decided, is going to be the penultimate post in this series. I had originally targeted a 9 part series, finishing up with a “tips and tricks” post, the way you often see with technical books. But I think I’m going to add a 10th post to the series where I make the business case for unit testing. That seems like a more compelling wrap up to the series. So, stay tuned for one more after this.

This post is going to be a collection of tips and tricks for new and veteran unit testers.

Structure the test names for readability beyond just descriptive names.

The first step in making your unit tests true representation of business statements is to give them nice, descriptive names. Some people do this with “given, when, then” verbiage and others are simply verbose and descriptive. I like mine to read like conversational statements, and this creates almost comically long names like “GetCustomerAddress_Returns_Null_When_Customer_Is_Partially_Registered.” I’ve been given flack for things like this during my career and you might get some as well, but, do you know what? No one is ever going to ask you what this test is checking. And if it fails, no one is ever going to say “I wonder why the unit test suite is failing.” They’re going to know that it’s failing because GetCustomerAddress is returning something other than null for a partially registered customer.

When you’re writing unit tests, it’s easy to gloss over names of the tests the way you might with methods in your production code. And, while I would never advocate glossing over naming anywhere, you especially don’t want to do it with unit tests because unit test names are going to wind up in a report generated by your build machine or your IDE where as production methods won’t unless you’re using a static analysis tool with reporting, like NDepend.

But it goes beyond simply giving tests descriptive names. Come up with a good scheme for having your tests be as readable as possible in these reports. This is a scheme from Phil Haack that makes a lot of sense.
I adopted a variant of it after reading the post, and have been using it to eliminate duplication in the names of my unit tests. This consideration of where the test names will be read, how, and by whom is important. I’m not being more specific here simply because how you do this exactly will depend on your language, IDE, testing framework, build technology etc. But the message is the same regardless: make sure that you name your tests in such a way to maximize the value for those who are reading reports of the test names and results.

Create an instance field or property called “Target”

This one took a while to grow on me, but it eventually did and it did big time. Take a look at the code below, originally from a series I did on TDD:

If you look at the nested test class corresponding to the BowlFrame method, you’ll notice that I have a class level property called Target and that I have a method called “BeforeEachTest” that runs at the start of each test and instantiates Target. I used to be more of a purist in wanting all unit test methods to be completely and utterly self-contained, but after a while, I couldn’t deny the readability of this approach.

Using “Target” cuts out at least one line of pointless (and repetitive) instantiation inside each test and it also unifies the naming of the thing you’re testing. In other words, throughout the entire test class, interaction with the class under test is extremely obvious. Another ancillary benefit to this approach is that if you need to change the instantiation logic by, say, adding a constructor parameter, you do it one place only and you don’t have to go limping all over your test class, doing it everywhere.

I highly recommend that you consider adopting this convention for your tests.

Use the test initialize (and tear-down) for intuitive naming and semantics.

Along these same lines, I recommend giving some consideration to test initialization and tear-down, if necessary. I name these methods BeforeEachTest and AfterEachTest for the sake of clarity. In the previous section, I talked about this for instantiating target, but this is also a good place to instantiate other common dependencies such as mock objects or to build friendly instances that you pass to constructors and methods.

This approach also creates a unified and symmetric feel in your test classes and that kind of predictability tends to be invaluable. People often debug production code, but are far more likely to initially contemplate unit tests by inspecting them, so predictability here is as important as it is anywhere.

Keep Your Mind on AAA

AAA. “Arrange, Act, Assert.” Think of your unit tests in these terms at all times and you’ll do well (I once referred to this as “setup, poke, verify.“). The basic anatomy of a unit test is that you setup the world that you’re testing to exist in some situation that matters to you, then you do something, then you verify that what you did produced the result you expect. A real world equivalent might be that you put a metal rod in the freezer for 2 hours (arrange), take it out and stick your tongue on it (act), and verify that you can’t remove your tongue from it (assert).

If you don’t think of your tests this way, they tend to meander a lot. You’ll do things like run through lists of arguments checking for exceptions or calling a rambling series of methods to make sure “nothing bad happens.” This is the unit test equivalent of babbling, and you don’t want to do that. Each test should have some specific, detailed arrangement, some easily describable action, and some clear assertion.

Keep your instantiation logic in one place

In a previous section, I suggested using the test runner’s initialize method to do this, but the important thing is that you do it, somehow. I have lived the pain of having to do find and replace or other, more manual corrections when modifying constructors for classes that I was instantiating in every unit test for dozens or even hundreds of tests.

Your unit test code is no different than production code in that duplication is your enemy. If you’re instantiating your class under test again and again and again, you’re going to suffer when you need to change the instantiation logic or else you’re going to avoid changing it to avoid suffering, and altering your design to make copy and paste programming less painful is like treating an infected cut by drinking alcohol until you black out and forget about your infected cut.

Don’t be exhaustive (you don’t need to test all inputs — just interesting ones)

One thing I’ve seen occasionally with people new to unit testing and especially getting their heads around TDD is a desire to start exhaustively unit testing for all inputs. For instance, let’s say you’re implementing a prime number finder as I described in my Pluralsight course on NCrunch and continuous testing. At what point have you written enough tests for prime finder? Is it when you’ve tested all inputs, 1 through 10? 1 through 100? All 32 bit integers?

I strongly advise against the desire to do any of these things or even to write some test that iterates through a series of values in a loop testing for them. Instead, write as many tests as you need to tease out the algorithm if you’re following TDD and, in the end, have as many tests as you need to cover interesting cases that you can think of. For me, off the top (TDD notwithstanding), I might pick a handful of primes to test and a handful of composite numbers. So, maybe one small prime and composite and one large one of each that I looked up on the internet somewhere. There are other interesting values as well, such as negative numbers, one, and zero. I’d make sure it behaved correctly for each of these cases and then move on.

It might take some practice to fight the feeling that this is insufficient coverage, but you have to think less in terms of the set of all possible inputs and more in terms of the set of paths through your code. Test out corner cases, oddball conditions, potential “off by one” situations, and maybe one or two standard sorts of inputs. And remember, if later some kind of bug or deficiency is discovered, you can always add more test cases to your test suite. Your test suite is an asset, but it’s also code that must be maintained. Don’t overdo it — test as much as necessary to make your intentions clear and guard against regressions, but not more than is needed.

Use a continuous testing tool like NCrunch

If you want to see just how powerful a continuous testing tool is, check out that Pluralsight video I did. Continuous testing is game changer. If you aren’t familiar with continuous testing, you can read about it at the NCrunch website. The gist of it is that you get live, real-time feedback as to whether your unit tests are passing as you type.

Let that sink in for a minute: no running a unit test runner, no executing the tests in the IDE, and not even any building of the code. As you type, from one character to the next, the unit tests execute constantly and give you instantaneous feedback as to whether you’re breaking things or not. So, if you wander into your production code and delete a line, you should expect that you’ll suddenly see red on your screen because you’re breaking things (assuming you don’t have useless lines of code).

I cannot overstate how much this will improve your efficiency. You will never go back once you get used to this.

Unit Tests Instead of the Console

Use unit tests instead of the console or whatever else you might use to do experimentation (get comfortable with the format of the tests). Most developers have some quick way of doing experiments — scratchpads, if you will. If you make yours a unit test project, you’ll get used to having unit tests as your primary feedback mechanism.

In the simplest sense, this is practice with the unit test paradigm, and that never hurts. In a more philosophical sense, you’re starting to think of your code as a series of entry points that you can use for inspection and determining how things interact. And that’s the real, longer term value — an understanding that good design involves seams in the code and unit tests let you access those seems.

Get familiar with all of the keyboard shortcuts

Again, this is going to vary based on your environment, but make sure to learn whatever keyboard shortcuts and things your IDE offers to speed up test management and execution. The faster you are with the tests, the more frequently you’ll execute them, the more you’ll rely on them, and the more you’ll practice with them.

Your unit test suite should be a handy, well-worn tool and a comfortable safety blanket. It should feel right and be convenient and accessible. So anything you can do to wear it in, so to speak, will expedite this feeling. Take the time to learn these shortcuts and practice them — you won’t regret it. Even if you have a continuous testing tool, you can benefit from learning the most efficient way to use it. Improvement is always possible.

General Advice

Cliche as it may sound and be, the best tip I can give you overall is to practice, practice, practice. Testing will be annoying and awkward at first, but it will become increasingly second nature as you practice. I know that it can be hard to get into or easy to leave by the wayside when the chips are down and you’re starting at a deadline, but the practice will mitigate both considerations. You’ll grow less frustrated and watch the barriers to entry get lower and, as you get good, you won’t feel any inclination to stop unit testing when the stakes are high. In fact, with enough practice, that’s when you’ll feel it’s most important. You will get there with enough effort — I promise.

By

Uber-Architects: The Building Metaphor Is Dead

Building Bad Software is Like Building a Tower

A little over a year ago, I wrote a post explaining how you can use the metaphor, “building software is like building a tower” to help you write bad software. The idea was that building something like a skyscraper requires insane amounts of planning because the actual act of building is laborious, time-consuming, and expensive, and also pretty much impossible to change once you get going. Furthermore, the real brains of the operation is required for the up-front planning, which is then done in such detail that the actual construction is a pretty straight-forward task that doesn’t require a whole lot of thinking — just following of detailed instructions and a practiced knack for skills like assembling plumbing, taping drywall joints, etc.

Software really only follows this pattern if it’s awful. If you were to describe a project you were working on by saying, “it’s important that we get everything right from the get-go because once we get started, this system is going to be so set and rigid that change is impossible,” wouldn’t you be a little alarmed and/or defeated? And what about the idea that the developer is so wildly different from the architect that they have two entirely separate vocational training paths (in the case of buildings, architectural studies versus carpentry trade school or apprenticeship). Is planning how to write software so very different than writing software?

I believe you’d be pretty hard pressed to continue to like this metaphor when you give it a lot of thought. But that hasn’t stopped the metaphor from being iconic in our industry, to the extent that it still vestigially governs roles, titles, career paths, and team behavior. Even though building software is nothing like structural construction, we continue to have a very real role/title called “Architect” that is responsible for coming up with documentation that looks suspiciously like a set of blueprints so that the lower paygrade laborers can toil away while he supervises.

Is this the best role and set of duties for the person called “architect” — the person on the team who has probably gotten to the position by being a good developer for a long time (or, more cynically, by being a mediocre and tenured Expert Beginner)? Should the result of spending years getting good at writing software be that you get to be in charge of the software by writing less of it? Are the architects of our buildings the people who are really, really good at pouring concrete and hanging drywall? Obviously not. And while we’re at it and this frayed metaphor is truly breaking down, should we even call them architects any more?

A Bit of Philosophy

I think that those of us who occupy the role or aspire to it should perhaps start striving to become post-architects or Uber-Architects. I’m borrowing this latter term from Friedrich Nietzsche, a philosopher and sporter of an awesome mustache that wrote about what he called the “Ubermensch,” which I believe translates from German to something along the lines of “over-man.” Nietzsche’s concepts in “Thus Spake Zathustra” are extremely nuanced and layered, but I’ll summarize what I took out of it when I read it and how I think it relates.

Nietzsche

You might know Nietzsche as the philosopher who famously said, “God is dead,” and he said that in this book. I believe that this is largely interpreted as a profoundly and stridently atheist sentiment, but that interpretation is one that ignores the context of the work and his other works. He was looking at a world (he lived in Europe during the 1800s) where morality had long been a matter simply dictated by the tenets of Christianity, but also in a world where the rejection of religion was becoming increasingly common. Nietzsche wasn’t gloating over the corpse of God; he was expressing worry that a growing atheist/agnostic segment of the population would opt for nihilism in the absence of any religion and that society would become dominated by what he called something like “last man,” a rather wretched creature interested only in its own comfort and with no direction or broader purpose. He was saying, “I don’t care for your religion, but if you take it away, I’m worried that things will get a lot worse.”

From Nietzsche’s perspective, 19th century Europe was in trouble and the path forward was for mankind to become the “Ubermensch,” a version of man that was capable of supplying himself with all of the things for which religion had previously been responsible. Basically, he should do good in life because it’s good to do good rather than because he’ll be in trouble if he doesn’t. He should define his own purpose and leave his mark on the world because it’s the right thing to do and the highest calling for an individual would be to leave a mark on history for the better. In the absence of the previous and declining moral order, a new, sustainable one had to be defined, so his argument went (or at least my recollection of my reading and understanding of it).

Forget the religious angle here in a discussion of software. I’m not interested in discussing the merits of Nietzsche’s religious beliefs or lack thereof here. But I am interested in relating his perception of the world to our situation. Throughout the history of software development, our roles have been defined by this now flagging and failing metaphor of “software is like building a tower.” We’ve mimicked construction in our historical approach with lengthy and detailed planning along with the division of labor. We’ve gone so far as to borrow the titles for the roles in that line of work and appropriate them for ourselves. Your software group has to have an “architect” that will make the “blueprints” for the software. But that’s absurd and people are starting to realize it (see the growth of agile methodologies that have no equivalent at all in the construction world).

The danger then becomes what happens in the absence of that metaphor. Do we adopt improvident and cavalier approaches to software architecture, swinging the other way on the “lots of planning versus no planning” pendulum? Do we abolish the role of any kind of technical leader and make all software development groups pure democracy? Do the former architects or developers in general become “last architects,” just nihilistically banging out whatever code seems interesting or gets them out the door at 5 without worrying over the future or the needs of the business?

Emergence of the Uber-Architect

This is where the Uber-Architect comes in. The Uber-Architect deals not in blueprints and orders from on high but from leadership by example in the trenches. Uber-Architecture isn’t about web services, database technologies, N-Tiers or enterprises, but about teaching and demonstrating important fundamental concepts of the craft: abstractions, design trade-offs, and implementation patterns. Uber-Architects don’t create a bunch of rules and enforce them across large organizations for consistency’s sake, like a foreman with a clipboard overseeing hundreds of fungible laborers. They pick up the hammers and nails and work along side those workers, showing them how it’s done, building the thing together, and making those around them better until it is no longer a fungible collection of workers, but a humming, autonomous machine that’s more than the sum of its parts. They leave their mark on the group not because they’re “architect” but because it’s the right thing to do, and it’s something of which they can be proud.

So what do teams look like when all of this comes to pass? I don’t know, exactly. But I think we’re finding out. I think that we’re going to see more and more teams with flatter structures, less worried about seniority, and more buying into the agile concept of self-organizing teams. And on those teams, there is no architect because people doing a good job of building software won’t assemble into organizational structures that are ill suited to building software. On these teams, there will only be Uber-Architects, who don’t hold a position afforded to them by 15 years in with the company, but who hold a place of respect among their peers due to ability and vision, and who create design concepts that make the lives of those around them easier and the skills of those around them sharper.

If this sounds overly idealistic, perhaps it is, but that’s because I view it as a goal and something to start reaching toward. And besides, with all of the cynical posts I make about Expert Beginners and overrated people and whatnot, some starry-eyed optimism probably balances out the cosmic scales a bit.

By

You Should Subscribe to Tech Podcasts

For the first post of 2014, I thought I’d make it a quick one, largely due to the fact that I haven’t had a lot of time to catch my breath over the last few weeks and am thus short on posts in my drafts. A while back, I wrote a post about multi-tasking where I described that I listen to podcasts on the drive to and from work each day. I thought I’d list some podcasts that you might want to check out. I find them valuable, anyway.

I have an app on my phone called Doggcatcher (I think it might be Android only). It’s great for organizing podcasts to which you want to subscribe and playing them as if you were listening to a radio show. With the bluetooth setup in my car, this turns out to be perfect: one ends, and the next one automatically starts without me intervening. New episodes download automatically and listened-to ones vanish automatically from your phone’s drive. Here is my list:

  1. .NET Rocks, a frequently released, professionally done show about all things .NET.
  2. Hanselminutes, a weekly technology talk show with Scott Hanselman
  3. This Developer’s Life, a sporadic personal evaluation of software developers’ lives (Rob Conery and Scott Hanselman)
  4. Polymorphic Podcast is a developer podcast from Craig Shoemaker (I don’t think it’s made anymore, but it was really good when it was, and I’m hoping it comes back)
  5. Herding Code, a group of prominent technologists conduct interviews with people doing cool things in the industry.
  6. The Java Posse, a show about all things Java, that helps me from getting too .NET-centric these days.
  7. The Stack Exchange Podcast will be familiar if you participate in the stack exchange Q&A sites.
  8. Deep Fried Bytes is another tech podcast, “with a southern flavor” (though I don’t personally consider that to be a draw, per se — it’s an interesting show on its own).
  9. Yet Another Podcast, the one I deliberately saved for last due to its name.  This is a last, but not least situation — definitely interesting.

I also listen to the Freakonomics podcast, due to a mild obsession with incentives and outcomes that I’ve had for the last couple of years, but I omitted that from the general theme of developer podcasts.

If you’re a developer and interested in improving your craft, I’d highly recommend subscribing to some podcasts.  This is an excellent array of them with lots of good information, in my opinion.  Perhaps there are others that you’d prefer, however.  Just find some and listen.

Podcasts are a great way to passively assimilate information.  You don’t need to concentrate heavily or even pay attention all the way through, though it’s certainly preferable.  These podcasts touch lightly on a wide variety of topics and the end-result is that they’ll make you vaguely aware of a lot of things that could be useful.  You’re not going to come away from your morning commute suddenly fluent in a new programming language, but when your peers are talking about writing a distributed, publish/subscribe utility that can dictate message routes, you can think to yourself, “I’m pretty sure something like that exists…. and that they talked about it on one my my podcasts… let me go google it.”  In fact, over the years that I’ve kept up with podcasts, I can’t tell you how many wheels I’ve avoided re-inventing.

So, go get yourself a podcast app if that’s your thing.  Or if not, just visit the sites periodically for new episodes.  Whatever approach you take, turn yourself on to this pasive way of keeping current with the industry that you can keep up with during life’s natural downtime.  I’m pretty sure you won’t regret it.

Acknowledgements | Contact | About | Social Media