Testable Logs

Aug 12, 2020

Every week in my Tuesday Lunch & Learn livestream, we choose a useful software development skill, define a challenge related to that skill, and solve the challenge live. This week, we’re building a testable logger.

The Log class we’re building this week is high-level infrastructure. High-level infrastructure is just like normal infrastructure, except that it uses code we’ve already written rather than talking to the outside world directly. So for today’s episode, we’re tying together a lot of the concepts from previous episodes. We end up with a lovely utility that makes testing logging a breeze.

To follow along, download the code from GitHub and check out the 2020-08-11 tag. To see the final result, check out the 2020-08-11-end tag or view it on GitHub.

Visit the Lunch & Learn archive for more.

Coming Soon!

Aug 10, 2020

Book cover for “The Art of Agile Development, Second Edition” by James Shore and Shane Warden. Published by O'Reilly. The cover has a large sticker on it that says “Early Release: Raw and Unedited.” The cover artwork shows a water glass containing a small sapling. The sapling has small green leaves. There is a goldfish in the glass.

Keep an eye on my RSS feed or the #aoad2 tag on Twitter for more announcements soon!

Nullable Output

Aug 5, 2020

Every week in my Tuesday Lunch & Learn livestream, we choose a useful software development skill, define a challenge related to that skill, and solve the challenge live. This week, it’s nullable output.

In previous episodes, we’ve talked about the Nullable Infrastructure Wrapper pattern. It’s a way of testing infrastructure code without using mocks. This is valuable because it allows us to write unit tests that don’t need backup integration tests.

Nullable Infrastructure Wrappers work by “turning off” their connection to the outside world. So how do you test code that sends data? For example, if you make a call to a microservice, or write output to stdout? One way is to store the last output, but that only tells us the last thing that was sent. What if we need to test multiple writes? In today’s episode, we solve this problem.

To follow along, download the code from GitHub and check out the 2020-08-04 tag. To see the final result, check out the 2020-08-04-end tag or view it on GitHub.

Visit the Lunch & Learn archive for more.

“Best Agile Articles” Compilation

Aug 5, 2020

One of my essays has been included in the 2019 “Best Agile Articles” compilation. I’m honored to be included.

This volunteer-produced compilation is available for free. Some links:

Enjoy!

Idiot-Proof APIs

Jul 29, 2020

Every week in my Tuesday Lunch & Learn livestream, we choose a useful software development skill, define a challenge related to that skill, and solve the challenge live. This week, we’re looking at how to program idiot-proof APIs.

We’re all idiots at times, of course. “Idiot-proof” really means writing your APIs so that they’re easy to use correctly and difficult to use incorrectly. When somebody uses your API, will they understand how it works? Will they be guided away from obvious mistakes? In today’s episode, we look at four techniques for making your APIs easier to understand and use correctly.

To follow along, download the code from GitHub and check out the 2020-07-28 tag. To see the final result, check out the 2020-07-28-end tag or view it on GitHub.

Visit the Lunch & Learn archive for more.

Colophon

Jul 22, 2020

Every so often, I describe what I do to make this site a reality. For the four of you who like to watch me gaze at my navel, I have good news: today is one of those days. For the rest of you, I’m sorry. It’s one of those days. You can move on. I won’t be offended.

Okay, here goes.

Production

I use a 13” MacBook Pro with a large external monitor to compose all of my essays. Years ago, my Windows laptop died and I decided to see if life was better on the other side. I’ve come to like MacOS, after some initial frustrations, and now I have a hard time imagining going back.

I write my essays in hand-crafted HTML using Webstorm. The files are served using a custom content management engine (CME) I originally wrote for my Let’s Code JavaScript screencast. It’s a polyglot engine, so I could theoretically use other markup languages, such as Pug, Markdown, or AsciiDoc, but I’m used to HTML and I haven’t bothered setting up the alternatives yet.

Everything required to make the site go, including all the content, are stored as static files in a git repository. I run my CME locally for testing, then commit and deploy to my web host when I’m ready to go live.

I’m paranoid about backups and revision control. There’s decades of work here. That’s why all of my essays are written in a text editor and stored in git. Most blogging engines save your work in the cloud. Easy, but not fault tolerant. I’ve been writing for nearly two decades and plan to continue writing for several more. My stuff has to be easily scripted, version-controlled, backed up, and trivial to deploy to another web host when (not if) my host goes under... which it already has. Twice.

My site is backed up many times over. First, in the git repo on my laptop. Second, in a copy of the git repo on my web host. The computer itself is backed up to two redundant drives with Time Machine every hour. I also make a bootable whole-disk backup using SuperDuper!. Every quarter, I rotate one of the backup drives to an off-site location.

Design

The site was originally designed in 2004 and it shows. Boy, does it show. But it’s functional and there always seems to be some other priority getting in the way of a redesign.

