Friday, December 26, 2008

AAAA Unit Testing

A while back Oren wrote about the Arrange, Act, Assert syntax for unit tests. I've seen several other discussions on this and I am not sure if he is the originator but I'll attribute him either way.

The syntax I most commonly use ressembles an Arrange, Assert, Act and Assert (AAAA) pattern.
  • Arrange the system in it's initial configuration. Create any collaborators and mocks you may need. Initialize services.
  • Assert that the initial state is correct. For me this is important since so many layer of dependencies exist in modern applications. This is analogous to a control group in the scientific method. In this step I would also test the inverse of later assertion such as the non-existence of objects that should only exist after the Act step.
  • Act on the system by creating/deleting/updating new objects or invoking services.
  • Assert again that the system is in it's expected state.
I've caught a lot of bugs using this method. Asserting the initial state may also be a good way to expose weakness' in the design.

Monday, December 01, 2008

Memcached for Monorail Update

Memcached for Monorail is a session replacement for the Castle::Monorail framework. It uses memcached on the back end for distributing the session across a web farm. I have added some additional notes about Memcached for Monorail. I have also uploaded a binary release. Although I recommend getting the source.

No time to discuss much more but feel free to ask questions and I'll answer them. The Memcached session provider is currently being used in a production environment with great success but it definitely has room for improvement. It's aimed squarely at extending the Castle::Monorail session so if you are looking for something more generic than please look else where...or consider switching to MVC with Castle::Monorail ;-)

Monorail installed on a 64bit OS

Installing Castle::Monorail on 64bit IIS7 proves to be much easier than I thought. You must use the 64bit handlers. To make this easy you can just add the handlers to your Web.Config:


  136   <system.webServer>
  137     <handlers>
  138       <add name="IconHandler" path="*.ico" verb="*" modules="StaticFileModule" resourceType="File" />      
  139       <add name="Monorail-64" 
  140            path="*" verb="*" 
  141            modules="IsapiModule" 
  142            scriptProcessor="%windir%\Microsoft.NET\Framework64\v2.0.50727\aspnet_isapi.dll" 
  143            resourceType="Unspecified" />
  144       <add name="Monorail" 
  145            path="*" verb="*" 
  146            modules="IsapiModule" 
  147            scriptProcessor="%windir%\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll" 
  148            resourceType="Unspecified" />
  149     handlers>
150
system.webServer>


As you can see above, I have added handler mappings for both the 64bit and the 32bit. Notice that the 64bit is listed first, this is important. The 64bit script processor is:

%windir%\Microsoft.NET\Framework64\v2.0.50727\aspnet_isapi.dll

A more detailed overview can be found at BitterCoder.

Friday, September 12, 2008

Javascript: Equality versus Identity

Javascript has 2 basic forms of comparison operators: === and == .== is the standard equality operator while === is the identity operator. The equality operator will perform casting and usually test both sides as strings. The identity operator compares the value each side the type, but it does not work like instanceof.

Recently we did some experiments with the different return values.

The Expressions

ExpressionResult
"test" == "test"
true
"test" === "test"
true
String("test") === "test"
true
new String("test") == "test"
true
new String("test") === "test"false
new String("test") === new String("test")
Before Firefox 3.0.1: true
After: false
new String("test") === String("test")
false

Here are some type tests we performed
ExpressionType
typeof("test")
"string"
typeof(String("test"))
"string"
typeof(new String("test"))
"object"
typeof(function(){})
"function"


What Did we Learn?
First we see that a string is not always a string. Sometimes it's an object. It's easy to forget that Javascript still has the concept of primitives and objects. Integers, Strings and a few others are all primitives. When using the identity operator (===) you have to assume that it is comparing the value of the variable and it's type (as returned by typeof). Further compounding this is the fact that new String() does not type to a "STRING", while calling String as a function does.

What this all suggests is that when dealing with primatives you might as well use the equality operator (==). If you feel it's safer to use the identity operator (===) then you should use String() as a function and never use new String().

Tuesday, August 12, 2008

Hire the Right People

I believe my team of engineers has been very successful. This is no accident. I look for, and like to, surround myself with smart people. I'm not being egotistical. I don't consider myself the sharpest tool in the shed, but I do know a sharp tool (smart engineer) when I talk to one.

Hiring the right person is harder than it sounds. The top two impediments, in my experience, to hiring the right person have been "Hiring People that are Non-Threatening" and "knowing nothing about the job you are hiring for."

Non-threatening can mean a lot of things. A non-threatening person can be a yes-man. Yes-men will agree with you on everything and never make you uncomfortable by pointing out flaws in your plan. Yes-men are often hired on the basis of philosophy rather than actual skill. Non-threatening people can also be that dull-tool that won't outshine the person who hired them. In both cases the company is stuck paying wages to an under performer.

More often, though, I have seen poor hiring decisions made by managers that have no idea how to judge candidates for a job. These managers tend to rely heavily on applicants' resumes and sets of nebulous questions about work ethic or previous projects. Lacking a basic understanding of engineering practices and what makes a good engineer, these managers usually hire based on a feeling.

So, how do I hire....smart people? First, I give a basic skills test. I actually test each applicant on basic problem solving skills using pseudo code. If they do well on the test, then I send them a practical exercise. I look for three things in the practical exercise: how well they followed the directions, coding style, and does it work.

The test and exercise help me weed out those applicants whose time would be wasted on an interview. If I am happy with the test and the practical exercise, I schedule an interview. I'm also a true believer in team buy-in on all new hires so I get as many engineers involved in the interview as we can afford.

The interview includes some basic questions about relocating and what technologies the applicant is interested in, but the real meat of the interview is a set of problems the applicant must solve, interactively, on a white board. The problem solving progresses, "lecture style," with the applicant lecturing us on how the problems could best be solved.

