Archive for July, 2009

A Different Approach to FitNesse “Macros”

Tuesday, July 28th, 2009

My teammates Maykel Suarez, J.P. Erkelens and  Eddy Lara ought to be the ones blogging about this as they come up with these cool ideas, but I have the time and the inclination so I will. I hope they’ll read this and correct any errors I make.

I’ve used FitNesse since 2003 and obviously have not learned enough up to now!

We want our FitNesse tests to be DRY (Don’t repeat yourself), easy to maintain and easy to read and understand. Maykel and I were pairing on some FitNesse/SWAT tests this morning and found we needed the same test steps in more than one place. Maykel created this page under our “HelperMacro” area. Each FitNesse variable contains a SWAT test table.

!define NavigateToRatingScale (
!|SWAT |
|StimulateElement|Expression|

innerHtml:Performance Management;onclick:USGPM|onclick|A|
|StimulateElement|Expression|
innerHtml:Rating Scale |onclick|A|
)

!define NavigateToAddChangeRatingScale (${NavigateToRatingScale}
!|SWAT|
|StimulateElement|Expression|

innerHTML:Overall Review|onclick|A|
)

!define InputNumberOfLevels (
!|SWAT|
|SetElementAttribute|

Expression|Id:txtLevelNums|value |${NumberOfLevels}|INPUT|
|StimulateElement   |Expression|Id:txtLevelNums|
onchange|INPUT|
)

These are ‘macros’ defined as variables. Cool, huh? Notice that the second one, NavigateToAddChangeRatingScale, uses the first one, NavigateToRatingScale.

Here are examples of how we used these in test pages. First we include the page at the top of the test page;

!*> includes
!include -c <SuiteBookworms.HelperMacro.

RatingScales
*!

Then we can use whichever of the macros within RatingScales that we need at any time.

Navigate to add/change rating scale page
${

NavigateToAddChangeRatingScale}

When you view the test page in the browser, you see:
Browser rendering of navigate steps

It’s easy to understand what the test is doing, but we only have to maintain those steps on one page.

Here’s an example of setting the number of levels in a rating scale:

!define NumberOfLevels {5}
${InputNumberOfLevels}

In the browser view, this looks like:

Browser view of set rating scale steps

We have the kind of macros I’ve always been used to as well for example, a login macro:

{HomeUr}!*> login to $ with ${UserName} and ${Password}
!|SWAT|
|NavigateBrowser|${HomeUr\l}|
|SetElementAttribute|Id|ctl00_

Content_Login1_UserName|value|${UserName}|INPUT|
|SetElementAttribute|Id|ctl00_
Content_Login1_Password|value|${\Password}|INPUT|
|StimulateElement|Id|ctl00_
Content_Login1_LoginButton|onclick|INPUT|
*!

which are included in a test in the way to which I am accustomed:

!define UserName {hobbest}
!include <SuiteBookworms.HelperMacro.LoginMacro

I can’t articulate why I like the first, different approach, using variables to hold the macros, better than the way I’ve done it for years. It seems more streamlined to me, while retaining the ease of maintenance and understandability. Say sometimes you want to navigate to Page A, and other times you need to get to Page 2 which requires first going to Page A. If you’re including a bunch of one-line macros – one to navigate to Page A, one to navigate to Page 2 – your test gets real clunky looking.

Something Really Slick

Maykel, J.P. and Eddy used a similar technique so that a test could iterate through the same steps with different inputs each time. A variable is defined with a SWAT FitNesse table as its contents, including both a variable for the input value and a variable for the assert. Then it’s quick and easy to have multiple test cases using the same table. It took me a little while wo work out what they’re doing, but I love it.

!define AssertValidInputNumberOfLevels (
${InputNumberOfLevels}
!|SWAT|
|@AssertElement\${Exists}|

Expression|innerHtml:Invalid numeric value. Value should be a number from 1 to 99.;id:ctl00_errMsg|div |
)

This test expects an error message to come up, since 5.3 is an invalid value.

!define NumberOfLevels {5.3}
!define Exists {Exists}
${
AssertValidInputNumberOfLevels}

The next test expects that no error message will appear, as 42 is a valid value.

!define NumberOfLevels {42}
!define Exists {DoesNotExist}
${ AssertValidInputNumberOfLevel}

(there are several more of these with different values, some which expect an error message, some which expect no error message)

