Interestings
- Underscore 1.4.0 and 1.4.1 helpfully blow up when passed nil. Underscore 1.4.2 is sane again.
Recently, @seriouslynow pointed me to a nice primer on user research by @semanticwill. My favorite slide lists five common biases,

which are:
or “CFORF” for short. With a little rejiggering, we get a nice pneumonic:
as in, “Stick a FFORC in it!”
</ rimshot> :-P
I’m really excited about a collection of new techniques I’ve been experimenting with over the past few weeks. They’re an evolution of the in-browser design approaches I’ve been using for the past few years, and taken together they help my team build better designs with less waste in a tactic I’ve taken to calling Spike Driven Design.
UPDATE: This is a blog-post version of the talk I gave last week at the Agile Experience Design / NYC SASS & Compass co-meetup. You can find the slides on my Talks page.
Traditional, Adobe-app-based design is great for designing before any software is built, for quickly iterating on user flows, and for experimenting with new high-level concepts. On the other hand, it suffers a heavy tax once working software exists and mockups have to play catchup with reality, and it does little to aid in designing interactions (Fireworks and Flash have an advantage over Photoshop and Illustrator in this regard, though they’re far from ideal).
Designing in the browser is great for working out low-level tactics, quickly iterating on interface and small interactions, and suffers almost zero set-up cost: install Firebug or tick the “Show the Develop menu” box in Safari’s prefs (or just install Chrome!) and you’re good to go. On the other hand, the toolset and techniques are immature, there’s a reasonably high learning curve, and the tools are tantalizingly close to the real app, but not quite there. Saving your work is difficult (to say nothing of iterating over a few ideas), and replacing text by hunting and pecking into Firebug fields gets old fast. For quick-and-dirty mocks, some light Firebug hacking, a screenshot, and a trip to Photoshop may suffice, but this workflow doesn’t hold up for prolonged investigations into a new user flow or feature track.
Enter Spike Driven Design. Rather than design in an Adobe app or even in the browser, I’ve taken to designing in Rails itself, using mostly SASS and HAML and little bits of Ruby. Whereas designing in the browser helped fake the front-end for mockups, it could never help with data. Now I can fake the back-end too! I’m not bothering with tests, and like any true Spike (in the Agile sense), this is code that is written to be thrown away. That gives me the freedom to move fast, focus on the UX and visual design problems without worrying about much else, and design using the actual medium the user will end up with: working software.
Plenty of ink has been spilled on the topic, but at heart, an Agile “spike” is a short investigation into a technique or a problem. For instance, when it comes time to build our Recommendations feature into my sample e-commerce site Hamazon, we might put a time-boxed chore into the backlog: “spike on recommendation algorithms and choose one”. By nature it’s explicitly exploratory and limited, and the goal is learning (rather than working software, the sine non qua of Agile development). After a spike is completed, the code must be thrown away. This is important: the imperatives to learn fast and to write healthy code are necessarily opposed, and the temptation to keep the code is always present. Resist it. Chuck the code. Now that you know the approach you want to take, write it again and write it right.
To start Spike Driving your design, branch the project, and begin to gleefully and recklessly hack around. For instance, if I were SDD’ing a new Order History feature for Hamazon, I’d want to have a bunch of orders to play with in my design. Instead of mucking around with a database and orders, I might just write a method called “orders” that returned a pre-canned list.
def order_history
[
{order_id: 102173, order_date: "8/1/2012", price_in_cents: 1799, item_name: "Snout T-Shirt", item_id: 1 },
{order_id: 102384, order_date: "8/1/2012", price_in_cents: 3699, item_name: "Berkshire Ham", item_id: 2 },
{order_id: 102930, order_date: "9/1/2012", price_in_cents: 1599, item_name: "Piggy Mug", item_id: 3 },
{order_id: 103151, order_date: "9/14/2012", price_in_cents: 3699, item_name: "Berkshire Ham", item _id: 2 }
{order_id: 103944, order_date: "9/15/2012", price_in_cents: 2299, item_name: "Tactical Bacon", item _id: 6 }
]
end
Obviously this doesn’t get us closer to anything that helps a user, but it lets me start designing with real(ish) data, real quick. I’ll call #order_history in a view somewhere, get the list of orders on the page, and start marking up and styling them. I also might put a comment at the top of this message: # TODO: make this real. It’s kind of a shady move to push all the real work onto “someone will take care of this later”, but running a quick grep todo lets us see all real dev work that needs to be done.
While I’m playing around in the Orders History page, I notice that the navigation is going to need a link to the Order History for the User Flow to make any sense, so I’ll throw that in now. (An aside: it may be a little premature to commit any of this to git, but when you do start checking in your work, take care to keep your commits small and atomic.)
Ugh, now that we need secondary navigation, that bloated 60px header bar really needs to be trimmed down.
Let’s deal with that right now, hop into the appropriate stylesheet, and bring it down to 30px. As I work, I’ll play around with the interaction, navigating through a normal user flow, jumping into the Order History, and then back.
Hm, these order line items are starting to look ok, but they could use something a little more visual; how about some icons? Which, now that I look at it, should really light up on hover, so let’s create some assets. Oh, also, we’re probably going to want to be able to perform bulk actions on this list.
I don’t need to write a working form, I can just throw in the checkboxes and select lists in the appropriate places—they don’t have to be wired up to anything. Ok, this looks pretty good; the PM (who sits right next to me, and has been chiming in along the way) and I pull a dev over to run through this with him and make sure nothing sounds too crazy. Once we’ve got the rough ‘ok’ we can start writing well-formed stories in Tracker and take screenshots of the SDD site and attach them as mock ups. I’ll also create an epic called “SDD-order_history”, and attach a note mentioning where the branch lives and what I’ve done in it.
So that’s the rough version of Phase One. Now the fun begins. If I haven’t done so already, I’ll go back through my work in git add -p or GitX and break all my changes down into small, atomic commits. Generally, I’ll have a few kinds of commits:
Now I hop onto the master branch and start cherry-picking those styling commits: BOOM! Free style tweaks and polish! All the design fit-and-finish that I meant to write stories for and get to at some point are now done and in production.
Phase Two is when the devs get to the SDD’d stories in the backlog (which ideally is within a few days). There’s a comment pointing them to the branch, which they can check out as a renamed repo and then run on another port:
git clone git@github.com:jonathanpberger/hamazon.git hamazon-sdd-order_history
cd hamazon-sdd-order_history
... (bundle, set up db's, etc)
rails server -p5555
During development they’ll run the real app on port 3000 and do everything normally, but living, functional mock-ups exist for reference on port 5555. Furthermore, they can take a look at the code for ideas on things like structuring the DOM, and can even harvest things like SASS and assets from the branch. This means that a lot of the work from the design phase can go directly into the finished project, without duplication of effort, and without sacrificing quality.
So what sorts of projects and teams are good candidates for SDD? On this project, we’ve established the basic design of the app and have a while to go before we’ll need to do the Big Design Refactor. We’re building a fair number of small or medium-sized features or feature tracks, and it’s important that we make sure our additions work well within the existing app and user flows. We’ve got two pairs of developers (one of whom is off-site), plus me (a design-developer hybrid). Naturally, the designer employing SDD needs to be fairly technically literate. Another nice side effect of SDD is that the team is almost never odd. SDD stories pull me into the pair rotation in a non-time-sensitive manner, which helps smooth out rough spots in the rotation if someone has a doctors appointment or is interviewing a candidate. All of which to say, SDD seems to work well on projects that’re past their initial design phase, and have small- to medium-sized teams with a technical designer.
So what problems exist? Because of the technical requirements, there’s a high learning curve for the designer. It feels a little risky (shady even?) to push real work into comments saying “make this real”. There’s a potential for non-production quality code to leak in when. The SDD branch tends to get stale quickly. If you try to go back to it two weeks later the main line will have moved on, and these merge conflicts tend to be especially thorny because they’re usually very similar to changes you since will have made.
Despite these shortcomings, SDD has proven to be an effective technique for our team. We look forward to continuing to explore this way of working, and especially to hearing if it works for others.
I want to try out HTML5′s Server-Side-Events (http://www.igvita.com/2011/08/26/server-sent-event-notifications-with-html5/) in my Rails 3.2 application. Any experience or thoughts on how to integrate?
The basic flow will be:
lather-rinse-repeat
A current client is designing their production deploy architecture and there is a lot of resistance to a nginx/unicorn/rails stack.
Is it worth exploring jRuby inside Tomcat?
One of my integration tests started to fail (Broke Pipe). Something to do with font-awesome & Qt?
Possible solutions include submitting the form to an iframe or finding a way to intercept a submit event after Chrome saves the form data.
The website is back open for 2012. Please sign-in. Also, talk to your clients – we’d like to double our participation yet again this year!
Convention Over Configuration is one of core principles of the Rails approach to software development, and delivers enormous value.
Convention Over Configuration – means that Rails makes assumptions about what you want to do and how you’re going to do it, rather than requiring you to specify every little thing…
Oddly, we tend not to apply the same perspective to project planning: on almost every project, the team re-invents the wheel of “how should we write and format our stories?”. I’ve worked closely with the Product team on about a dozen projects in the past few years, and rigorous story-writing is one of the most common areas for low-cost, high-gain improvement. I encourage every team to adopt (or at least consider) these techniques.
Scenario: User adds item to cart
Given I'm a logged-in User
When I go to the Item page
And I click "Add item to cart"
Then the quantity of items in my cart should go up
And my subtotal should increment
And the warehouse inventory should decrement
Feature: Shopping Cart
As a Shopper
I want to put items in my shopping cart
Because I want to manage items before I check out
When a story feels a little fishy, check that these bases are covered. If any are missing, fix then before you do anything else. The answer will often be driven out in the process of working the story into Well Formed shape.
Well Formed stories truly drive out the feature from the user’s perspective; this catches 80% of weird edge cases while the whole team is together, in context, and in planning mode, instead of having to interrupt-drive the PM. Well Formed stories make it impossible to camouflage large stories as small stories by elision. Because the story has to be written out step-by-step, all the complexity might otherwise be hidden is forced out into the open. And when you find yourself with conditionals or switches? That’s a new scenario! Now all stories are forced into roughly the same size. Another side-effect is that once one story ~= one scenario, the amount of work to be done can be roughly gauged spatially, by looking at how much of your wall is covered by index cards. For bonus points, use the story title as your git commit, e.g. the story “User should be able to recommend a product” becomes the git commit “User is able to recommend a product”, and your git log tells the narrative of your project.
Once apon a time, J (the anchor) made N (a very bright, technical Product Manager) write stories in Gherkin. Most stories weren’t 100% ready to be pasted into cucumber, but it usually didn’t take too much work to get them there. The team would discuss in IPM, and then devs could copy-and-paste stories right into Cucumber. This doesn’t work for every PM, but even in the worst case, teams with less than tech-savvy PMs see real benefits from writing their stories at the right level of granularity. Once I was exposed to a team where we wrote Gherkin all the time, anything else felt like broken process.
UPDATE: To be clear, the opinions in this article are my own, and do not reflect anything close to consensus or standard practice on the part of Pivotal. Some Pivots will agree with this position, while many others will not.
UPDATE 3/17: Added a brief introduction elaborating on how Well-Formed Stories help bring principles of Convention Over Configuration to story-writing.
Today I’m in the Ace Hotel at a one day conference titled “Agile Testing and BDD Exchange” #bddxny, and I’ll be taking and sharing notes throughout the day.
Skills Matter is a UK based technical education company who are starting out in New York. This is their second conference. I’ve been to a few one day conferences, training days and evening meetups at their London base. I’m giving them bonus points for bring PG Tips.
Please forgive the inevitable spelling mistakes and typos, but I hope there’s some interest in this.
Uncle Bob starts with some 2001 Space Oddesy music to the video of a code file scanning down. It takes at least 3 minutes. He then starts, “I am your new CTO”, and continues to give his talk as if we, the audience, are employees at the same company. He outlines not how he wants us to work, but what he expects the outcomes of that work are.
Here follows the notes from his talk.
“I am your new CTO”
“Setting expectations”
“How do we deal with the people who say yes”
Where do we begin if we have lots of bad code
eval “$(rbenv init -)” does an rbenv rehash which only allows one session in at a time.
This causes weird failures if you have multiple CI builds starting at the same time.
Having one master build do the regular init, and then the other builds do a eval “$(rbenv init – –no-rehash)” solved it for us.
Not needing to compile rubies after download makes rvm way faster
RubyMine uses a custom formatter.
Try rspec my_spec.rb -b on the command line.
If you do something like this:
after_fork do |server, worker|
current_directory = File.expand_path(File.dirname(FILE))
log_path = “#{current_directory}/log/#{Rails.env}.#{worker.nr}.log”
Rails.logger = ActiveSupport::BufferedLogger.new(log_path)
Rails.logger.level = Logger::INFO
end
… in order to have a different logfile for each unicorn worker, setting the log level in your environment file will not take affect.
It always passes.
The rspec folks haven’t decided what it should do. “Official” suggestion is to only use any_instance with stubbing instead of with expectations.
When you use the deploy:cleanup task it only looks at the FIRST server declared in deploy.rb to determine which releases to rm. You’d think that it would look at the primary server. But then you’d think that the task would be included by default, too. Which it doesn’t.
We ran into what we thought was a quirk of Enumerators where inside the enumerator you are in a different thread from outside. This affects ActiveRecord because your connection is determined by Thread.current.object_id. So you’d end up with a new connection inside the Enumerator.
This turned out to only be true in JRuby. Under MRI, you have the same Thread object, however, you have a new Thread locals context. This makes it particularly hard to find someplace cross Ruby for Rails to store its connection id.
https://jira.codehaus.org/browse/JRUBY-6887