I’ve already written about why Agile is interesting in the first place, and how you might customize its application for your team. The hard truth is that you can’t become Agile overnight. People need time to change, and your software needs time to change too.
In this post we’ll talk about the technology side of Agile. Without deliberate effort, the software project itself with fight you every step of the way.
Imagine that the feature you are implementing right now, as soon as it is done, will immediately be in your customers’ hands. How does that make you feel? Do you feel worried? Take a second to think about some of the things that might make you feel a little bit better…
Got some ideas? Write them down before you forget!
To me, the core idea is risk management. Any given change might completely block usage, or just disable one scenario. You might lose customers entirely or just get some concerned tweets. And so, the effort spent to verify a bug fix or feature must be balanced against the associated risk.
We know that the benefits of iteration are clear: over time we learn and adapt, tuning features to business and user need. The faster we can do that the better. So, let’s mitigate risk to reduce the stress often involved with quick iterative learning.
As you imagined sending that feature out to customers, the first thing that popped into your mind was probably testing. You can hear the finger-wagging admonitions in in your mind, can’t you? All those things you should be doing: Run the tests before you check in! Run tests on your Continuous Integration server, so it doesn’t just work on one machine! Static analysis and linting, unit tests, deeper tests, automation of the UI itself (browser or native app), and so on.
Don’t listen to the purists. 100% code coverage for your test suite is a fine goal, but it can hurt in two different directions:
You need your wits about you when designing good tests. How to approach this problem intelligently? The 80/20 rule is worth considering here. How much risk mitigation do you get for a given amount of development and maintenance effort?
If you have to choose one type of testing, make it a full, end-to-end manual test with the real user interface, back-end services, and databases. Probably on a staging server with everything set up just like production. Most projects start with unit tests or small-scale integration tests because they are easily automatable, but these are far less important than the key paths through the app that users care about. Start with manual testing, then automate for increased efficiency over time.
Over time you’ll establish a process you can trust. Maybe each pull request comes through with enough validation to be confident that everything still works, with a little bit of manual effort to double-check visuals and edge cases.
Okay now you know that your primary scenarios are in good shape. Now we can start to think about getting updates to users more often. If you’re writing a mobile app, you might have an App Store approval process to get through. Or you call someone from the operations department to do the deploy for you. It’s time to make this process more automated.
If you have a Continuous Integration server like Jenkins, let’s imagine what it might take to get the results of every successful build onto staging servers. Tools like Ansible or Capistrano, or CodePush for mobile apps made with React Native, can make deploys quick and easy.
As you get more confident about these processes, you can switch your continuous delivery target to full production servers.
Now your users are getting more frequent updates. New features are appearing out of nowhere! It helps to have some mechanism to introduce users to these features. The App Store release notes feature isn’t enough, now that updates can happen in the background. When will the users ever see that?
Tutorials and walkthroughs are sure to both advertise and educate, but they can interrupt a user’s flow.
Slack’s What’s New widget at the top right of the screen is a good balance. It’s unobtrusive unless you’re like me - I can’t stand red badges! Once you open the What’s New pane, most items link to a blog post with comments enabled.
In a similar vein, my side project when I was at Microsoft had a “Feedback Stars” feature. All over the website, we added little stars to the page. When you clicked on a star, you’d get a popup with a chance to rate the feature it represented, even add a little comment about it. Once we built the core feature, it was easy to use it to get feedback right in the moment.
But don’t wait for users to tell you what’s happening! Systems like Graphite and statsd make it extremely easy to gather tons of metrics about your application. Now you’ll know if signups or other key activities drop off right after a deploy!
It’s easy to get data from your servers. You’ll need to put a bit more effort into finding tools to collect data from clients: both errors and usage. Try Errorception or New Relic for capturing browser errors, and find a web analytics provider that works for you. On the native side, Apple collects application crashes for you, and again there are lots of analytics players in the mobile space.
So far we’ve been talking about systems useful for production-ready systems. The trouble is that the bar for production is typically very, very high. It slows things down. But we’re interested in reducing risk while also enabling fast iteration.
That’s where a whole host of tools for incomplete features come in:
A little bit of planning and infrastructure code can go a long way. Each of these reduces risk while also enabling iteration.
Get creative! You’ll be surprised how much these low-level features change behavior. If you can roll out a mostly-complete feature for just a few customers with an easy avenue for feedback, iteration will just happen naturally! It won’t feel like bushwhacking to iterate - it will be the main trail!
It’s important to think holistically about Agile - sprints can feel pointless if your releases don’t actually go out the door afterwards. This infrastructure might even make your sprints seem too long!
Now you’re ready for my next post in the series: An Agile organization. It’s easy to be Agile within technical teams, but how to handle other parts of the organization still asking for specific features on specific dates?
Resources:
I’ve been told that I’m a very productive developer. And I’m sharing my techniques. Welcome to number two of my developer productivity tips: Focus. Context-switching always has a cost, but it’s far... Read more »
It’s time for another edition of recent stack improvements! This time we’re primarily focused on React and Redux. But if you use Node.js at all, my comparison of Node.js version managers should be... Read more »