In the browser these look like this, so they’re perfectly easy for POs or anyone to read.

Slick way to use variable to iterate different inputs, expected results

Is this something everyone does and I just didn’t run across it before?

So How’s the Big Agile Working So Far?

Friday, July 10th, 2009

I’ve been working in this large agile setting (28 Scrum teams, 2 week sprints, 4 production releases per year) about 6 weeks now. It has confirmed my past experiences that success depends on having good people, and letting them do their best work.

In this short time, my 5-person team (3 programmers, 2 testers) has implemented a CI and build process in Hudson, which build our code as well as the full product, runs our automated unit and FitNesse/SWAT tests, deploys to our sandboxes, and reports results. We’ve finished several stories. We’ve had one sprint review, which went well. We’ve shaved a lot of yaks, which is to be expected for a new team and new employees (especially yours truly. The combination of telecommuting and lack of Windows and network expertise isn’t good). We work in pairs and trios, and stay in constant communication via Skype, chat, webcam and shared desktops.

Something new to me is having to depend on other teams for certain tasks. If we need something added to the database, we have to put a request into Jira and wait, though the turnaround is fairly quick. In order to get data changes into our own environments, we sometimes have to do a db refresh process that can take hours. We even had to wait a few days for another team to provide the new error message we needed. Before we can get final approval from our PO on a story, we have to request that the official company-wide build be deployed on one of our environments. I was frustrated by this, but we seem to be adjusting our rythym so that we fill in the delays with productive work.

To give you an idea what my job is like now, here’s a typical day in my work life:

Before 8:00 AM Mountain time – Get on group chat with rest of team. I’m the last one on – 3 are on Eastern time, and 1 is just faster at getting to work than I am.

8:00 AM – Attend Scrum of Scrums by conference call. This consists of general news that affects all teams, such a build problems, and polling each of 28 teams for impediments. It’s usually over in 10 minutes, amazingly.

8:15 – Join Skype call and webcam videos with rest of team. Pair with fellow tester (Chris McMahon) to write automated GUI/functional tests in FitNesse/Skype. We use VNC to share desktops.

9:30 – Standup meeting. We have an app that brings up a photo of “The Usual Suspects” with our heads on random bodies. I look good with a tattoo.

9:45 -10:00 – Watch the developers work on some unit tests, using LiveMeeting to see their desktop.

10:00 – 11:30 – Catch up on emails, maintenance tasks, and the like, and eat lunch.

11:30 – we’re all back on Skype, chat, webcam and desktop sharing.

11:30 – 12:00 One of the developers helps me with an issue I’m having with my local test environment, using VNC to take control of my desktop.

12:00 – 12:30 We discuss our acceptance tests with the PO. The other teams he works with put acceptance tests in spreadsheets and attach them to the story “card” in Jira. We are writing the acceptance tests together in sprint planning, in BDD style, directly onto the FitNesse wiki pages where we’ll also write the automated tests. Then Chris and I automate the tests. The PO is fine with our approach, he can easily understand the tests, and has found some test cases that we missed. However he’s concerned that we’re deviating from the “standard”. So far, nobody has objected to our writing tests in the FitNesse wiki, and it works so well for us, we’re going to continue.

12:30 – 1:30 Pair with Chris again to update the narrative acceptance tests for the stories based on the PO’s input, and write additional automated tests.

1:30 – 3:00  The database change needed for the story the developers finished yesterday is ready. Chris and I update our local databases, deploy the new code, run the FitNesse/SWAT tests, and do exploratory testing of the new functionality. Whenever we run across an issue, we show it to the developers using VNC desktop sharing.

3:00 – 5:00 Everyone else is done at 3:00, so I’m on my own. I update the wiki with notes about how to use the system that allows us to add test users. Then I do some additional exploratory testing on the story we worked on earlier. Next, I look into a problem we were having in a SWAT test. I had emailed the internal user group about it, and had some responses with suggestions to try. I’m able to get this working, and check the test in. I make sure our task board is up to date.

As time goes by, I spend less time on things like getting my environment working or solving network problems, and more time doing productive work. I’m also starting an internal company testing community, so we can all share ideas. My teammates and I are blogging internally about how we are writing and designing tests, and how we’ve implemented our CI and build process. We hope the ideas that work for us will spread to other teams, and we’re also looking at what other teams to and adopting their good ideas.

So far, so good!