- Consulting / Coaching
- Jeff’s Blog
PragPub celebrates their seventh anniversary issue this month with a large collection of feature articles–pieces by Ron Jeffries, Alistair Cockburn, Allen Holub, Michael Nygard, Jonathan Rassmusson, Venkat Subramaniam, and me (I am honored!)–reflecting on the past, present, and future of agile software development. (And there’s more! …the issue also includes articles by Johanna Rothman, Michael Swaine, Marcus Blankship, and Natasha Murashev.)
Visit The Prose Garden to grab a copy for less than a couple bucks, or to subscribe to PragPub at a measly $20 per year. You owe it to yourself to stay current with this stellar publication.
I chose to write about my feelings regarding TDD, a practice I’ve embraced for now half of my fairly long development career (Ron still has me way beat). In Half of a Third of a Century in TDD, I talk about the reasons I’ve personally found TDD to be an indispensable practice.
(I’ve linked just my article… thanks Swaine for the permission to do so!)
A few months ago, I chose to return to operating Langr Software Solutions full-time, after over two-and-a-half years working for the startup Outpace Systems. (I’m still providing development work for them.) Along with that move comes a new site design, intended to update from a 2010-ish look to something a little more modern and responsive.
I’m thrilled with the artwork. Madeleine Einfalt of Artmmmporium provided the commissioned painting of Pikes Peak; I love it. I sketched an attendant “national parks sign” logo, and my sister Christine worked it up professionally and precisely.
Indeed there will be bugs, however. Please let me know of any you spot! Also, I will need to start working to ensure all blog content is moved across; this will take some time. I suspect all the old material can still be reached, however, using the old links.
Hmmm. Why is my article list not coming up, for example? Time to fix that!
I’ve been amiss at my writing for the past year-and-a-half while knee-deep in a startup. I wrote this post somewhere near the end of 2013, but never published it until now. I’ll be adding a follow-on soon. You’ll also have an opportunity to read more about this distributed development experience at PragPub in an upcoming issue.
There are a few familiar things, including Jenkins and vim. Altogether, it’s well over 20 new technologies in less than 50 days of work. All this while occasionally bouncing back to Windows, Visual Studio, C#, Fitnesse, and some C++ (to support the release of Modern C++ Programming with Test-Driven Development). I’ve regretfully had to put aside my ramping-up on Android development.
Even more challenging: Most of us work from home.
It’s insane, frustrating, and somehow exhilarating. These are all technologies I’m happy to learn, so it’s all good, but most days I feel fairly stupid. Of course I’m not anywhere near mastering any of the new technologies. Right now, we’re bouncing mostly between Clojure and Coffeescript/Angular, so I hope to master them in due time.
It shouldn’t work, but it does. Why? Everyone on the team is an accomplished programmer. We pair online through most of the day using Google Hangouts, and switch roughly daily (though sometimes every couple days, a bit long for my taste but it helps to have the time to immerse more on the unfamiliar stuff). We communicate frequently through the day via a persistent campfire chat, a morning business briefing, a morning dev planning session, and ad hoc hangouts as needed.
What’s not to like? Well, the pairing constantly sometimes gets old, and we’re pairing a little longer per day than I’d prefer. Bouncing around so frequently between technologies has been rough. And remote communication has its hiccoughs that detract from the experience. Ultimately, nothing is as good as being there.
However, our efforts have been very effective, even with most of the other programmers (about 10) not masters of most of these technologies either (many are intimate with Ruby). We’ve managed to make the customer happy with a quick first effort, and are well into incrementing on a second product.
I can’t imagine attempting something like this without pairing. We’ve had at least one candidate dismiss the opportunity because of pairing–“it can’t possibly be anything but a waste of time to have sharp programmers work together.” But they’re the ones who are missing out–it’s hyper-productive, rewarding, and has been the glue in keeping us from devolving into complete chaos.
After a couple failed attempts, I managed to successfully run com.example.mapdemo in an Android Virtual Device (AVD). It’s not tough, but required cobbling together instructions from a variety of sources.
The following instructions work for the ADT installed under Ubuntu, version linux-x86-20130522. I make no guarantee that these steps will work for you. It’s possible that some of the steps are extraneous.
Using the Android SDK Manager, install Google Play Services (v7).
Using the Android SDK Manager, install Google APIs (v3) (located under Android 4.2.2 (API 17)).
Using the Android Virtual Device Manager, create an AVD with a target of Android 4.2.2 – API Level 17. (I created mine with a 4.65″ 720p, not sure if that’s important.)
Start the AVD
Download two application package files (APKs):
Install the APKs using adb (located in the ADT directory ./sdk/platform-tools):
adb install com.android.vending-4.1.6.apk adb install com.google.android.gms-(3.1.36).apk
Restart the AVD
Copy ./sdk/extras/google/google_play_services/libproject/google-play-services_lib/ to your Android projects area.
Create a project for Google Play Services (projects needing to use Google Maps will need to depend on this):
Import->Android->Existing Android Code Into Workspace.
Navigate to ./sdk/extras/google/google_play_services/libproject and select google-play-services-lib.
Create a project for the map samples:
Import->Android-Existing Android Code Into Workspace.
Navigate to ./sdk/extras/google/google_play_services/samples and select the maps directory.
Create a Google Maps API key (note: these steps supposedly will not work for your production deployment):
Copy the SHA1 from your Android Debug keystore. Here’s the instructions I used under Ubuntu to display the contents of the keystore:
keytool -list -v -keystore ~/.android/debug.keystore
By default, the password for the keystore is android.
Go to https://code.google.com/apis/console and select API Access from the menu (to the left).
Click the button marked Create new Android Key….
Paste in your SHA1, append a semicolon, then append com.example.mapdemo
Click the Create button.
Copy the API key into the paste buffer (you will use it in the next step).
Configure the map sample project:
From the project’s build path settings, Add External JAR: ./sdk/extras/android/support/v4/android-support-v4.jar
Go to the Order and Export tab, and export android-support-v4.jar
Go to Properties->Android. In the Library section, add the google_play_services_lib project as a dependency. (You will need to open google-play-services_lib if it is not already.)
Edit AndroidManifest.xml to contain your API key: In MainActivityManifest.xml, ensure you have a meta-data element with something like the following:
<meta-data android:name="com.google.android.maps.v2.API_KEY" android:value="AIzaSyCawgR4hVSiAzHIg4wJMbg7jvNyt-KZNgs"/>
Substitute your API key for the android:value attribute. The meta-data element is a direct child of <application>.
Edit AndroidManifest.xml to contain appropriate permissions. For example (don’t forget to substitute your package name):
<permission android:name="com.langrsoft.plangrok.permission.MAPS_RECEIVE" android:protectionLevel="signature" /> <uses-permission android:name="com.langrsoft.plangrok.permission.MAPS_RECEIVE" />
Here are some of the links I used to piece this together:
Please let me know if I missed any steps or if you discovered something else.
Your business doesn’t want to hear about how you “delivered stories.”
The business wants you to deliver value, in the form of what they most likely refer to as features.
A story should trigger a conversation around a feature request. Your software product doesn’t contain stories, it contains features that help users accomplish goals.
Wikipedia describes a user story as “one or more sentences” that capture a user’s needs. Those sentences represent a brief description or summary based on the planning and preparation so far, and they are reminders of the conversation that you must continue to have around the feature you will build. The sentences are not the feature. They aren’t even the full story, in most cases, as it often takes the requester several more oral sentences or even paragraphs to say what they really want.
If you think about stories as a simplified form of a requirements document (“a couple sentences”), you’re constraining agile to be a small tweak to how you did things before, with a trendier name. That diminishes the most important aspect of how agile can help you deliver software successfully: Through continual collaboration and oral communication. Without understanding of the importance of collaboration, stories end up being another waterfall-like hand-off document.
On another front: Too many teams waste time over the wording of a story. It’s a discussion point, not an artifact. The “standard” story template should help you clarify feature requests by asking you to think about who needs them and why. But otherwise spending time on precise word-smithing of a story writeup misses the point. You’re going to discuss it, and you can iron out any ambiguities as you do.
Stories provide only minimal value as an artifact. The ensuing discussion is where the details come out. Unfortunately, most of us can’t fully recall details from a conversation a half year prior, or even a half month prior. Granted, the details end up embodied in the software, but source code more often than not does a poor job of expressing such details concisely and simply. Even programmers must sometimes spend hours to determine just what the code does for the smallest of features.
We need a better artifact than the few sentences that represent a story. Many successful teams have found that the best way to capture system behaviors is in the form of acceptance tests, best derived by use of acceptance test-driven development (ATDD) or BDD. The acceptance tests supplant the nebulous conversation with real meat. A test’s name describes the goal it accomplishes, and its narrative provides an example that quickly relates the details of system behavior. The set of test names describes the complete set of designed system behaviors. The tests capture the important detail behind the discussion triggered by the story.
A story is not a feature, and it should always trigger a conversation.
With the goal of delivering quality software, I can help you with:
Want to hear more? Call 719-287-GEEK or use the Contact Me form to the left.