The biggest challenge for me in originally making the site was my complete lack of web design skills. (Software engineering, yes. Graphic design, no.) Sitepoint got me started and A List Apart carried me through. I borrowed liberally from Jeffrey Zeldman in creating the sidebar, as permitted by comments in his CSS.

For the color scheme, Jason Beaird’s "Color for Coders" article helped me get started and Visibone’s Color Laboratory allowed me to pick web-safe colors. (I don’t think we have to limit ourselves to 216 “web-safe” colors any more, but... did I mention the site was designed in 2004? I cheated a bit for quotes, though.)

I also took advantage of some royalty-free icons. The RSS feed icon (sample icon) came from Feed Icons; the Twitter icon (sample icon) is resized from an icon I got from Productivedreams.com; the print icon (sample icon) came from graphicPUSH; the star icon (sample icon) came from 1ClipArt; and the spinner (sample icon) came from Andrew Davidson.

Finally, lots of trial and error got me to the result I have today. W3Schools’ CSS Reference was invaluable for making it work, but these days I prefer MDN. Eric Meyer’s "Going to Print" article provided the finishing touch for my print stylesheet by showing me how to automatically insert URLs after printed links.

Hosting

The site is hosted by Heroku and runs on a custom content management engine written in Node.js. Logging is handled by Papertrail, which also sends me email and text message alerts when things go wrong. I use Pingdom as a backup alerting system. TierraNet makes sure that my domains point to the right place. Google handles my analytics. Sorry about that.

This combination of custom source code and outside services gives me total control over the code behind the site while outsourcing a lot of the complexities of modern software stacks. It’s a nice tradeoff that allows me to focus my attention on more important things. The code is very well tested, so it almost never fails. Because there’s no database—everything’s in static files—and minimal service dependencies, my uptime is the same as Heroku’s, and requires no effort from me.

History

In the very beginning, the site was rendered by a very simple static site generator I wrote in Ruby. But for 15 years, from February 2005 to July 2020, the site was rendered by the ultra-minimalistic Blosxom. That’s when I started blogging in earnest; you can see my very first entry here.

Back in the day, Blosxom was the only blogging software I could find that actually allowed me to store entries locally, in files that I could back up and put in version control, rather than on a database on the server. (Nowadays, of course, static site generators are a dime a dozen.) Blosxom ran on Perl 5. It did the job, but my volume of content caused performance problems, and it had a lot of idiosyncracies. It was low maintenance, but also constrained what I could do. I’m happy to finally be rid of that technical debt.

Colophonem adidi.

International Dates and Times

Jul 22, 2020

Every week in my Tuesday Lunch & Learn livestream, we choose a useful software development skill, define a challenge related to that skill, and solve the challenge live. This week, it’s international dates and times.

The challenge with international dates and times is that you want your users to see different results, depending on their local time zone and language. But your tests need to work consistently, regardless of the local time zone and language. In today’s episode, we write a simple application that displays the local time, and we do it in a way that continues to pass tests no matter who runs them.

To follow along, download the code from GitHub and check out the 2020-07-21 tag. To see the final result, check out the 2020-07-21-end tag or view it on GitHub.

Visit the Lunch & Learn archive for more.

No More Flaky Clock Tests

Jul 15, 2020

Every week in my Tuesday Lunch & Learn livestream, we choose a useful software development skill, define a challenge related to that skill, and solve the challenge live. This week, we’re preventing flaky clock tests.

There’s nothing more frustrating than flaky tests: tests that fail randomly. You end up having to run your test suite over and over to get a good result, even if there’s nothing wrong with your actual code. And code that involves time—that interacts with the system clock—are one of the most common cause of flaky tests.

In today’s episode, we kill flaky clock tests dead. If you use these techniques, you’ll never have another flaky clock test.

To follow along, download the code from GitHub and check out the 2020-07-14 tag. To see the final result, check out the 2020-07-14-end tag or view it on GitHub.

Visit the Lunch & Learn archive for more.

How to Fix a Bug

Jul 8, 2020

Every week in my Tuesday Lunch & Learn livestream, we choose a useful software development skill, define a challenge related to that skill, and solve the challenge live. This week, we’re fixing a bug.

There’s more to fixing bugs than, well, fixing bugs. In addition to finding and fixing the bug, you also have the opportunity to prevent additional bugs like this one from occurring in the future. How you do that depends on what kind of bug you have. That’s what we look at in this week’s episode.

To follow along, download the code from GitHub and check out the 2020-07-07 tag. To see the final result, check out the 2020-07-07-end tag or view it on GitHub.

Visit the Lunch & Learn archive for more.

How to Add a Feature (Cleanly)

Jul 1, 2020

Every week in my Tuesday Lunch & Learn livestream, we look at a useful software development skill, define a challenge related to that skill, and solve the challenge live. This week, we’re adding a feature.

That’s not as simple as it sounds. Whenever you’re working with code you’re not familiar with—and in professional software development, that happens pretty often—the code’s a black box. So the question becomes, where do we add the new feature we’re about to add?

