Wednesday, December 31, 2008

Is estimating a bad practice?

According to Naresh Jain, writing in response to a LinkedIn Agile Alliance discussion, it is:
Estimates are a hang-over from the waterfall world. For the last 6 years, I’ve been very happy and successful building products and delivering projects without all the estimation related ab-ra-ca-dab-ra. No more real-time, ideal-time, story point, function point; non-sense. I’ve realized the key is to focus on the flow of the deliverable and not whether your are delivering according to the estimates.
He goes on to make a pretty compelling case for the abolition of estimates (he provides some useful back-and-forth with his detractors in the comments, too). Since some of our teams have started down the kan-ban path, it would be interesting to know how much of our experience squares with Jain's claims.

Jain also references Joshua Kerievsky's Agile 2008 presentation on the same topic.

Tuesday, December 30, 2008

An acceptance-test development approach by any other name would smell as sweet

Gaffo forwarded this snippet from the RSpec users list in response to the question "Is there a difference between Behaviour-Driven-Development and Story-Driven-Development?":
Excellent question,

I think the more common term is STDD (Story Test Driven Development). There is ATDD (Acceptance-Test Driven Development too) ;-)

They are all variations on the same theme and only marginally different IMO. The biggest difference seems to be that different people and groups promote them and talk about them in slightly different ways, and emphasise the various techniques differently. My personal take is that BDD *is* ATDD/STDD, but with an additional emphasis on Business value and getting the words right. I'm not sure how ATDD and STDD are different.

Maybe the best place to get a good balance of viewpoints on this topic is in a tool-agnostic forum - maybe this one:
http://groups.google.com/group/behaviordrivendevelopment (I don't know of any STDD or ATDD forums).

