Make the change easy, then make the easy change.
I was pairing with a junior developer. I had setup a frame for working on an assigned task.
I had went into this session intending to be somewhat quiet; answering questions and asking questions when it looked like they might be a bit stuck.
When I began pairing, I noticed that they had put the frame inside an environment that had a large boot time. They were, quite reasonably, running the script inside a full Ruby on Rails (Rails 📖) context.
They had been working on their script and with each change would run the task, requiring a re-boot of the Rails environment. For this case, they did not need the entire Rails application logic.
So I shifted gears saying, “Let me help you set this up to get faster feedback.”
I had them add the explicit
require statements for the gem they needed.
They needed the venerable OAI gem 📖 and I set them up with a debugger.
They ran the script and the boot time dropped from what felt like forever to a hundred or so milliseconds.
With that change, I knew that they could more quickly iterate. And hopefully solve the task at hand.
Focus on Unblocking
My job, as a lead developer, is to help the team get unblocked. And sometimes folks don’t know when they are blocked. They don’t know what they don’t know. Or they might not know of other pathways or available automation.
For example, I would hope that most developers know and use a hotkey for copying and pasting content. I also hope that folks know about tools like Jumpcut or Raycast; both of which provide paste buffer history.
Emacs 📖 has the venerable
kill-ring for paste buffer history.
Or that you can find files in a project without using the mouse and click through the directory structure.
Not all of those things might stick with folks; but I have found that gently showing folks alternate approaches can help illuminate alternate pathways in their approaches.
And I consider slow feedback to be a blocker in software development.
In Take on Recursion Redux, I wrote about writing a few fast tests to sequence a simple dependency graph. Prior to starting that task, I didn’t know the how to write the code. Once I had a few fast to run tests, I could easily iterate, catch bugs, and move on to other things.
I structured Derivative::Rodeo 📖 to get fast feedback. The entire test suit takes 30 or so seconds. I think I’ll be able to continue to keep it short and quick because I’m trying to only test the time expensive things once; and after that test using mocks that conform to narrow interfaces.
In a past project, from years ago, the team and I agreed that for a new Rails project the test would be considered broken if the suite took over 45 seconds to complete; Imagine 2000 or more unit and integrations tests done in under 45 seconds. We also agreed that the 45 second threshold was negotiable; and something we’d change via a pull request and conversation.
We held that line. And the result was an application that helped make the easy changes.
In another recent case, I noticed that we were having problems around a particular conceptual area. This area spanned from A to B to C. I introduced some fast tests that could verify A to B. Verifying B to C is very expensive.
And we’ve used those fast tests to help improve the entire process; We also use that A to B to quickly triage if the problem is there or in the B to C process.
Back to the Instigating Change
In my experience, creating a setup where a junior developer can iterate, helps them more readily explore the space. All too often I’ve heard early career developers describe (or even write) some code change and ask “will this work?”
The answer I want to always be able to provide is: “Run it and find out.” To look to the testing environment not as a chore, but as a trustworthy companion whom you can ask for help or insights.
I cannot emphasize enough how vital it is to understand how to test your code; and to have a space where you can rapidly test a significant portion of the solution space.
A Painful Lesson from the Past
When I first started Rails in , myself and the others at the company made a conscious decision: we were not going to write tests. We were all learning the new to us framework of Rails and felt that learning that framework plus how to write tests was beyond our capacity.
We proceeded with minimal tests. And paid for it in numerous ways.
Our code had lots of bugs. And our changes had unanticipated ripple effects.
But more importantly, in hindsight, we denied ourselves the opportunity of learning different approaches to writing code. Because as I’ve moved in my career, the more test writing I’ve done, the easier it has been to construct my code. And the easier I’ve found it to isolate bugs; or build modular systems that are durable and extensible.
But those gains have only come when I was deliberate about having a “fast” feedback loop. Ensuring that I could verify changes quickly. Important to that is understanding that “quickly” is relevant.
When I’m working on a task I want to know two things:
- What does done look like?
- What does it look like to show it’s done?
The “what does it look like” is the “final” review. But it can also be the feedback process you build up along the way.
This post’s title plays on the opening Kent Beck quote. “Make the change easy, then make the easy change.” The strategies of fast feedback and making the change easy speak to the idea of keeping software “soft” and malleable. Something in which you can play with and shift around. To provide a countering force to both entropy and accretion.