One of the things that separates better code from not-so-better code is how much attention people put onto understanding the design of existing code. It’s tempting to just find the existing behavior, make the minimum change needed to get your new feature working, and call it good. But that leads to technical debt. How do we take this black box, understand where the feature we need to add should live, and then implement it really cleanly in a way that improves the design?

To follow along, download the code from GitHub and check out the 2020-06-30 tag. To see the final result, check out the 2020-06-30-end tag or view it on GitHub.

Visit the Lunch & Learn archive for more.

Microservices Without Mocks, Part 4: Code Whispering

Jun 24, 2020

Each week in my Tuesday Lunch & Learn livestream, we look at a useful software development skill, define a challenge related to that skill, and solve the challenge live. This week, in part 4 of our extended microservice example, we’re putting the final polish on our microservice.

Over the past several weeks (part 1, part 2, part 3), we’ve created a web server, sent responses, and read requests. This week, we need to implement routing. The infrastructure work is done, so our challenge is to design our routing code well. To do so, we’ll use a technique called (somewhat tongue-in-cheek) “code whispering.” As always, we’ll make sure it’s all thoroughly tested, and we won’t use mocks or broad integration tests.

To follow along, download the code from GitHub and check out the 2020-06-23 tag. To see the final result, check out the 2020-06-23-end tag or view it on GitHub.

Visit the Lunch & Learn archive for more.

Microservices Without Mocks, Part 3: Reliable Requests

Jun 16, 2020

Each week in my Tuesday Lunch & Learn livestream, we look at a useful technical skill, define a challenge related to that skill, and solve the challenge live. This week, in part 3 of our extended microservice example, we’re reading requests from the client.

Two weeks ago, we created the ability to start and stop a web server. Last week, we made it send responses. This week, we’re reading requests. When a request comes in, we need to read the request body, encode it using ROT-13, and serve the encoded result back to the client. As always, we’ll make sure it’s all thoroughly tested, and we won’t use mocks or broad integration tests.

To follow along, download the code from GitHub and check out the 2020-06-16 tag. To see the final result, check out the 2020-06-16-end tag or view it on GitHub.

Visit the Lunch & Learn archive for more.

Microservices Without Mocks, Part 2: Robust Responses

Jun 9, 2020

Each week in my Tuesday Lunch & Learn livestream, we look at a useful technical skill, define a challenge related to that skill, and solve the challenge live. This week, in part 2 of our extended microservice example, we’re making our server respond to requests.

Last week, we created the ability to start and stop a web server. This week, we’ll continue that effort by handling requests. When a request comes in, we need to output Request received to the command-line and serve a simple response. As always, we’ll make sure it’s all thoroughly tested, and we won’t use mocks or broad integration tests.

To follow along, download the code from GitHub and check out the 2020-06-09 tag. To see the final result, check out the 2020-06-09-end tag or view it on GitHub.

Visit the Lunch & Learn archive for more.

Microservices Without Mocks, Part 1: The Server

Jun 2, 2020

Each week in my Tuesday Lunch & Learn livestream, we look at a useful technical skill, define a challenge related to that skill, and solve the challenge live. This week, in part 1 of our extended microservice example, we’re building and testing a server without using mocks or broad integration tests.

In previous weeks, we’ve demonstrated infrastructure wrappers and testing without mocks. But those episodes all used toy examples. How do these ideas work when you’re writing complex, production-grade code?

In today’s episode, we start an extended example of applying these ideas to production-grade code. We’ll upgrade the simple ROT-13 command-line application from previous weeks into a real, production-grade microservice. Our first task is to build the server, start it, and make sure everything is thoroughly tested... without writing mocks or broad integration tests.

To follow along, download the code from GitHub and check out the 2020-06-02 tag. To see the final result, check out the 2020-06-02-end tag or view it on GitHub.

Visit the Lunch & Learn archive for more.

Testing Without Mocks

May 26, 2020

Each week in my Tuesday Lunch & Learn livestream, we look at a useful technical skill, define a challenge related to that skill, and solve the challenge live. This week, it’s testing without mocks.

Although mocks (and spies) are useful for testing interactions and isolating code, that isolation comes at a cost. Mocks can only check if dependencies’ methods are being called. They can’t check if they’re being called correctly. As a result, mock-based tests must be supplemented with integration tests, and these tests are slow and expensive. Wouldn’t it be nice if we could write unit tests that didn’t need additional integration testing?

Our challenge this week: given a simple command-line application, update the existing mock-based tests so they work without mocks, spies, or integration tests. The end result is surprisingly effective: tests that are more reliable than mock-based tests, faster, and easier to read.

To follow along, download the code from GitHub and check out the 2020-05-26 tag. To see the final result, check out the 2020-05-26-end tag or view it on GitHub.

For more details about testing with mocks, see the Testing Without Mocks Pattern Language.

Visit the Lunch & Learn archive for more.