There are good articles about ATDD and STDD here:
Sounds about right to me. The most important thing is what you actually are doing, not what you call it (though that's important, too). Around here, I use ATDD, since I think it best describes the practice and people are already familiar with what acceptance tests are. And STDD sounds too much like STD, which doesn't exactly foster a mindset of willing acceptance.

Tuesday, December 23, 2008

DynamicPageList installed on wiki

We've installed the DynamicPageList extension on the company wiki. The extension is:
a universal reporting tool for MediaWikis, listing category members and intersections with various formats and details ... Typically the selection of pages to be shown will be based on one or more categories. But there are many other choices for selection criteria, like e.g. author, namespace, date, name pattern, usage of templates or references to other articles.
This allows us to dynamically generate lists, such as most-popular pages, recently-edited pages and pages edited by certain authors. I initially found the extension in my quest for a way to organize our retrospectives and let interested people see at a glance, say, the last five retrospectives for a particular project.

Monday, December 22, 2008

Path to Programming

Over the weekend, I read this article along with discussions about it on Reddit, Hacker News and a related discussion on what it takes to become a talented programmer on O'Reilly's blog.

It got me thinking about my own path to programming:

0. My first CS course ever was in high school. I did ok, middling at best. It was taught in C++. The Borland compiler we used marked syntax errors the line after they occurred, which caused me a lot of headaches. The final assignment, biggest grade of the class, was to create a game, any game. The brightest kid in the class wrote a poker game using ascii art to actually draw the cards. I thought I was at least as smart as him, so I made a poker game as well, but halfway through writing it, realized I couldn't figure out how to determine what hand a player was dealt, so I did what any industrious 10th grader would do. I rigged the game. Every hand dealt to the player was all hearts and it always printed out:
You have a flush!
I did not go to college hoping to earn a degree in Computer Science.

1. As a biology undergrad, though, I did have to take an introductory computer science class. It was in C. What I had learned in High School was sufficient enough that I slept through every class and aced every homework assignment. In retrospect, it probably set unrealistic expectations for courses to come.

2. The summer after my freshman year, during a summer internship in a bio lab, I found myself spending every waking moment in the library reading technical computer books. The campus had a network of vending machines with student id card readers attached that would, when swiped, bill your student account. I noticed that they left the phone line that connected them to the campus network exposed, and was convinced that if only I knew a little bit more about TCP/IP I could send the machine someone else's student id number and get free Snickers for the duration of my internship. I never succeeded, but at the end of the internship nothing I had still to study in biology seemed as appealing as figuring out the answers to all of the questions my reading had stirred up. That fall semester, I enrolled in CS.

3. My Operating Systems class made the most sense of any class I took as a CS major. Each assignment covered a separate system call and that system call would be printed at the top of the assignment handout, verbatim from the man page. Combined with a good specification of exactly what our program was supposed to output and how we were to deal with error conditions meant that in order to turn in a working program, all I had to do was read the assignment and the man pages enough times to put statements together in the right order. I won't even pretend that I understood how my assignment to write a primitive shell worked, I had just read the execv man page enough times that by sheer combinatorial probability it had to work.

4. Many people in the comments on the article and in the forums noted that while initially programming may not make sense to a lot of people, sometimes, out of the blue it will "click" for a student. I actually had an "Aha" moment during a final as time was being called. The last question on the last test of Computer Architecture and Assembly Programming, asked what instruction was equivalent to popping the top of the call stack. I will never accuse anyone of having a dumb, blank stare again as my slack expression betrayed that fact that somewhere inside my cranium, hexadecimal notation, the von Neumann architecture, Intel memory addressing and the 8086 instruction set were coalescing into actual understanding. Even more amazing was that my brain took those tiny electrical impulses and mechanically translated them into little carbon-graphite scratches representing a correct answer. I remember leaving the test, talking to a fellow student for whom that question had not ignited any cranial conflagrations and despite the urge to prove my superiority, I withheld my hard won answer from him, realizing that sometimes the possession of knowledge comes secondary to its acquisition.

The common thread of my education, though, I think, was that I never really questioned why things worked the way they did or worried that I didn't have as much control over them as I wanted. In High School I never questioned why I wrote int main(char* argc, char** argv) even though I had no idea what those two arguments were, nor ever used them in my programs, nor (until my infamous OS shell assignment) questioned how those values would ever be populated.

More theologically inclined students wanted to know why the for loop looked the way it did or pouted when they knew that they wanted their code to be compiled, but could not properly translate that knowledge into a series of dashes and letters that gcc would understand.

I never questioned the magical gcc incantation that was usually provided to me. Cryptic error messages, I felt deep down, were my fault. It is this same suspicion that persists in me even today, keeping me from writing copious amounts of bug reports for the software I use.

I did know I hated C++ and liked C, though I had seen the phrase C/C++ bandied about so often that I thought that they were merely two different styles of writing the same language, sort of like the distinction between which style of brace indentation you chose.

And once, while practicing for a programming contest, competing against my advising professor, he blew my mind by writing some 4 or 5 line string function in C that I had written with 1 in Java, and like the master to the grasshopper, asked my how mine could still be slower.

There were more classes, but I was a college student and blissfully unaware of the totality with which my life after college would be consumed with, well, life after college and I tried not to let too many more painful epiphanies erupt inside my skull. Departed from college for a handful of years, I now work with very smart people that force these epiphanies on me cruelly and with great relish. Its probably why our company has been as successful as it has been and makes me wonder just what their path to programming was.

So, to end of this heinously long post, I completely agree with whoever it was that said "A little bit of knowledge is a dangerous thing".

Wednesday, December 17, 2008

Reducing authorization Redundancy in Web.config

We are developing a website that includes several pages, where user access is by page. The users are assigned to groups, which correspond to user roles, in Active Directory. Access to the various pages is based upon a member's being associated with any one of a group of roles.

Here is an example that illustrates the situation:

A user is granted access to the pages, "Bananas.aspx", "MonkeyMatch.aspx", and "Swingers.aspx" if (s)he is in any of the roles: "monkey a", "monkey b", "monkey c".

A user is granted access to the pages, "JavaJabber.aspx", "RailsRules.aspx", and "CodeGuru.aspx" if (s)he is in either of the roles: "geek 0" or "geek 1".

A user in the admin role is granted access to all pages.

Only a user in the admin role is granted access to the page, "SpyOnGeeksAndMonkeys.aspx".


So, Web.config might look like this:

<configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0">
<!-- blah, blah ... -->
<system.web>
<authentication mode="Forms">
<forms name=".ADAuthCookie" timeout="10" loginUrl="login.aspx" defaultUrl="default.axpx />
</authentication>
<authorization>
<deny users="?" />
</authorization>
<!-- blah, blah, blah -->
</system.web>
<location path="Bananas.aspx">
<system.web>
<allow roles="monkey a,monkey b,monkey c,admin" />
<deny users="*" />
</system.web>
</location>
<location path="MonkeyMatch.aspx">
<system.web>
<allow roles="monkey a,monkey b,monkey c,admin" />
<deny users="*" />
</system.web>
</location>
<location path="JavaJabber.aspx">
<system.web>
<allow roles="geek 0,geek 1,admin" />
<deny users="*" />
</system.web>
</location>
<location path="RailsRules.aspx">
<system.web>
<allow roles="geek 0,geek 1,admin" />
<deny users="*" />
</system.web>
</location>
<location path="CodeGuru.aspx">
<system.web>
<allow roles="geek 0,geek 1,admin" />
<deny users="*" />
</system.web>
</location>
<location path="SpyOnGeeksAndMonkeys.aspx">
<system.web>
<allow roles="admin" />
<deny users="*" />
</system.web>
</location>
<location path="images">
<system.web>
<allow users="*" />
</system.web>
</location>
<location path="javascript">
<system.web>
<allow users="*" />
</system.web>
</location>
<location path="css">
<system.web>
<allow users="*" />
</system.web>
</location>
<!-- blah, blah, blah -->
</configuration>


You can see the problem! Having the list of roles duplicated in the various location elements is definitely asking for trouble. What are the chances that someone will mess up the roles on a new page -- or even in the original configuration. As the number of roles and the number of pages increase, it gets even worse.

It would be very nice if the path attribute of the location element could take multiple paths. Unfortunately, it doesn't.

There are options. We could organize the structure of the site around authorization. In that case each location element would only need to reference the containing folder. Sometimes that makes sense.

Another option is to use the configSource attribute of the authorization element. We can then write separate files that have the configuration that we need. For example, we can write these files:

AuthMonkey.config

<authorization>
<allow roles="monkey a,monkey b,admin" />
<deny users="*" />
</authorization>


AuthGeek.config
<authorization>
<allow roles="geek 0,geek 1,admin" />
<deny users="*" />
</authorization>

AuthAdmin.config

<authorization>
<allow roles="admin" />
<deny users="*" />
</authorization>


AuthAllowAllUsers.config
<authorization>
<allow users="*" />
</authorization>

The web.config location elements can now be replaced with:




<location path="Bananas.aspx">
<system.web>
<authorization configSource="AuthMonkey.config" />
</system.web>
</location>
<location path="MonkeyMatch.aspx">
<system.web>
<authorization configSource="AuthMonkey.config" />
</system.web>
</location>
<
location path="JavaJabber.aspx">
<system.web>
<authorization configSource="AuthGeek.config" />
</system.web>
</location>
<
location path="RailsRules.aspx">
<system.web>
<authorization configSource="AuthGeek.config" />
</system.web>
</location>
<
location path="CodeGuru.aspx">
<system.web>
<authorization configSource="AuthGeek.config" />
</system.web>
</location>
<location path="SpyOnGeeksAndMonkeys.aspx">
<system.web>
<authorization configSource="AuthAdmin.config" />
</system.web>
</location>
<location path="images">
<system.web>
<authorization configSource="AuthAllowAllUsers.config" />
</system.web>
</location>
<
location path="css">
<system.web>
<authorization configSource="AuthAllowAllUsers.config" />
</system.web>
</location>
<
location path="javascript">
<system.web>
<authorization configSource="AuthAllowAllUsers.config" />
</system.web>
</location>


As a result, the groups of roles are kept in one place. The Web.config file now references the appropriate authorization rules in the location elements. This is a great improvement over redundant values in the allow and deny elements.

Acceptance testing pains converting WatiN tests to run in Selenium

For the last year and a half we have been using WatiN to drive our automated integration/acceptance tests for one of our projects  (If you'd like some insight into our decision, see Adam's blog post on it), and it has worked out really well. However, lately we have been experiencing pain when it comes to running our acceptance tests, and we have considered moving our tests to run using Selenium instead.

Our first point of pain is the amount of time it takes to run our acceptance tests. We have around 500+ and they have been taking close to 40 minutes to run. I'm not sure at what point they began to take so long, but I hardly considered 40 minutes to be acceptable. One of the key ideas behind Test Driven Development is the red, green, refactor principle, which requires you to run your tests often. With the acceptance tests taking 40 minutes to run, I had begun to find myself running those tests less and thus losing the security blanket that we had created by writing those tests from the very beginning.

Another point of pain is testing the number of web browsers we are supporting. Currently we are supporting eight different browsers, Firefox 2 & 3 (Mac & PC varieties), Safari 2.0.4 & 3 (Mac only), IE 6 & 7. We are looking to add support for at least two more, Google Chrome & IE 8. One of WatiN's biggest limitations is that it only runs in IE. Our stories had to be tested manually in the other browsers to ensure they were complete and if you do this often enough it, you will loose a lot of time out of your development cycle.

We decided to reexamine using Selenium, particularly Selenium Grid and Selenium RC, in our test suite. We were hoping to a) Speed up the time it took to run out tests b) Run our test across a larger set of browsers. Knowing how the Grid works, we knew that b could easily be achieved, but how would the speed compared to WatiN.