Engineers are free to ask questions and the applicant is encouraged to show all his work. After the interview, I discuss the applicant with the other engineers and prepare for the next interview.

Once we have an adequate pool, we all sit down together to review, compare and contrast all the applicants.

Wednesday, August 06, 2008

Watin Installed

I've spent the last few days getting our testers up to speed on Watin. Watin is an Automated Web Acceptance Test Tool We are using Watin CTP v2.0. So far I have learned a few things about Watin that I didn't know when I wrote my original Watin Review. If you are completely unfamiliar with Watin I recommend you read my review first.

Our descision to go with Watin was based on 4 factors. (1) Watin handles AJAX applications very well, (2) Watin doesn't inject Javascript into your code, (3) Watin supports Firefox (Not 3.0 as of this writing) and (4) it's open source (we can mod the code).

Watin Smarts

Watin has a good set of algorithms for handling the WaitForLoad stuff. WaitForLoadTimeout is the amount of time the underlying framework should wait for a page to load even though you have asked the framework to find an element.

Example:

browser.goto("http://www.google.com");
browser.Button(Find.ByValue("submit")).Click();


In the example above the thread will reach the 2nd line before the page finishes loading. Watin is smart enough to wait for the page to load before clicking the button. This behavior is controled by the WaitForLoadTimeout property.

