Saturday, July 14, 2012

My Mercurial Workflow (using Bookmarks)

The "master"

I create a bookmark that always points to the latest changeset from the shared repository. I should call it "origin/master", but have been able to manage with a single 'master' bookmark. I update to the master bookmark before making changes or pulling changes,

Any changesets that I want to push are ancestors of the 'master' bookmark. I put new commits on 'master' and defer the decision to create a branch when I have changes that need to be shared at different times. For example, when you start working on a new feature, but have to go back and fix a quick defect.

Daily Flow:

hg update master
(edit, commit, edit, commit, edit, commit)

** determine I need to move previous commits to a feature branch
hg bookmark feature1

** move the 'master' bookmark back to the last shareable/pushable changeset (rev 1234)
hg bookmark -f master -r 1234
(edit, commit, edit, commit, edit, commit)

** Quit working on the non-sharable commits push the sharable changes
hg update master
hg pull --rebase
hg push -r master

** Time goes by with dozens of changesets by other....
hg pull --update (--update will move the 'master' bookmark forward)
hg update feature1 (move my working directory to my feature1 branch)
hg rebase -d master (rebase my feature1 changeset on to the latest changes)

** when these are ready to be shared
hg bookmark master -f (move the master bookmark to the changesets we want to share)
hg push -r master

Pushing (The secret sauce)

If you have local changesets on bookmarked branches that haven't been merged in to master and you attempt a push you get the "abort: push creates new remote head" error.

Include the -r (or --rev) option to only push master changesets.

-> hg push -r master
pushing to origin
searching for changes
1 changesets found
adding changesets
adding manifests
adding file changes
added 1 changesets with 1 changes to 1 files

Tips for Bookmarks

Keep an eye on the active bookmark. The active bookmark is denoted with an asterisk (*). When you commit, the active bookmark will update to your new commit. This is most important when you're pulling in other changes. Switching the active bookmark is done by updating the bookmark (hg update feature_1). This can be done even when the bookmarks are point to the same revision.

-> hg bookmark
   feature_1                 3097:6757f51d7d1a
 * master                    3101:0b0834be4897

Thursday, May 3, 2012

Testing Boundaries

Many projects follow the same pattern for software testing. These projects test the entire system by running manual test cases through the user interface. When the number of manual test cases grow beyond the capacity of the current staff they introduce automation tools to execute the manual test cases. This testing strategy leads to discussions about data management, test maintenance cost and ever increasing execution times.

While there are ways to improve the exist testing process, ultimately I think the strategy is wrong. More specifically the test boundaries are wrong. We can't effectively test a system using end-to-end tests exclusively. This is an example of an alternative testing strategy.

Imagine we have a system with three Modules (A, B, C).

For the sake of simplicity lets assume that each module has 10 paths. Every path in Module A depends on every path in Module B and every path in Module B depends on every path in Module C.

If we test the entire system across all the modules, we need 1000 tests to cover all the paths through the system.

We can drastically reduce the testing effort by splitting our test boundaries.

When we unit test each module in isolation we'll need 10 tests per module, 1 for each path in the module. However these 30 tests don't cover the interactions between the modules. We need 200 integration tests between the modules. 100 tests to validate A and B plus 100 tests to cover B and C.

So if we change our test boundaries we can get the same test coverage for a system using 200 + 30 = 230 test cases.

The most powerful benefit of smaller test boundaries is the ability to quickly localize failures. If there is a single path in Module B that has a defect and we have a full system boundary we will have 100 failing test cases. This large number of failing tests makes it difficult to track down a single defect.

If we split our testing boundaries up, we have a single unit test failure for Module B and 10 broken integration tests between Module A and Module B and 10 broken tests between Module B and Module C. 21 failing tests is still a lot, but our single failing unit test will tell us the exact location of the defect and we can quickly discover the defect.


I realize this is a simple example, but I hope it illustrates the effects and impact of using smaller testing boundaries.

Sunday, April 29, 2012

Observations from a 2 day Hack-a-thon

Last week I had the opportunity to participate in a two day "hack-a-thon". This is an event where engineers get to work on any interesting project and present their results to a panel of judges. The judges determine which projects are the most innovative and are awarded and promoted across the organization.

In the past I've been skeptical of these types of events. Most of the proposed project are engineering improvements that should be worked on as part of their project deliverables and the majority of the projects for this event would fall into that category. However, I think the event gave the teams authority and permission to work on these projects and was impressed by the results the teams produced in two (more like 1.5 days to allow for demos).

This lead me to ask a couple questions. One to the teams and one to the leaders/managers. To the team, I asked: How were the teams able to deliver such impressive results in 2 days? Some of the team's reasons included:

  • Improved collaboration
  • Uninterrupted/focused work
  • Interesting projects
  • Competition with other teams
  • Scoping the work to two days
  • Food and snacks
The reason that I think contributed the most to the success of the projects is scoping the work to the time available. Most teams had two to three options for what they envisioned for their demo. They delivered the simplest demo first then worked on the next small improvement. Most demos were ready during the first day.

I saw another impressive behavior...The teams followed up on impediments instantly and would not take "no" or "tomorrow" as an answer. I don't know if I would call it Drive, Responsibility or Ownership, but was very happy to see it.

On Monday, I'll follow up with manager and leaders on how to replicate these outcomes on our real projects.