As a test we converted a small subset of our fixtures, about 10, over to Selenium and did some slight benchmarking. After the 10 fixtures were converted, we didn't see any initial improvement in the average test time. It was decided the advantage gained by being able to test across multiple browsers was more than enough for us to convert the rest of our tests to Selenium.

It appeared the quickest way to move forward was to rewrite our tests using SeleniumIDE. It took two developers about a week and a half to convert every test over and flush out any old tests or broken tests. After this was all said and done the Selenium tests ran about two to five minutes faster than the WatiN tests, but I feel that what we gained was well worth the effort. At the very least, we did not slow ourselves down and we can now test across multiple browsers with ease, and I like knowing that whatever changes we make will be tested and tested well.

*We were able to speed the tests up and get them to run in as little as 12 minutes. I'll share that in a later post.

Tuesday, December 16, 2008

Pairamid

A few teams at Asynchrony have used pairing charts as a mechanism to help us pair and change pairs frequently so that we gain the benefits of sharing knowledge, widening our understanding of the code, etc. Here's an example of something I call the "pairamid" (pun intended):
In this particular pairing chart, we put a tally for each pairing session, color-coded by day of the week. It serves as a gentle reminder in our war room that we shouldn't let one of the squares have too many more tallies than any other and that person x should try pairing with person y (which we obviously weren't doing very well that iteration!).

Tuesday, December 09, 2008

Hendrickson on ATDD

The prolific Elisabeth Hendrickson has posted another insightful piece on her blog, an overview of Acceptance-Test-Driven Development. I'll let you read it, which includes a .pdf with more details, but I wanted to highlight a graphic from the .pdf:

I think we do the Discuss and Develop components well, but our weaker muscles tend to be the Distill and Demo aspects. Distilling takes a bit more time, but I think it's an example of the old saying "a stitch in time saves nine."

Friday, December 05, 2008

