Hey there! I'm Nat Bennett – writer, walker, software engineer – and you're reading Simpler Machines, a newsletter about making software.
The main thing I've got for ya'll this week is, of all things, a video. Earlier this week I recorded a pairing session with Caroline Taymor, where we started up a new project in Elixir, to build a tool for generating PDF invoices. The first half covers getting Elixir installed on a new machine and getting automated tests running on Github Actions, and then we start scaffolding out the project with our first few tests.
It's actually a pretty good little Elixir intro and demo, and shows off a few of the features that make me so excited about the language. It's also a pretty true-to-life rendering of what it "real" software engineering looks like on a day-to-day basis. (Spoiler: It's reading documentation and figuring out why stuff doesn't work.)
But the main reason I made this was to show what test-driven development actually looks like.
See, there's a reason that TDD & pairing go together. TDD is hard to learn on your own. Most of the people I know who are good at it have spent at least some time doing it with someone who already knows it. There are a lot of ways to write tests first that aren't "really" TDD, or at least aren't effective TDD, and without a guide it's easy to spend a bunch of time writing bad tests that just get in your way.
One I see a lot is folks who write all their tests up front, and then start writing code. Or who think that writing tests early in a project when you don't know how you're approaching the problem is stupid. (Often correct, incidentally – that's why there's a thing called a "spike.") Or who use mocks to diligently test every individual function of every class, and then discover that their tests interfere with refactoring. Or who think that TDD doesn't work in "real" code, because all they've ever seen are canned examples with simple problems.
And you know what? TDD often is taught with canned examples with simple problems. And I think that can make it hard to get a handle on the messy parts of TDD. How do you start a project, especially one where you're integrating with an external system and you don't know exactly how it works yet? Should you test everything your program does? If you don't write tests for everything, how do you decide what to test?
So I want to show off TDD on some more "realistic" projects.
I'm really interested in feedback on this one. If there's something in this video that you'd especially like to see more of, let me know. We cover a lot of ground – Elixir, a bunch of command-line and systems stuff, scaffolding and stubs, TDD-proper – and there are a bunch of different directions we could go with the next one. I'm also open to doing a different kind of project or another language if there's a particular kind of problem you'd really like to have live examples of for your team.
Pop Up Newsletter: A Walk Around the Bay
You can sign up now to the temporary daily newsletter I'll be sending for about a week starting February 20th, as I walk across the Golden Gate Bridge, and around the rest of the San Francisco Bay. I did one of these last year about a trip to Point Lobos and it was really fun – because the pop-up newsletters are only e-mail I can get a little weirder than I would for something that's hosted on the public internet forever