Wednesday, August 26, 2009

Testing with Moxy

Overview
Build proxies that pass through most requests, but create mock results on well-known data.

Our situation

We needed to be able to verify the behavior for error conditions from our Selenium (web) tests. We had already created mock services that would return these results. We then had to manage when we connected to which endpoint, which put the expectation about behavior outside the test and in the server configuration. In order to do a single regression pass, we had to stop and reconfigure the server.

Our solution
We created Moxies (mock proxies), which most of the time are just a plain passthrough to the real endpoint from our vendors' test systems. For a well known set of data (addresses in Broken Arrow, Oklahoma) the Moxy returns error conditions. Those addresses and their expectations are defined in a single class, shared both by the Moxy implementation and the tests.

Benefits
Test real success and mock failure in same server configuration.
Data and its expectation is in sync (shared classes).
Code is explicit about which tests depend on which Moxies, and which specific behaviors.

Future
With the same solution we expect to create a set of test cases that do not rely on the availability of the vendor test systems, based on similar conventions. (Eureka, CA)

Other implementations
We considered using wrapper objects injected via Spring to accomplish the same thing with less monkeying around with endpoints. This would avoid needing to deploy a real http mock service, and avoid issues around certificate verification and authentication. However, an injected solution would require deploying the mock software on all the client machines, and tweaking its configuration so that the wrapper bean is injected in our test environment, but not production. The injection solution also doesn't test the parsing of the error response, though that should probably be done in unit tests anyway.

If we were using a ESB like Mule, we could have configured Mule to redirect the requests based on the data, and used our mock services unchanged, and the test system configuration also unchanged.

Some solutions avoid having to use key data in the request object by manipulating http header info instead. This wasn't an option for us, unless we create some kind of signal for that header all the way through to our public pages. That seemed too invasive for our situation.

Closing
It works for us, and has a cool name*. What more could you want?

* Yes, you could probably more accurately describe this as a decorator. But Mockorator isn't nearly so awesome a name.

Monday, August 03, 2009

Leading Self Organized Teams

Self Organization, Collaboration != Fire Your Leadership

One of the questions I've tackled with the agile teams I've worked with is how to find a balance between the need for direction and quick decisions with the open and self-organizing approaches that are recommended for teams practicing agile processes. A lot of this perceived conflict comes from people overstating the basics. In particular:
Self Organization != No Leadership. Collaborative Approach != Everyone Votes On Everything.

Core Values:

Self Organization: Invite owners and participants rather than assigning people to teams

Transparency: Discuss topics openly, rather than among a separate team.

Collaboration: The point of the self-organized group

Direction: The owner is responsible for driving to dates, providing major guidance (sometimes from above), and deadlock resolution.

Review: Periodic review of practices and applications is key to success.

Example: Spacely Sprockets Quality Issue

Problem: All the sprockets we've got are throwing NullPointerExceptions.

The Development Director in this case wants to delegate this task to the team. In order to do that, she asks for volunteers to be the "owner" for this issue, and Olaf steps up. After consulting with the Development Director for parameters (due dates, budget, etc) the first thing Olaf does is send an invitation: (Self Organization)

  • To: yourWholeTeam
  • Subject: Spacely Sprockets Quality Issue
  • Hello Team,
  • We need to determine whether to stay with Spacely Sprockets, change to Cogswell Cogs, or pursue some third option. if you're interested in participating, send me an email and I'll include you in tomorrow's meeting.
  • -Olaf

The group meets a couple of times (Collaboration), trades emails (via whole team mailing list, for Transparency) and works towards a recommendation. One participant suggests Gary's Gears, but Olaf shares that Gary's Gears are outside the budget for the project. (Direction). Absent of that option, the group finds consensus on staying with Spacely after an impassioned speech by George J., one of their salesmen. Olaf shares that recommendation with the rest of the team, then the Development Director, who puts the recommendation into place after a few additional questions/clarifications (more Direction).