Twitter badges now on blog sidebar

I added individual Twitter badges of Asynchrony employees to the sidebar of this blog. Apparently, there's no way to aggregate multiple Twitter accounts into one badge that I've seen. If someone wants to try, let me know.

Also, I'm using the big block flash badges because there's no easy way to display multiple individual non-flash badges on the same html page. You can read more about it.

Wednesday, November 26, 2008

Helmkamp on Story-Driven Development

Gaffo noted this very good talk -- "Story Driven Development" -- by "the guy who runs webrat" (aka Bryan Helmkamp):
It really picks up about 25 minutes in for us, but the first 25 minutes are interesting because they cover Rspec and story runner (the precursor to cucumber). He's talking about a lot of the things we're currently running into and I think it will help facilitate later discussions.
Good stuff; I second Mike's commendation.

Tuesday, November 25, 2008

Testing Pyramid, part 2

I went ahead and grabbed the actual test numbers from the build(s) -- simply the total number of assertions in each of the test levels (unit, functional, integration and UI) -- and generated a chart in Excel:

I posted it in our war room; we'll see what kind of conversation it sparks. It looks like we need to continue moving toward increasing the ratio of webrat (integration) tests to Selenium (UI) tests, as well as upping our base level of units. Using the actual data also corrected my anecdotal assumption that we had a lot more unit tests than we do (see my sketch in my previous post).

UPDATE: I ran the numbers for another team. Here's their chart:
This team has some UI tests written in Watir, but they don't run them (so they're useless). All of their integration tests are Webrat; apparently, these can be run as Selenium tests, but the team isn't doing that (yet). This team has the fundamentals down well -- more unit tests than functional, more functional than integration. We'll see how they expand the upper levels of their triangle in the coming weeks.

Monday, November 24, 2008

Constructing the testing pyramid