Nice Syntax
The Syntax for finding elements on a page is pretty nice. Here is an example:
 browser.Button(Find.ByValue("submit").And(Find.ByClass("pretty-btn")).Click();
The "Find" constraint has both an "AND" and an "OR" method. Both take a single Find as an argument. Testers will prefer this syntax to the more arcane XPath style syntax but I would have preferred something like this:
browser.Button.Find.ByValue("submit").And.ByClass("pretty-button").Click();
Either way the Find constraint offers many ByXXX methods for do all sorts of neat tricks and if need be you can drop to regular expressions (well coded sites shouldn't require that). I also appreciate the HTML mappings syntax.

Firefox Support
You'll notice that the firefox support depends on a firefox plugin called jssh. JSSH opens up a telnet server that allows Watin (or any other framework) to issue automation commands that it then forwards to Firefox. Watin 2.0 comes with a version of JSSH in it's Mozilla folder. This version only works on Firefox 2.x. We have tried several "fixed" version and we have tried turning off compatibility and security checks in Firefox 3.x. All attempts to run JSSH failed. In Firefox 2.x we experienced great success. So, I have no doubt that support will come soon.

Either way if you plan to support multiple browsers then you should use the BrowserFactory class. It has a create method that returns an IBrowser instance based on a BrowserType enum. In this way you can use the same tests for both Firefox and IE.

Final Thoughts
One of the most attractive things to me, about Watin, is the fact that the tests live in source code along with all our other tests. They run using Nunit and the same tool set we use for Unit Testing.

I also like that Watin does not want to inject javascript into our code. So far our testers seem excited and I hope we can keep up the momentum.

Sunday, July 13, 2008

SVN LDAP and Active Directory

We just upgraded to the 1.5 series of SVN. Almost all of our "team" tools have some hook into Active Directory (AD) for authentication. For SVN this is done via the AD LDAP interface. It turns out that some of SVN's auth_ldap libraries have changed and now our repository sits dead in the water.

For those who don't know, SVN is really just a very elaborate Apache web application. Apache handles the network communications while SVN does the versioning stuff. That being the case the real problem exists with the instance of apache that comes with SVN 1.5.0. I believe the LDAP module libraries shipped with SVN are out of date.

I have considered switching to the mod_sspi for authentication. Others have got it to work. Has anyone else had luck with this?

The benefit (I suppose) of SSPI would be the seamless inferance of domain credentials. In short, the SVN client should use your windows logon credentials to authenticate against the server. This is how CVSNT works but I'm not sure it's that easy with SVN.

Oh well....more later.

Sunday, July 06, 2008

A Project Dashboard

Lots of talk at work about implementing a project management suite. I'm not a big fan of any of the current offerings. So, I've been working on an Excel spreadsheet to track project velocity and health. What I'm attaching pretty much tells me everything I need to know about a project's health. The spreadsheet has 2 worksheets; Data, Dashboard.

The Data workbook holds all the raw data about each iteration. Only Columns A thru F should be filled in. The rest of the columns are calculated using those values. Also, I have hidden all the rows from below the last row to row 1400. I do this so these rows aren't calculated into the charts on the Dashboard worksheet. As I add rows I unhide it.

The Dashboard workbook has several charts that I find useful. The release progress chart is a sort of burn down chart. It not only includes burn down but also tracks points completed. I like this chart because it gives me a rough estimate of a project's halfway point. The estimation quality factor lets you track your estimates over time. The estimates are calculated automatically ((Pts Remaining +AVGChange) / Velocity) but can be filled in manually if need be.

For my next challenge I will move the dashboard to Google Docs.

Take a look at the dashboard. Discuss it below....I'll post changes as requested!

Download Here!

Wednesday, June 11, 2008

Back from Iraq!

As many of you know I have been in Iraq for about the last 12 months. I just returned and I am excited to get back to my family and job!

I'm also excited to be blogging again!

Saturday, April 12, 2008

Accountability Model or Making Commitments

Below is a post that I have mulled over for a while. I'm not satisfied with it but I would love some feedback.

I'd like to address two areas that are often considered taboo in the Agile field; Accountability and commitment. Just like the pig in the "Chicken and Pig Make Breakfast" story, agile teams make commitments. Teams commit to stories and they commit to estimates. As an agile project progresses through the 5 Levels of Planning it also moves through progressively higher levels of accountability; Nice Idea, Best Effort and Commitment.





Making Commitments

The Accountability Model above is meant to illustrate how each level of planning helps the team zero in on an actual commitment. Since agile teams accept that requirements will change, the most detailed design estimates are held off until just before implementation. So, project stakeholders can expect The Release Plan to be more accurate than The Road Map and the Iteration Plan to be more accurate than the Release Plan.

With higher levels of accuracy come higher levels of accountability while lower levels of accuracy call for lower levels of accountability. Let's take a look at the levels of accountability:
  • Nice Idea
    The Vision and the Project Road Map serve as guidelines for prioritizing during the more detailed planning that takes place closer to the Iteration. As new requirements and unforeseen changes expose themselves The Vision and The Road Map WILL change. Management should shy away from holding anyone accountable for changes that occur in the Nice Idea level. Rather, they should embrace the change as nessecary or find ways to mitigate the change.
  • Best Effort
    The Release Plan is a best effort estimate based on yesterday's weather. Iterations are timeboxed and most teams track velocity. This allows a project manager to produce an iteration schedule. The Release Plan, while more accurate than the Road Map, is less accurate at the front-end than at the back-end. For this reason, managers should consider using a confidence range chart or some other measurement of accuracy. Tracking a project's rate of change can also help mitigate risk. Managers should encourage change in the early iterations of a release but changes should stay within the scope of the current vision and roadmap. If you see either the vision or the roadmap changing you should consider wrapping up the release and starting a new release plan.
  • Commitment
    Iterations are short and easily estimated. Teams with a well established velocity and a long history with the current project will be able to make the most reliable estimates. These teams should be able to fully commit to an Iteration of work.
Who's Accountable?
Accountability is a hard subject to address in this field. A person can "be" accountable, "be held" accountable or account for someone else. In general, developers are accountable to the user, the team and themselves. Holding a team accountable for the completion of a project is usually a huge morale killer and often does more harm than good. Holding someone (coach, scrummaster, etc) accountable on behalf of the team will most likely fail as well.

So who is accountable? How is accountability expressed on an agile project? On agile projects, developers hold themselves accountable. They hold themselves accountable to the team, the users, their pair partner, themselves, etc. For Agile teams to be successful a culture of accountability must be nurtured but not forced.

Nurturing Accountability
Nurturing a culture of accountability is easier said than done, but it can be done. The usual tools of evaluations, reviews and threats have no place on a self organizing team. You can apply incentives, a sense of accomplishment, team ownership and a little peer pressure.

A good incentive suggested by Scrum is a burn down chart. On some teams the build server plays music or turns a light green when a build passes all tests. Involving the "Whole Team" in the planning and design is a surefire way of building team ownership. This leads to buy-in and allows developers feel a real sense of accomplishment. Also, large information radiators are a good way to keep the team focus.


Final Thoughts
So, what I'm suggesting is that teams should want to commit to an estimate. Teams who have "bought-in" to a project are more likely to hold themselves accountable. Kent's discussion about accountability was my original inspiration for this.


Sunday, April 06, 2008

Memcached for Monorail Update

Memcached for Monorail (MfM) is my attempt at a simple, memcached/enyim based, session and caching facility for Monorail. MfM offers a lightweight, fast, low friction, facility for balancing Monorail sessionstate and object caches accross multiple servers. You can read my original post.

Memcached offers an excellent solution for applications that need to balance object caches across multiple servers. It does so without the overhead of a database or even the use of the hard disk. Although, a major pitfall for memcached is it's unreliable nature. If a server in your memcached cluster fails then you lose all the objects cached on it. Memcached is just not meant for persisting object data permanently.

The current release of MfM is capable of persisting sessionstate to a memcached cluster. If one or more memcached servers fails then that part of the session will be lost, permanently. For my projects, I found this unacceptable. I decided to add a DB persistence layer using ActiveRecord.

I just started adding the database persistence layer to the custom session factory. My plan is to use ActiveRecord for the persistence. This will allow MfM to leverage the crossplatform support already built into ActiveRecord. Here is the psudo-logic I plan to implement:

If Writing to the Session then Write value to DB AND
delete the object stored on the Memcached Cluster.

If Reading from then Session then retrieve from Memcached Cluster OR
if value doesn't exist in Cluster then retrieve value from DB AND
write the value to the Memcached Cluster.

I imagine I will want to implement some kind of locking.

To learn more check out the project website. You can also browse the source repository or checkout the code yourself.

Saturday, March 29, 2008

Writing User Stories and Pragmatic XP

Writing User Stories

Part 1

Part 2

Part 3

My previous post in this series generated a lot of commentary on the XP list. I honestly appreciate everyone's insight....it can only make me better.

My intent (with respect to this series) was to suggest other approaches to writing stories. The series is aimed mostly at helping users. I try to make these approaches simple. Some users will find a "by the numbers" approach easier to wrap their mind around. The 5Ws method may also provoke a deeper analysis of the story as users try to describe each W. I also believe that some developers and testers might appreciate a more predictable user story. In the end though, users can bring us any scribble. Be it on a card, a sticky note or a napkin and we will do our best to make it a reality.

The series was never meant to be a holistic commentary on writing stories. As a rule I try to avoid anything holistic. I do, these days, try to be pragmatic and a bit understated.

When I first started down the path of XP (uhg, sounds way too cult-like) I worked in a shop with no formal method for developing software. When I discovered XP, I wasn't looking to be agile....I was looking to be methodical. My first instinct was to codify as best I could a fully functional set of XP policies and procedures. What mostly drove my efforts was a need to justify our wacky ideas (ie pair programming) to what was and primarily still is a government contracting company.

It took me several years of struggling to realize that I missed the whole point of XP. Yes, XP does help you to be more methodical, but without the formalized process. XP's informal nature is what makes it "Agile". The practices are not rules but guidelines. The coach doesn't drive the bus (the team does) she simply points out the pot holes. Finally, this all works because each person values good software over the process. The point? We write and discriminate our user stories the same way.....with a lot of guidelines and very few rules.

I wish I could say that I gained all of this insight many years ago...but I didn't. I really only got it in the last two or three years. One day I had to stop talking and start listening. To that end, I can mostly thank the insights of two of the smartest people I know (Gareth and Jason) and the never-ending patience of my boss Rob.

In the words of the "Wyld Stallyns"...."Be excellent to each other!"

Friday, March 28, 2008

Shoot Yourself in the Foot!

!WARNING! If you're not a major nerd or geek you won't get these jokes!
Recently a friend of mine sent me some funny additions to the Shoot Yourself in the Foot! list. The list is a humours look a the logic you might need to "shoot yourself in the foot" in different programming languages. Here are his suggestions:
Python
You try to shoot yourself in the foot, but the gun refuses
to go off because it doesn't have appropriate space around it.

Perl
You quickly create your own gun and shoot yourself in the
foot. Witnesses are unable to explain what happened. No one else can
figure out how to use the gun.

JavaScript

Your prototype gun admirably shoots feet during testing,
but in production many users' hands are incompatible

Flash
As you pull the trigger, the gun's barrels surge
impressively to life. The muzzles flash, smoke billows, and the ring
of pounds of expelled brass is barely audible over the deafening
gunfire. After the smoke clears, your foot is unaffected and you
realize nothing seems to have happened.


Here are a few of my own additions/revisions:

Visual Basic 6
You take advantage of the very handy ShootMyselfInTheLeftFootOnce() method and wait three years for M$ to release a ShootMyselfInTheRightFootOnce() method.

C#
You spend several hours browsing through Intellisense drop downs and the object browser looking for the right combination of .Net classes and methods to shoot your foot and eventually decide to port the Java libShootMyFoot library.

Java
You decide to take advantage of the libShootMyFoot library. After days of scanning painfully abstract API documentation you realize that, through some complex twist of logic that still can only be understood by developers working for Sun, the libShootMyFoot library was never intended to be used for shooting feet.

Please post any additons you would like to see!

Thursday, March 27, 2008

Monorail Custom Session Factory for Memcached

Introduction

I have written a simple but effective ICustomSessionFactory implementation that uses memcached storage on the back-end. If you don't know why you should be using memcached then you should check it out first. If you want to check out the code now, then go here. So far I think I have a passable Session Factory implementation that uses memcached on the back end. In later posts I will give some code examples and more details about deploying the Factory code.

Details

Here are a few dependencies you will need to get going:

  • Castle::Monorail
  • A memcached server or servers running on your network. Memcached is a simple and fast distributed object server for balancing object caches across many servers!
  • The latest release of Enyim. These are the guys that did all the real client work! Thanks to them for a great memcached client!
  • If you want to run the tests or plan on making modifications then you will need the Nunit/RhinoMocks stack.

Current Features

  • A session dictionary that uses memcachedon the backend. This is the real meat and potatoes.
  • Almost complete IDictionary implementation (The Values property and enumeration are not implemented). The default session in monorail doesn't seem to support the values property either. For that reason and for performance reasons I have no plans to implement the values property.
  • ICustomSessionFactory for CASTLE::MONORAIL

Planned/Missing Features

  • Optional DB persistence of sessions using activerecord/memcached fusion. Memcached storage isn't redundant and as a rule caches should be considered unreliable. I would like to give developers the option of turning on a DB persistence layer to ensure the reliability of the session state.
  • Cache provider for monorail. Abiity to easily add memcached caching into all of your service components.
  • Cache provider integration with ActiveRecord.

DOWNLOAD MEMCACHEDFORMONORAIL!

Other Memcached Goodies

I also intend to write a custom cache provider for ActiveRecord / Monorail. So stay tuned!

Writing User Stories the 5 Ws Way

Writing User Stories

Part 1

Part 2

Part 3

This is Part 2 of my "Writing User Stories series". Part 1 focused on some common pitfalls while writing a user story. In this article I intend to outline a simple but effective method of writing a user story using the 5 Ws.

A User Story is written by any User. The User Story should have a short but descriptive title and a longer narrative. The narrative should include the 5 Ws: Who, What, When, Where and Why.

  • WHO: Usually, the type of user (ie Admin, Student, Teacher)
  • WHAT: What the user in the WHO is going to do (clicks on the "new blog comment" button)
  • WHEN: "When" may describe a time or date or relative time (ie After logging in or after reading a blog)
  • WHERE: Where on the page or in the application.
  • WHY: What was the trigger for the user (user wants to suggest a change to the blog post)

Example 1: A student (who) clicks the new blog comment button (what) after reading a blog post (when) located at the bottom of the blog post (where) in order to make a comment about the blog post (why).

Discussion 1: Example 1 is pretty straight forward the who, what, when, where and why are well defined. Let's look a more complex example.

Example 2: An instructor (who) has determined which students to put into which discussion groups(why,when). Viewing the student listing for a class (where) clicks the checkboxs next to several student names, selects a discussion group from the drop down and clicks the add to discussion group (what).

Discussion 2: Example 2 is a bit more complicated. The "what" is a bit more protracted and the "why" and "when" are combined. For more complex stories it may be easier to list the 5 Ws first:

Who: An Instructor

What: Selects multiple students (at once) and adds them to a discussion group

When: After determining what students go in which groups.

Where: From the student listing screen.

Why: To get students into discussion groups.

In this format the when and the why come out a bit differently. Using the 5Ws method can greatly reduce the amount of time it takes for users to produce good stories. When all stories are written this way they become easier to estimate and the why element give valuable insight into what a user expects from the software.

Note: (Added 2 Sep 2009) In fairness to the SCRUM world this could also be expressed in SCRUM Style: As an instructor I want to add multiple students to the discussion groups from the student listing.

Feel free to suggest additional examples or make comments!

Wednesday, March 26, 2008

8 Things You can do Now to Improve Your Software

These aren't new ideas but they are true. The list below focus' on the things that organizations should be doing to help make their agile teams more productive.

  • LET USERS SUBMIT ISSUES! Let users submit issue tickets. They may be bugs, feature requests...whatever. You need to start tracking it. Your users will sense that you place value on their needs and you will have invaluable data for prioritizing new user stories.
  • GET USERS TALKING ABOUT YOUR SOFTWARE! Create a discussion forum or bullitin board for users to discuss the software they use. Creating a community around your software will help endear your users to it. Your engineers, product managers and other stakeholders should be encouraged to actively participate. Your team will gain great insight into how users are using the software.
  • MAKE A USER AVAILABLE! Developers should have real-live users to contact and ask questions. Most of what slows delivery of new features is a clear understanding of how a user will use them. Many new features end up looking nothing like what a user was asking for. These features sit around and remain unused.
  • TESTERS SHOULD BE USER EXPERIENCE EXPERTS! Put user experience experts on your testing team. If you don't have a testing team then become a user experience expert.
  • CO-LOCATE THE "WHOLE TEAM"! XP defines the Whole Team as the developers, testers and users. Studies show that communication is a major linch-pin in the success of software development. Anything you can do to improve communication will pay off.
  • EAT YOUR DOG-FOOD! Dog-fooding is the process of using your own software internally (eating your own dog food). If you use it then you will fix it!
  • RELEASE OFTEN AND EARLY! Your users like to see new features! These days you absolutely MUST give users a sense that your software has a future. Your organization should never consider a project "complete". You must work iteratively and release smaller chuncks of functionality.
  • ALLOW DEVELOPERS TO CHOOSE! The big boys know this one! Google does this and so does M$. Take advantage of your engineers' Creative Momentum and let them decide which project to work on. I would suggest that this can be done from iteration to iteration or release to release.

Wednesday, March 19, 2008

Programmer at War (in Iraq)

Most of those who read my blog are probably unaware that I am in Iraq. Normally, I am a Software Engineer/Chief Systems Architect for an Oklahoma based company. One weekend a month I am an Officer in the U.S. Army Reserves. Last summer I was deployed to Iraq.

I am a Platoon Leader in a Medium Truck Company. It's quite interesting how different my civilian and Army jobs are. In my civilian job we are always going forward with new developments. In my Army job, each mission tends to be organized similarly and entail doing the same task over and over again. Although, sometimes, the enemy has a say in that.

In some ways though, my jobs are very similar. There is a great deal to be learned from my experience in the Army. Being an "agilisto", I really value communication and people. In the Army, the most successful leaders learn to communicate very well and place the needs of their soldiers before all else.

On an agile project we plan and deliver value incrementally. This allows teams to embrace change. In the Army, it is understood that your enemy, the weather and the terain have the final say-so in all plans. Unfortunately, just as in the software engineering world, not everyone understands this concept and are unable to embrace change.

I dealt with this recently. We were planning for a mission. Our higher echelon wanted us to push out on a certain day. I felt we could do it. The Platoon Sergeants had a "feeling" that we could not push out until 2 days later. Usually , in the agile world, the nod would go to the Platoon Sergeants (the team).

99% of the time I would agree. Although, sometimes, we are presented with time sensitive requirements. I attended a workshop several years ago at AgileXP, that talked about Advanced Estimation. They suggested that, in some cases, you have to push the envelope to get requirements met on time. I felt this was a time to push the envelope.

Well, since I am the acting XO, I argued my point. Eventually, I was able to convince the Platoon Sergeants that we could "try" to meet the requested date. I suggested, we would keep our higher echelon (the customer) informed by passing up incremental updates and letting them know the risks upfront. As the date approaches, and things aren't looking good, we give them the option of changing the operational scope. If the scope is what they value most then we suggest they push the date to the right.

Ideally, we want to stay pragmatic and plan our time accordingly, but in a few cases we have no choice but to work out some solution. A common argument from the Platoon Sergeants was that our higher echelon would consider this a solid commitment and our hands would be tied if something went wrong. Surprisingly (not really) our higher echelon was very understanding and, like everyone in Army, was prepared for a contingency in which we were unable to meet the mission.

Sunday, February 24, 2008

Webtest Tool Round-up (Round 1:WatiN)

This is the first article in a series of reviews. I plan to test a few Open Source automated Web-Testing tools. As I complete my tests I will publish the results to my blog.

The Test Procedure

The world has gone Ajax and Web 2.0 crazy. Any tool that doesn't handle dynamically changing DOMs is an instant failure. So, I decided to use one of the most Ajax intense applications I know of, Gmail. Gmail uses Ajax and Iframes indiscriminately. The developers at google seem to obfuscate ALL the HTML element IDs which means that my web-tests have to do some real back-flips to find the buttons, hyperlinks and textfields required to send messages. I have no doubt that Gmail will adequately stress the tools in this line-up.

Test Steps

  1. Log in to Gmail
  2. Send an Email
  3. Check the same email
  4. Apply a Label
  5. Archive it
  6. Check to see if it is in the label category.
  7. Log Out

Round 1: WatiN (v1.2.1)


homepage | download


Test Date
17FEB08

Environment

Windows XP Home
Visual Studio 2005
.Net 2.0
IE 7

PROS
Easy Install
Integrates w/ Nunit
Good DSL
Integrates with most xUnit
Spreadsheet Tool
Recorder

CONS
IE Only until v2.0
Requires IE to be running.
The DSL could be more intuitive.

WatiN Project Overview
WatiN started life as a .Net clone of Watir. Rather than emulate a browser, WatiN uses the browser's own API to conduct web-tests. As of this writing, WatiN only supports IE7, but they promise that the 2.0 version will have FireFox support.

WatiN is technically just an API for controlling Internet Explorer, reading the DOM structure of web pages and triggering events on DOM elements. The library includes many utility methods (something of a DSL) that make scripting the tests ahead of time fairly trivial. Tests are written in you're favorite .Net language using your favorite .Net IDE.

For my tests I used the standard Visual Studio/Nunit stack that I use for unit testing. In short I created a class library of Nunit TestFixtures and used TestDriven.Net to start the tests.

Getting Started

When you download WatiN you have several options: a .Net 1.0 or .Net 2.0 installer or zip packages. I chose the .Net 2.0 installer. The install was pretty smooth. The installer, oddly enough, does not create any shortcuts for the documentation. Since WatiN is just an assembly and no shortcuts are created, the installer seems a bit superfluous.

WatiN has no command-line runner. As I mentioned above, WatiN is intended to provide an API/DSL for automating Internet Explorer. You write tests and run them using your favorite xUnit tools.

Before beginning the Gmail tests I worked through the "Getting Started" tutorial on the WatiN site. The tutorial walks you through creating a console executable that automates Internet Explorer. Unfortunately, I immediately ran into an error:

COMException: Retrieving the COM class factory for component with CLSID {0002DF01-0000-0000-C000-000000000046} failed due to the following error: 80040154.

After playing around with the code a bit I eventually discovered that IE must be running in order to get the console app to work properly. Once I started IE the Getting-Started app ran as expected. Internet Explorer opened and navigated to the appropriate pages. I could watch each click in the browser and it was kinda nice. Now I am ready to write some fixtures to pass my Gmail test!

Bring on the Gmail

I used FireBug's excellent HTML inspection tool to find the element IDs of each button and text field I would need. I wrote all the tests as Nunit TestFixtures. This was very easy since I already write TestFixtures for all my other projects. I used the test Setup method to launch an Instance of IE and closed IE in the TearDown method. WatiN provides pretty intuitive methods for controlling the browser.

The first thing that hits me while writing the fixture is the DSL. For the most part, I really like it. But, it could be re-factored a bit. In the example below, I wait for and then enter text into the email text box:

ie.TextField("Email").WaitUntilExists();

ie.TextField("Email").TypeText("******@gmail.com");


I would prefer to do something like this:


18 ie.TextField("Email").WaitUntilExists().TypeText("*****@gmail.com");



I also discovered that WatiN requires STA Threading. The web site doesn't hide this fact either. This required a small work around in Nunit. To guarantee STA Threading in Nunit (.Net 2.0) you must define it in your test assembly's config file:
  <configuration>
<configSections>
<sectionGroup name="NUnit">
<section name="TestRunner" type="System.Configuration.NameValueSectionHandler"/>
</sectionGroup>
</configSections>
<NUnit>
<TestRunner>
<!-- Valid values are STA,MTA. Others ignored. -->
<add key="ApartmentState" value="STA" />
</TestRunner>
</NUnit>
</configuration>
The Gmail tests went surprisingly well. The browser opened up. The appropriate items were clicked, textfields were filled in and my emails were sent. As with most tests, I found a lot of overlap in the web-tests. The login and logout routines were used quite often as well as other routines. In order to simplify the tests and practice good "Once and Only Once", I re-factoring the logoff and login into separate utility methods.

Other WatiN Tools

WatiN also has two other contributed tool projects; Wax and WatiN Recorder. With Wax you can write simple test suites in an excel spreadsheet (think FIT but easier) and run them directly. WatiN Recorder is a fairly robust recording tool that will help when you are writing tests for legacy code.

Final Thoughts About WatiN

I found WatiN to be quite impressive. WatiN includes about as much DOM search functionality as you could ask for. You can find anything including elements embedded in IFrames. You can trigger any event you wish. The DSL is fairly intuitive but if need be you can drop into XPath style searches. Keep your tests simple by searching for element IDs. Write your tests first and design the UI that the tests are written for. You can check out their API to HTML mappings.

For me the fact that the tests are written in .Net/Visual Studio was very nice. This allows you to leverage Visual Studio's intellisense and the full power of the .Net framework. Your testers may not find it as easy to write Nunit tests. I would recommend using Wax tests in those cases. It doesn't support the most complex features of WatiN but I would suggest your site should stay away from an overly complex UI.

While the tutorial project was refreshing in the fact that it has no dependencies, other than WatiN. I worry that those developers who remain uninitiated into the world of TDD will read this as the accepted method fr running WatiN. I would prefer to see a tutorial that employs a unit testing tool.

Most shops will have many reasons for implementing an automated web-testing tool. For me, the most compelling reason is the value it brings to your user experience design. By writing automated tests first, you are forcing your UI design to be simple. In short, the UI you create, to pass the tests, will do the simplest thing that could possibly work. This allows you to deliver "any kind of value immediately". The cool stuff (web2.0) can be added later AFTER the necessary stuff is done.

Here is the source of my test project. Don't forget to install Nunit and Watin!

Round 2?

For Round 2 I plan to test Selenium! So stay tuned....

Wednesday, February 20, 2008

Microsoft MVC or Is the Monorail off it's track?

For those of you who didn't know, Microsoft has been working on it's own MVC framework. I haven't used it yet since I am in the middle of testing several Web-testing tools for an upcoming article. That said, I have done a little research on the web and here are a few things that Monorail users may want to know:

  • Hammett, the founder of Castle::Monorail, has helped MS by making suggestions about their implementation. See his comment below:
    I'm not actively collaborating with MS regarding the MS MVC. I've offered help due to my expertise with complex web sites we have built using MonoRail, I was invited to fly to Redmond and analyze their product, and discuss things, make suggestions.
  • It's been suggested (in comments) that Monorail may become a wrapper for the MS Framework, if the MS MVC framework progresses well.
  • The MS Framework does support intellisense in it's views. Views are written in your .Net language of choice.
  • ASP.Net controls are available for use in Views.
  • The MS Framework does not forbid the use of ActiveRecord but with LINQ on the horizon developers may choose it. (I haven't played with the LINQ extensions yet)
  • Monorail is more time tested (and just works)! Also, the MS framework is closed source.
  • The MS MVC framework will allow you to use any xUnit framework and any Mocking framework you choose but, as of this writing the MS solution has nothing nearly as kewl as the Monorail BaseControllerTest.
  • I can find nothing about IoC support in the MS offering.
  • Some people believe the routing engine in the MS offering is easier to configure. I'll have to test this assumption.
I personally have no plan to switch to the Microsoft framework yet. I DO believe the MS Framework will introduce MS developers to how great MVC can be. I also believe that Microsoft will slowly position the MVC framework as it's preferred web-app architecture. The ASP.Net architecture, while successful, was a fundamentally flawed offering that should be abandoned quickly.

As Microsoft moves into this new territory we'll start to see a subtle change in how they do business. The .Net framework was their last major move ( just had it's 6 year anniversary). The latest signs of change are already out there; LINQ, extension methods, the MVC architecture. Things to look for now; Redesigning the Ajax.Net library, functional programming with F#, greater support for DSLs.

Some Interesting Links
Let me know if you have any other questions. I'll try to answer them as I play with the new framework.

Thursday, February 14, 2008

Getting the Data out of my Controller Tests

While working on PlanningPokerOnRails I started writing a unit test for my LoginController. The Monorail BaseControllerTest makes this easy. I am also using Rhino Mocks and Nunit. Here is the test:




The test is very simple. First, it sets a single recorded expectation that a Redirect will occur:

34 using (mocks.Record())

35 {

36 // First redirects to the index page

37 Response.Redirect("/Home/Index.rails");

38 }


Next, the playback is run and the code emulates a few things that users might do...like login with Request params for a ReturnUrl:

39 using (mocks.Playback())

40 {

41 Request.Params.Add("ReturnUrl", "/Home/Index.rails");

42 loginController.Login("dan", "danny");

43 }



Writing the Code to Pass this Test

Next I wrote the CardPlayer component (my user) and the LoginController. Seeking to do the simplest thing that could possibly work I merely had the CardPlayer inherit from the ActiveRecord base.


This made writing the controller easy, the ActiveRecord base has plenty of good methods for instantiating. I only have to call the FindOne method on the CardPlayer:


104 public static CardPlayer FindCardPlayer(string UserName,

105 string Password){

106

107 CardPlayer user = FindOne(NHibernate.Expression.Expression.And(

108 Expression.Eq("Username", UserName),

109 Expression.Eq("Password", Password)));

110 return user;

111 }


So why all the Problems?

I never intended to initialize ActiveRecord, in my tests assembly. I believe that test data should only be used for Acceptance Tests. It turns out that the test fails because no ActiveRecord config or initialization exists.


How do I solve this?

I forgot to implement good Dependency Injection. The way I would normally grab an instance of a component (like the CardPlayer) is through a service container (or repository). MVC architectures generally have two types of Model objects; Components (like the CardPlayer) and Services (like the CardPlayer Service I should have written). The services usually act like or wrap a repository of Components. In my opinion, ActiveReecord already provides the repository.

It turns out my solution is to write a CardPlayer Service container. This object will go into the IoC container (winsor) and be automatically injected into whatever controller requires it (like the LoginController). The service will use the ActiveRecordMediator to instantiate new CardPlayers and I can remove the ActiveRecordBase from my CardPlayer component.


Wait why does this help?

Well by forcing all instantiation to go through injected Services your tests can easily inject a Mock Service (I use Rhino Mocks) and tell the Mock to provide predefined instances of components. Since you have mocked the service layer you no longer need ActiveRecord in your tests!

Keeping the Data
Now that I've convinced you to write a service layer, I am going to tell you that you may not need it! While you can mock the Services going to your controllers you cannot easily get rid of ActiveRecord when testing the services. For most simple lookups a test may not be appropriate but in many cases your component lookup up and other operations will be non-trivial. For these cases you will want to test the service layer and you may have to initialize ActiveRecord.

You could decide to Mock the ActiveRecordMediator or you could use an approach similar to Oren's.


I'm Confused...

I admit that this is some advanced stuff. I promise to come back to this post and update it with more concise information.


Please leave comments on ways I can do this without a service layer. Thanks!

Wednesday, February 06, 2008

Is this a SourceForge Killer?

I doubt that the Google Code Projects Hosting will compete with SourceForge anytime soon but it does put Google one step closer to being the next SkyNet. I've been hosting one of my recent open source projects there and been quite pleased. Here are a few features of note:

  • It's FREE! (So is SourceForge by the way)
  • Provides a Subversion Repository with a really slick online browser. Check it out here.
  • Most of the interface is a just a frontend to a smart wiki. So you can use wiki code just about anywhere.
  • You can add users into different roles.
  • The Issue Tracker is relatively complete and fairly customizable since it's a highly specialized wiki. It allows you to assign tasks and track the workflow in your own way.
  • Plain old Wiki. For all your other needs there is a fairly robust wiki.
  • Package Download system allows you to upload your latest builds, documentation or whatever.
  • 100MB of storage for your source (you can request more).
  • Google account logins are used. As a matter of fact an Google Account login can be used.
  • Limited customization of the look and feel.
What has impressed me the most is it's barebones nature. No banner ads poping out. Searching is fast. Most of all, it seems to be growing in features. When I first started my project they had no source browser available. Now it has one of the best SVN browsers I have seen (FishEye would be better). I also feel like they are driven by user's needs. If enough people request a feature then they just build it in!

Finally, I really think that Google's approach to software development is very Agile. They always build the simplest thing that could possibly work and then add new features as users ask for them. We could learn a lot from this approach.

Saturday, February 02, 2008

New Pattern: CPT (Can't Polish a Turd)

I recently read a hilarious article, "Asshole Driven Development." The author, Scott Berkun, takes a cynical look at the abundance of acronyms in the software engineering field. Along the way he uncovers a few insights that, while very cynical, ring true. In addition to Scott's funny acronyms many users have added additional goodness. One anonymous post read:

How about CPT (Can’t Polish a Turd) development, This is where management cannot understand the need to stop and fix/clean up/refactor or start again.

I saw this post and wondered if we hadn't worked together! I've polished many turds in my time, a few were my own, and let me tell you...it's not easy. The fact is, these turds never really shine. Sure, sure...wet em down a bit...put em in the right light and they seem to shine. Heck...we have well paid people (some brilliant) that spend most of their time putting turds, in the right light. But, in the end a turd by any other name is still crap.

So why all this infatuation, with turds? In my experience it can be broken down into several very bad reasons:

  • Turd Love Affairs: This turd was once your next big thing. It would solve all the world's problems and make the company tons of cash. Somewhere along the line it got off track for various reasons (see the above article) and no one wants to admit it. These love affairs can be identified by an organization's death march development of a product that almost no one likes.
  • WSIA (We Sold It Already): WSIA is a surprisingly common problem. It's in the field and someone has paid for it. Because it's a turd it takes all your manpower to constantly tweak and thus no developers are available to work on a new version or refactor the old turd. Companies with this problem are usually immature and don't adequately plan for the software's lifecycle. (BTW: XP solves this problem since it assumes the software is never done)
  • Management Mistrusts the Engineers: I imagine them sitting around in a smoky room saying, "well those stupid nerds are whining about the XYZ again. Tell them we'll start on the new version in a month...that'll shut them up." Of course that month becomes 3 then 6 then the project is scrapped or the company goes out of business. "What!? no one wanted to buy a shiny new turd?!"
So, what can we do when we find ourselves in this situation? The first thing I always advise when someone feels workplace dissonance is to step back and remember, "everyone in the organization is probably doing what they think is the best thing for the product." This is important because we have to know that our peers and those above us are trying to make the project successful. People aren't always going to agree on the best plan of action.

The first thing you should do is try to understand why the organization is doing what it does....polishing turds. In most cases you just need to look at the project from another person's perspective. How long have they been working on this project? How emotionally attached are they? What fears do they have of losing customers? Once you understand the reasons for polishing turds you can begin to form arguments that support your course of action.

Finally, most turds started out as great ideas. Many of them can be fixed or re-written. Look for that original, good idea. In this way the true brilliance of the original great idea can shine through!

You can probably think of more reasons companies shine there crap...feel free to post a comment.

Saturday, January 26, 2008

Writing User Stories

Writing user stories should be easy. The reality is that most users don't know how to properly write a user story. Suppose a client asks you to write a wire transfer subroutine for systems at two different banks. (below I will highlight proper Stories in green and improper stories in red)
The client says...Write a wire transfer subroutine for systems at two different banks.
While a need is expressed, I would submit that this is not a User Story. What's been stated here could be the beginning of a vision statement, perhaps for the next release or the next Iteration. Let's try to distill this a bit.
So the client reconsiders and says.....System A should use a web-service exposed by System B to electronically wire funds.
A common pitfall in writing User Stories......getting too technical. The statement above assumes that web-services will be used and it may be perfectly logical to assume that they will be used, but let's examine what a User Story is really intended for. First and foremost is the "USER";specifically, what actions a user will perform and what she will experience in return. The examples above don't expose any User Experience information. Second, is the "STORY"; how the user gets to this point, what the user expects to happen.
A user, wanting to transfer money to account XXXXX, logs into bank A's system She selects the wire transfer option. A message asks her to enter the account number and bank to transfer to (bank B). The system then asks the user for the amount to transfer. After submitting the amount the user may log into bank B and see the new wire transfer as a deposit.
This example gives us more insight into how our client intends to use the system. This provides a better foundation for acceptance tests. It also doesn't assume any particular technology. XP projects have an evolutionary design. So, whether or not the system uses web-services is unimportant.

With our story in hand we can begin to develop acceptance tests. Once acceptance test are written we can begin the process of costing and eventually developing the story.

Further Discussion
While users should avoid getting too technical, users should also feel free to express common UI elements. In most cases they have a good idea of how they want to do their work. If you have user experience people or just smart developers you can help suggest alternatives. The point is to get insight into how a user "uses" your software.

What you DO want to avoid are stories that specifically suggest infrastructure or service elements. Things that throw red flags for me are terms like "Web Service", "Array", "SQL Query", "Stored on the Hard Drive".

Checkout Part 2: Writing User Stories using the 5Ws.

Here are some other good references on writing User Stories:

Tuesday, January 01, 2008

New Name....Same Crap

I've changed the name of my blog!!!! Not that this makes much difference to my audience. This blog will, from this day forward, be known as "Something Smells". While my critics may consider the cause for this change to be self evident (Garreth, Rob?), I made this change for wholly different, and much shallower, reasons.

First of all I no longer fancied the old name (yes, I just used the word fancied). Second, after long deliberation in the shower at the American Airlines Admiral's Club, I decided to really re-enforce the code smell concept. Oh and I changed the masthead....I think the new title goes better with the masthead.

Why more on code smell? Well, I won't be writing more about code smell, but I do think that my general technique for coming up with interesting topics (don't say a word) is somewhat similar to how we find code smell. Also, I think the art of hunting for code smell is a bit misunderstood. For better or worse, we all do it (hunt for code smell) and the sooner we accept it the better we can start to become at it.

Enjoy, comment and try to be kind!

Happy New Years!!!!!!