Common Problems

Self Organization Problem: nobody signs on

Often you'll be expecting "the usual suspects" to show up when you invite people to collaborate. Sometimes you'll be surprised to find no responses to your hot topic. As the owner, this gives you the opportunity to find out why. This may be for many reasons:

  • People are busier than expected
  • People are tired of working with the issue
  • People feel that the solution is obvious
  • People feel that the recommendation won't result in change.

What to do:

Talk to your usual suspects with these possibilities in mind. The major advantage of the process in this case is that as the owner you are aware of these problems at the beginning rather than the end of the process.

Self Organization Problem: everybody signs on

Instead of "the usual suspects", you get the whole department. Reasons for this include:

  • Concern that some aspects of the issue are being ignored or are unknown to the group
  • Concern about "the expected outcome"
  • Size/Impact of recommendation

What to do:

Hold a first meeting and have a round-table where you invite each participant to share what motivated them to participate.

People who feel that they're alone in a concern have an opportunity to share it, and can hear others if they exist. Those who are worried about an "expected outcome" can share their point of view. If the source is that the impact of the recommendation is huge, then team members have an opportunity to voice general concerns and witness for themselves the process by which the recommendation is being made. Sometimes just having the preliminary session is enough -- the team can identify when enough of each viewpoint exists and will drop out satisfied that their viewpoint is represented.

Another approach is to assure the team as a whole that there will be an opportunity to review the recommendation before it is "ratified." This can make team members feel less urgency about allowing others to tackle a difficult or contentious issue.

You may be tempted as the Owner to be aggressive in this case about reducing team size. Be sure that you are keeping in mind that the real goal is not to simply make a recommendation, but to have it understood and implemented by the entire team. To this end, it may be more effective to allow for some up-front "inefficiency" in order to get everyone on the same page and reach the real desired outcome faster as a result.

Direction Problem: small project

Sometimes this all seems like a lot of effort, with more time spent sending invitations and setting up meetings than it would take to do the work.

What to do:

Use IM and/or email for self-organization. Set a deadline for response (self-organization), and list your planned actions by that deadline (Direction, Transparency). Ex:

  • To: yourWholeTeam
  • Subject: I hate the PMD "use if x==y not if x!=y" rule

  • Hey all, Can someone tell me why I shouldn't hate this rule? If nobody objects, I'll remove it on Wednesday.

  • -Developer Danielle

Collaboration Problem: can't reach consensus

Rational people can disagree on a subject. Time doesn't always allow all avenues to be examined.

What to do:

This is the "big job" of the owner. It's the owner's responsibility not only to identify when it's time to just make the call, but to also make all the participants feel that they've been heard even if they haven't been agreed with.

Every time the process is used without the need for this outcome are like money in the bank. That money (trust, really) is expended in these situations. If you've got a positive balance, then this is just a a problem. If you're overdrawn, then this situation can become a fiasco. Team members must feel that the situations where the owner makes the call without consensus are rare, and due to issues that are a toss-up, or due to outside pressure. If you're doing a lot of this, it's probably an issue that should be considered in the process review.

Transparency Problem: When should I include everybody?

Is copying yourWholeTeam on *everything* really the recommendation? What if they're unlikely to care and it's just noise?

What to do:

Use a restating of the golden rule to determine what to send to the whole group: If you weren't an active participant, would you want to know about this part of the discussion? Err on the side of Transparency.

Criteria For Review

These criteria help determine success of this approach and your specific practices:

  • Does everyone feel they understand the approach?
  • Does everyone feel that quality recommendations are being made?
  • Do team members feel involved, not dictated to?
  • Are recommendations timely and within expected parameters, ie conforming to Leadership's direction?
Last Words

To restate a problem from above, it's important to keep in mind that the end goal isn't a decision, its a decision whose spirit is implemented and upheld team wide. I use this approach not because it makes everyone feel good, but because it's the most effective way to get real results.