I like Mike Cohn's testing pyramid as a guideline for test allocation, and I've mentioned it to a couple of teams around here (for more, read Patrick Wilson-Welsh's blog and/or see his Agile 2008 presentation). Lately, on one team, we've been very earnest about writing Selenium tests for UATs, even doing some ATDD. But we're seeing what many have seen: Selenium tests are often (necessarily) long and slow, and occasionally brittle. I asked the team what our "testing pyramid" would look like, and it's something like this:

^^^^^^^^^^^^ (GUI/system)
^^^^^^^^^^ (functional)
^^^^^^^^^^^^^^^^^ (unit)
That is, the majority of our tests are at the unit level (that's good), but we are top-heavy with GUI tests. So with the help of the Ace team, we're moving toward more under-the-GUI integration tests using Webrat. Now we're looking more like:

^^^^^^^^^^^^ (GUI/system)
^^^^ (integration)
^^^^^^^^^^ (functional)
^^^^^^^^^^^^^^^^^ (unit)
The goal is to convert some of those Selenium (GUI/system) tests to Webrat (integration) and get our pyramid more in line (and help our team be more productive). There's still obviously need for the GUI-system tests, but we're just trying to be smarter about it. 

Friday, November 21, 2008

Aysnchrony Mentioned In Local Blog

A local blog titled "Downtown St. Louis Business" does a fantastic job posting the latest news, rumors, and rumblings of local area corporations.

Brian, the site's primary author, posted a column earlier this week that summarized local businesses that have sadly relocated their headquarters from downtown St. Louis, to other areas of the metro area.

On a much brighter note, Brian posted a column today that notes local businesses that have pursued the opposite path - moving their business *into* the downtown perimeter. Although it isn't exactly "news" - since Asynchrony relocated from Earth City in April '08 - it's nice to see our business recognized as one of the local corporations contributing to the growth of downtown St. Louis.

Here here.

Friday, November 14, 2008

ENTER key press in Selenium

Mike Gage needed to simulate an ENTER key press in Selenium to call a submit. Erstwhile Asynchronite Ryan Tyer provided some helpful feedback via Twitter (we're gonna miss him!):
In selenium, there is a submit function. This submits the form without using a submit button, same as an enter key press. [And in a followup:] Further, you should be able to simulate an enter key press with selenium...in rc (java) selenium.keyDown(id, "\\13");
Mike specifically wanted to make sure that the ENTER did something, which meant that he didn't want to use the submit function in Selenium. Here's what worked for him, using Ryan's approach (only with KeyPress) -- in Firefox, at least:
[Test]
public void EnterKeyPressedOnTextAreaTriggersSubmit()
{
selenium.Open("/");
selenium.WaitForPageToLoad(DEFAULT_PAGE_TIMEOUT);
selenium.Type("quicksearchtextcriteria", "text");
selenium.KeyPress("quicksearchtextcriteria", "13");
selenium.WaitForPageToLoad(DEFAULT_PAGE_TIMEOUT);

Assert.IsTrue(selenium.IsTextPresent("We could not find an exact match for your Quick Search entry"));
}

Tuesday, November 11, 2008

Tip: A Visible Approach to Sizing Stories

Brian sent me an email that had this interesting tip from another Brian, Brian Bozzuto:
Next time you are sizing a large number of stories - especially when beginning a new project - consider using a visual method. This exercise is best done with a long table. Begin with an average size story card and place it in the center of the table. Take the next story and place it either above or below the first story depending on its size. The team should, one at a time, place stories on the table relative to the size of those already laid out. Rather than trying to define an absolute size, the team will sort stories based on their approximate size.

This exercise forces people to think in relative terms instead of absolute estimates. Once all the stories have been placed in order, the team takes a set of planning poker cards and inserts each card along the spectrum of stories to identify the transition from one size to the next larger one. For example, those stories on the simple end of the sizing spectrum will start at "1", and the team will place the "3" card at the point where the first story is that should be sized as 3 instead of 1. The team is done once they have ordered every story on the table and grouped them into one of the story sizes.

This visual exercise is most useful when a team has a hard time moving from the high precision exercise of estimating to the relative exercise of sizing. It is also useful when there are a large number of stories to be sized, as most teams will move through the sizing much faster than in traditional planning poker. However, it does allow each individual to provide an unbiased opinion, and moderators should be sensitive to the fact that soft spoken team members may have a harder time offering input.
If anyone tries this, let us know. 

Thursday, October 30, 2008

Grouping "Friends" List on Facebook

One feature I especially like since the Facebook redesign is the ability to group your "Friends" list. If you have not noticed this feature yet, start by going to your "Friends" list. On the left side, click "Make a New List." Just as the instructions say, choose a name for your list, then hit the Enter key to save the name. You will be given a screen where you can type names or, even better, you can select multiple friends from a list of your entire Friends list.

Additionally, this feature allows you to do two other things I find helpful: 1) You can send a message to an entire group of friends and 2) You can select your group from the "Live Feed" on the dashboard. This allows you to get a quick update of information for a select group of people.

Tuesday, October 28, 2008

OpenCV on Fedora 8

Our team has just spent a bit of time configuring and running openCV on our Fedora 8 boxes. openCV is a very rich toolkit for applications that have computer vision requirements. After some bouncing around between various useful web sites with different installation processes, we assembled a complete set that works for us.

This install process includes the ffmpeg libraries, and takes you from a basic Fedora 8 box to running the facedetect example.

Install ffmpeg

Do this as root.

* yum install SDL-devel
* From ffmpeg, download a full checkout.
* tar xjf ffmpeg-checkout-snapshot.tar.bz2
* cd ffmpeg-checkout-2008-10-28 (or whatever release yours is)
* ./configure --enable-shared --enable-swscale --enable-gpl
* make (You'll have time to get coffee, maybe see a movie, while this runs.)
* make install
* echo "/usr/local/lib" >/etc/ld.so.conf.d/ffmpeg.conf
* ldconfig

Now, run ffplay and pass it the name of a local video file - flv, avi, whatever.

Install OpenCV

You're still root, yes?

* yum install gtk2-devel
* Download http://downloads.sourceforge.net/opencvlibrary/opencv-1.1pre1.tar.gz
* cd /tmp
* tar xzf opencv-1.1pre1.tar.gz
* cd /usr/local/include/
* mkdir ffmpeg
* cd ffmpeg
* find ../ -name "*.h" | xargs -n1 ln -s
* cd /tmp/opencv-1.1.0/
* ./configure --enable-apps --enable-shared --with-ffmpeg --with-gnu-ld --with-x --without-quicktime CXXFLAGS=-fno-strict-aliasing CFLAGS=-I/usr/local/include/ffmpeg CPPFLAGS=-I/usr/local/include/ffmpeg LDFLAGS=-L/usr/local/lib

You should see

...
Use gtk+ 2.x: yes
Use gthread: yes
...
Use ffmpeg: yes
...

* make
* make install

Now, to verify that everything's good.

facedetect

You can do this as an ordinary user in your home directory. You'll need an avi to use, in the place of /shared/public/videos/dove_hires.avi, but I'll leave it up to you to go find one.

* mkdir face
* cd face
* rsync -a /tmp/opencv-1.1.0/samples/c/ .
* g++ facedetect.c -o facedetect -I /usr/local/include/opencv/ -L /usr/local/lib/ -lm -lcv -lhighgui -lcvaux
* ./facedetect --cascade="/tmp/opencv-1.1.0/data/haarcascades/haarcascade_frontalface_alt2.xml" /shared/public/videos/dove_hires.avi

You should see the video play, with facedetect drawing a red circle around anything it thinks is a face. Cool stuff!

Monday, October 27, 2008

Free Lean Software Development Course

Alan Shalloway (NetObjectives) is offering a free Lean Software Development Course starting Dec. 1. Here's some of the email that I saw posted on the XP-St. Louis list:
Lean-Thinking provides a framework from which to improve virtually any organization's software development process. While not a panacea, Lean provides clarity on what to look at and how to solve the problems that are often beyond other methods. For software development organizations, Lean provides several principles that provide guidance to Agile methods, particiularly Scrum. Lean will assist those organizations which have either had problems adopting Agile methods or those who have been successful at the team level and are now attempting to scale it to the Enterprise. See Alan Shalloway's blog Is Scrum Failing Us?  for some examples of the challenges Lean can give guidance to.

This Free on-line training is true training, including lectures, readings, exercises and question & answer periods. The intent of this training is:
  • Provide the equivalent of a one-day Lean Software Development Overview course
  • Promote Lean Software Development to many in the industry
  • To improve the ability of participants to explain to their associates why Lean Software Development is useful
  • Provide insights on how to scale Agile/Scrum to the enterprise
Session 1: Introduction to Lean Software Development
Session 2: Five Reasons for Agility
Session 3: Lean as a Guide for Agile Methods
Session 4: QA's role in Lean Agile Software Development
Session 5: How Business Analysts can help their teams
Session 6: Lean Anti-Patterns
Here's the link, if you're interested: http://tech.groups.yahoo.com/group/NetObjectivesLeanOnlineTraining/ If you decide to take it, please let me know or post a comment here.

Thursday, October 23, 2008

Adventures in testing (or user experience? or fraud?)

Let's hope that we don't have any job applicants from the Obama campaign anytime soon; their online work is a bit, shall we say, suspect. From Powerline blog, quoting a reader's experiment with Obama's web site:
I've read recent reports of the Obama campaign receiving donations from dubious names and foreign locales and it got me wondering: How is this possible?

I run a small Internet business and when I process credit cards I'm required to make sure the name on the card exactly matches the name of the customer making the purchase. Also, the purchaser's address must match that of the cardholders. If these don't match, then the payment isn't approved. Period. So how is it possible that the Obama campaign could receive donations from fictional people and places? Well, I decided to do a little experiment. I went to the Obama campaign website and entered the following:

Name: John Galt
Address: 1957 Ayn Rand Lane
City: Galts Gulch
State: CO
Zip: 99999

Then I checked the box next to $15 and entered my actual credit card number and expiration date (it didn't ask for the 3-didgit code on the back of the card) and it took me to the next page and... "Your donation has been processed. Thank you for your generous gift."

This simply should not, and could not, happen in any business or any campaign that is honestly trying to vet it's donors. Also, I don't see how this could possibly happen without the collusion of the credit card companies. They simply wouldn't allow any business to process, potentially, hundreds of millions in credit card transactions where the name on the card doesn't match the purchasers name.

In short, with the system set up as it is by the Obama camp, an individual could donate unlimited amounts of money by simply making up fake names and addresses. And Obama is doing his best to facilitate this fraud. This is truly scandalous.
It would seem that the people running Obama's site either a) don't test their stuff very well, b) don't care much for user experience, c) intentionally engaged in fraud or d) all of the above. It's a lesson for all of us, whether we're programming web sites for high-profile political campaigns or simple apps for internal use. 

Oh, and the power of the blogosphere shows itself again: NRO's The Corner blog reports that the Obama camp, $600 million later, has fixed the problem.

Tuesday, October 21, 2008

For all your Kanban needs

Since at least two of our projects have dipped a figurative foot in the Kanban pool (aCe and kinda Mako and kinda MFKR), people who are interested in learning more (like me!) can join a Yahoo group for Kanban development, aptly titled "kanbandev."

Here are a few other Kanban links:

Monday, October 20, 2008

Cross-Location Teams: Stay Connected Via Co-Op

If you're anything like me, RSS feeds have significantly altered your reading habits.

So many options, so little time.

I skim, glance, peek, and ponder (alliteration, +2 blogging points) through countless options that are surface-level unique only through the negligible details.

Although the sophomoric tendencies of limiting my reading/downloading habits to items that immediately appeal to my interests is mindless at best, I've learned to appreciate 'simple' in addition to 'functionality'.

One such item I encountered over the weekend is the "Co-Op" web application.

Think Ace iteration planning...mixed with online to-do managers such as "Remember The Milk"...mixed with Twitter.



Co-Op is completely web-based, completely free, and completely simple. Yet, it encourages structure and organization across a group of people that are working tasks in parallel.

While morning stand-ups and the tight environments of a localized agile team can probably accomplish most of Co-Ops online features on its own, don't write off it's usefulness just yet.

As Asynchrony continues work in corporations with existing IT shops, off-site employees communicating with on-site employees is a growing concern. The need for a cross-location communication tool external to email is evident, and essential, to daily team performance.

Furthermore, although the Asynchrony sales team attempts to stay connected with daily standups, any number of individuals could be out of town or away from the office. And yet, there are proposals and projects that depend on the entire group.

Co-Op serves as a central meeting place for general team notes, important to-dos, and team member status updates. It's worth taking a brief look. I promise.

And yes, each team member can upload their own avatar.

Monday, October 13, 2008

Selenium tip of the day: assertXpathCount

For those of you (like me) learning some Selenium IDE commands, here's a tip that Ben showed me today: assertXpathCount. The other day, Abra and I were trying to assert that a certain column in a table contained the same value. Ben noted another way to specifically check the count of something in a page using assertXpathCount. So if I wanted to assert that Roger's name appears in a column (any cell with a particular class) three times, I'd use the assertXpathCount command and the following arguments:

  • Target:
    //td[@class="presenter" and contains(text(),"Roger")]
  • Value:
    3

Thursday, October 09, 2008

Another published Asynchronite!

Some of you may have already heard: Shawn Sheldon is the latest Asynchronite to become a published author. Tate Publishing recently released his children's novel, Stranded, the first book of his Dragon Ship Series. From the site:
"That night was another restless one. Actually, it was the worst one of my life to that point. I knew I had better get some rest if I was to have any hope of managing the day that was coming for me the following morning. What kind of day you ask? Let’s review. Tomorrow I would need to secretly explore the Blue Goose site gathering intelligence information, lead my brother and sister and four other children in play, and rescue my dog Snowball—a pretty tall order for a twelve year old; I think anyone would have to agree! In Stranded, the first book in the all new series The Dragon Ship Series, written by Shawn Sheldon, follow a boy and his brother and sister on their unusual Christmas vacation. Their backyard adventure leads to both frightening and exciting encounters with intelligent dragons, Bigfoot, and ‘pet’ robots. A mystery begins to unravel as they discover that the common link involves an amazing space ship, hazardous waste, and even their own family history. Will they be smart enough and brave enough to meet the challenges they discover?
Congrats, Shawn! Bring your copy to the third floor, and he'll autograph it for you!

p.s. Yes, those are his kids on the book cover.

Wednesday, October 08, 2008

Customer tests breaking the build?

I was chatting with a team member about the possibility of his team moving toward ATDD (Acceptance-Test-Driven Development) in which they would write automated acceptance tests before development. He raised the concern that it would mean that they would be checking in tests that broke the build for unacceptably-long periods of time (a day or more). I turned to Brian Button and Ryan Tyer to see how they handle that. Their responses:
Brian: I ignore the ATs that aren't implemented yet so they don't show up as broken tests. (I mean ignore from a JUnit ignore point of view, not just ignoring by choosing not to look at their failures!) Once I start working on something, I unignore the tests.

The restriction on checking in code on broken tests goes for programmer tests, not customer tests. Customer tests go from ignored, to failing, to passing, and shouldn't ever regress.

Ryan: I'd add that with some testing frameworks (TestNG comes to mind) you can flag tests to ignore programatically (@Ignore if I remember correctly). These will not be run so they will not fail the build. You could have two suites of tests (all and all but ignored tests) for the frameworks that don't support this.

Brian: That idea is what I was talking about. In junit 3, you'd have to comment the test out or something, since it doesn't have a way to ignore tests. In Junit4, Nunit, Xunit.net, TestNg, you just mark the test as ignored.

In visual studio architect edition, team suite, or tester edition, you can use test lists to separate ignored ATs from those that should pass.

Google Chrome, Zimbra and you

I started using Google Chrome when it first came out but quickly reverted to Mozilla Firefox 3 because the advanced version of Zimbra didn't work on Chrome. When I polled the company about whether anyone else could get the two to work together, here's what I received:
"No. And it's really annoying. I believe they have some js in the page that looks for IE 6 or 7 and Firefox browsers and anything else gets the standard view."

"yes and no. I am using Chrome, but the Ajax version doesn't work. I am using it anyway, because I have run into issues with the Ajax version in Firefox."

"Last time I looked there were some issues with it and both google and zimbra were looking into it."

"I have been using Chrome for a while, and it always uses the standard version no matter what version you pick. I'm guessing here, but suspect that Zimbra doesn't recognize the browser so it doesn't understand whether or not it has AJAX support, so it launches the safest (standard) version no matter what you choose.

Another thing to note here is that Zimbra Standard has some things that don't work properly (and there are AI's already in ACE about them). For one thing you can't download e-mail attachments (it produces an invalid URL in the download link). For another, if you create a public calendar entry (i.e. "Out of Office") via Chrome, nobody else can see it but you. There are probably other limitations, but those are the only ones I've seen so far. Other than that Chrome & Zimbra seem to work together okay - albeit limited by what the HTML version can do."

"Elitist"

Tuesday, October 07, 2008

Finally-close your resources

You are a java programmer. Do you read from databases? Perhaps you write to files? If you aren't careful, you might be creating memory leaks and inadvertently leaving database connections open. Java is notorious for making simple things like file i/o complicated. Consider the try-catch block inside the finally block, which is necessary because the close() method throws an IOException; what is an application programmer supposed to do if the operating system won't allow him to close an open file? Witness the following code:

1 myFile.open();
2 contents = myFile.readContents();
3 myFile.close();
If an exception occurs while reading the file's contents on line 2, your program will skip over line 3 where the file is closed, as the exception interrupts normal execution flow and propagates up the stack, leaving the file ambiguously open. Fortunately, you can invoke this simple solution. Behold:
1 File file = new
File("/shared/home/richard.green/.bashrc");
2 BufferedReader reader = null;
try {
reader = new BufferedReader( new FileReader(file) );
String line = reader.readLine();
// Deal with line
}
catch (IOException e){
// Deal with exception ...
}
finally {
try {
reader.close();
} catch (IOException e) { /* ignored */ }
}
When execution leaves the try block (line 3), code inside the finally block (line 5) is executed under any circumstance. Therefore, in the above solution, if an exception occurs while reading the file's contents on line 3, the file will still be closed on line 5 before the exception propagates up the stack.

Frameworks like Commons IO from the Apache group ( http://commons/apache.org/io) take much of the pain out of dealing with Java I/O. Commons IO provides variety of utility classes which safely implement common I/O operations without dealing with the ugly Java Reader/Stream/Exception semantics.

Resource leaks due to exceptions are a problem in more-or-less every programming language. Each language has its own idioms for dealing with them. C++ coders wrap resources in their own classes and use the language's constructor-destructor semantics to allocate and de-allocate the resource. In Ruby, you use the IO::open method with a block; this automatically closes the resource when the block ends. Familiarize yourself with these idioms as part of learning a new language.

Monday, October 06, 2008

Coming soon: Selenium Grid

Coming soon to a project near you: The advantages of Selenium Grid. From the web site:
Selenium Grid transparently distribute [sic] your tests on multiple machines so that you can run your tests in parallel, cutting down the time required for running in-browser test suites. This will dramatically speeds up end-to-end web testing, giving you quick and accurate feedback you can rely on to improve your web application.
We've been using Grid for one of our customers and within the next few weeks will be setting up a hub for use in other projects. See Cornel, Dave M. or me for more details.

Agile2008 conference proceedings

The Agile2008 conference proceedings are now on the public drive at \Agile Conferences\Agile2008. You can find a lot of good presentations and material there. (The Agile Conferences directory also has Agile2006 and Starwest2007.)

Thursday, September 25, 2008

Marcano on acceptance-test-driven development

When I met Antony Marcano, who runs the essential blog Testing Reflections, a year ago at STARWest in Anaheim, I immediately liked his views on agile testing. He published a very insightful article in Better Software this month on a topic that's been top-of-mind for me recently: Acceptance-Test-Driven Development (ATDD). I'll let him explain (emphases mine):
ATDD bridges the gap between an idea summarized in a user story and the implementation of that story. It helps elicit the detail behind the idea to make it better understood by both the customer with the idea and the cross-functional development team that will implement it. ...

Whenever we begin to discuss acceptance criteria, it’s safe to say the user story alone is not enough. To establish a shared understanding of a user story, the customer elaborates on the idea behind it by first outlining some acceptance criteria—often in terms of the new behaviors that the system will exhibit once the story is implemented. This is so that the team has a high-level view of the story’s real meaning. Programmers, testers, and the customer exchange examples of specific inputs and outputs that further clarify the scope of the user story. This results in refinements to existing acceptance criteria or additional criteria. During the iteration, programmers and testers work with the customer to draw out the detail required for them to expand outlined acceptance criteria into specific examples in the form of tests. From these tests, programmers infer the underlying rules that must be implemented. During this process, with the help of a variety of testing techniques, testers help to identify exception cases and reduce other example behaviors into equivalent cases. The result is a set of examples, expressed as automated acceptance tests. These tests are run and, since the feature isn’t implemented yet, they fail—as expected. For each of these automated acceptance tests, programmers implement enough of the software for the acceptance test to pass (ideally using TDD with unit tests). Once all the acceptance tests for a story pass, the story is done— almost.
(He goes on to note that the story's not "done" until exploratory testing -- another important practice -- happens.) It seems to me that ATDD goes a long way to solving many pains: knowing when "done" is, eliciting requirements, developing the right features first, etc.

Tuesday, September 23, 2008

Standups and communication

Communication is the first core value of XP. So how does your team communicate with each other? How well do you do it?

One way that our development teams communicate is via daily standup meetings. But what is a standup meeting, anyway? How about this definition: a self-organizing daily gathering to gain shared understanding of the state of our team, focus our day and remind ourselves that we're all in this together. As one comment on Ward Cunningham's wiki puts it, "Our aim is modest: to identify short-term obstacles. The agenda is minimalist: What does the day look like?" Some teams eschew standups because they’re not helpful; perhaps understanding the objectives can help you reshape your standup. How do you know if your standup meetings are effective? Here are some possible outcomes:
  • Everyone knows what he or she is going to do -- and with whom -- as soon as the standup ends (rather than finding a pair partner or figuring out what to do after the meeting ends).
  • Everyone understands where the team is on all the stories -- if an outsider were to ask you about any story, you could answer (rather than merely “the story I'm working on”).
  • Everyone knows high-level problems facing the team for the day (rather than not knowing).
  • Everyone has a sense of how complete the iteration is, and what needs to be done to "make it" (rather than being surprised on the last day).
  • The team has decided to have breakout meetings to resolve specific problems (rather than try to solve bigger problems in the standup).
  • Everyone knows what the team is pledging to accomplish for the day (rather than being unfocused).
If you're not accomplishing these, check out the standups article on Martin Fowler's site, which provides useful patterns and identifies "smells" for standups. Now for some best practices that we’ve seen around Asynchrony:
  • Prompt start: The way a team starts its standup is indicative of the way the day will go; when everyone arrives on-time (or, heaven forbid, a minute early!) the meeting tends to have a snappier pace. Use a fun disincentive to cut down on lateness (e.g., tardy MFKR team members having to wear a PPE jumpsuit).
  • Story-based: Rather than focusing on individual check-ins, the team talks about its progress in terms of stories. Facing the story posters on the board, the team talks about the unfinished stories in order of priority and how to complete them. The team can set a goal by determining which stories it will attempt to finish that day.
  • Know what’s next: Before the standup meeting is over, know who your pair partner is (consult the pairing chart for help) and what task you’re going to work on, and go to it.