The Way We Work - Week 1 at Gameplan
As Andy mentioned last week, April 1 was the day the creation of Gameplan stepped into gear. We spent the morning setting up Andy's trusted ol' Mac Mini as the development machine (complete with Homebrew, Git, Rails 2.3.5 and other Rubygems); talked about the features we'd like to implement for the coming week; added them as GitHub issues; and away we went. There is a more detailed blog-post coming on the setup of our development machine - watch this space.
A week later, we'd completed all the features that we had planned for (and a few bonus ones as well) and it looks like we are on our way to meeting our first deadline.
A closer look at the way we work Andy and I decided that we'd like to have a four-and-a-half-day work week with Friday afternoons being spent doing planning for the next week, catching up on news, discussing interesting new ideas and completing any other crufty admin work we've been putting off. (Obviously a big part of yesterday afternoon was catching up with the iPhone OS 4.0 keynote).
Our planning sessions are generally quite quick (at least for now) - we don't try to dispirit (or kid) ourselves by planning too far ahead, but just enough for the next week.
GitHub Issues Once we've decided on the features, they get added as issues on GitHub. We decided to go with GitHub Issues as our project-management/issue-tracking tool of choice, since it is very simple, allows us to tag issues with multiple tags and ties in very closely with GitHub. For a two-member development team, we feel it's important not to complicate things with project management, but still have an efficient way of keeping track of our todos, bugs and features. GitHub Issues fits the bill perfectly.
Git Practices Each issue on GitHub gets its own branch - the rule that we'd like to enforce at Gameplan is that the master branch is always clean, i.e. all tests always pass on master. If a feature is a work in progress (and thus causes tests to fail), then it must be on its own branch. Once we've completed a feature and made sure that all tests pass, it gets merged into master and then pushed to GitHub.
Just-In-Time Development A great practice that we've gotten into (and one which I wasn't too familiar with) is just-in-time building with pair-programming. I'm sure BDD-gurus would scoff at my excitement at this 'new fangled' practice, but to practice it with discipline gives us great pleasure and confidence in our code. For the un-initiated, it goes like this:
- We start off by describing our feature using Cucumber. This clarifies our intentions regarding the feature, including things like what needs to be shown on the page, what are the possible errors that can happen on the page and where the user goes to after completing an action on the page.
- We then start writing functional tests for the controller in question and make sure that the controller does everything that is supposed to, including setting the right instance variables, setting (or not setting) the flash and handle any redirects if necessary. [NB: Cucumber comes built-in with RSpec, but we've decided to go with regular Rails tests sprinkled with Shoulda awesomeness]
- If the controller interacts with any models (well, if it doesn't you're violating the fat model, skinny controller pattern), we write unit tests to make sure that the models have the right behavior. If we are starting off with a blank state, this is when we define what goes in the model (and sometimes actually even create the model).
The other interesting side-effect of this is that not once have we opened a browser to interact with our application.
So, where are we? It was a little tough for me to get used to the rigor of practicing behavior-driven-development (it helped that Andy's BDD-fu is pretty awesome), but once we got used to it, we started cranking out features at a pretty impressive rate, and at the end of week 1, our results look like this:
10 features completed, 31 issues closed, 337 lines of code, 696 lines of test code with a code-to-test ratio of 1:2.1