Jay Harris's blog on coding .Net, automation, and improving quality through code. RSS 2.0
 Wednesday, July 26, 2006

Many .Net developers that have experience in presentation-layer development have previous exposure to this one, but to those who haven’t, I must share: Request.ApplicationPath is evil! Request.Application path should never be used. Ever. I hate it!

It’s misgivings are most commonly exposed when concatenating strings to the end of it to create a URL of some sort.

sURL = Request.ApplicationPath & “/someDirectory/somePage.aspx”

This is evil. Neither will work in all situations due to the method’s inconsistency with trailing slashes.

If the application root is in a sub-directory, say “http://server/myRoot/index.aspx”, then the appPath is “/myRoot”. Note: there is no slash at the end, and the above sURL gets a value of “/myRoot/someDirectory/somePage.aspx”.

If the application root is not in a sub-directory, say “http://server/index.aspx”, then the appPath is “/”. Note: there is a slash at the end, and the above sURL gets a value or “//someDirectory/somePage.aspx”. In this case, rather than requesting “http://server/someDirectory/somePage.aspx”, wonderful Internet Explorer requests “http://somedirectory/somePage.aspx”. (I don’t fault IE for this. I commend it. It is actually one of the few cases where IE doesn’t kludge together a band-aid for Developer mistakes.)

So, don’t use Request.ApplicationPath. Ever. With no exception. You could make a method, perhaps MyUtilities.ApplicationPath, that checks to see if the return contains a trailing ‘/’, and if it does, give it the axe. This will turn your domain-root appPath to an empty string. Use your new method rather than Request.ApplicationPath, and all will be well with the world. But, don’t do it! Don’t make a new method. That just continues the evilness.

Use Page.ResolveURL(”~/someDirectory/somePage.aspx”) or the counterpart Control.ResolveURL if you want it to be relative to the control’s location. This is the only scenario you should use. ApplicationPath is evil!

Wednesday, July 26, 2006 7:19:23 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0] -
ASP.Net | Programming
 Saturday, June 03, 2006

I’m finally catching up on some of the blogs that I haven’t checked out in a while. I came across an intriguing post (on 04 March 2006) by Daniel Grunwald on the #develop teamblog. It seems that he created a tool to analyze Subversion’s ‘Blame’ output to check the ‘Blame’ data from #develop repository and tell what percentage of the code was committed by each contributor. (Incidentally, he has contributed 27% of the application, according to the post’s screenshot.)

My analyzer program gets the person who committed each line of code. Additionally, it searches log messages for the term “patch by” and uses that name instead.

He admits that the tool may need some love, and that some of his parameters are hard-coded, but it may be worth a look. I’m curious to see the contribution stats on our LMS.

Additionally, it is coded in Boo. I’ve been meaning to check out Boo, and getting Daniel’s app working against our configuration might serve as a great introductory Boo task for me.

Saturday, June 03, 2006 9:05:29 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0] -
Programming | Reviews | Source Control
 Wednesday, May 31, 2006

Most of our VS.Net solutions contain hundreds of files (classes) organized neatly into dozens of folders (namespaces), but despite all of this organization the vertical content size of the Solution Explorer can get quite large. Finding a particular file when the majority of the tree is expanded is tedious and time-consuming, considering it should be a simple effort of less than five seconds. Fortunately, all of this is solved by the click of a button (assigned to handy macro).

The most useful macro for Visual Studio that I have ever encountered (and in the running for most useful VS tool, period) is the CollapseAll macro authored by one current and one former colleague, Dennis Burton and Mike Shields. In a quick XP effort, Dennis and Mike created a handy macro that recursively collapses the entire Solution Explorer tree down to just the solution and its projects.

With the tree collapsed, it is easy to find that desired file.

CollapseAll Macro for Microsoft Visual Studio.Net 2003
Dennis Burton & Mike Shields | Published with Permission

Imports EnvDTE

Imports System.Diagnostics

 

Public Module CollapseAll

 

    Sub CollapseAll()

        ‘ Get the the Solution Explorer tree

        Dim UIHSolutionExplorer As UIHierarchy

        UIHSolutionExplorer = DTE.Windows.Item(Constants.vsext_wk_SProjectWindow).Object()

        ‘ Check if there is any open solution

        If (UIHSolutionExplorer.UIHierarchyItems.Count = 0) Then

            ‘ MsgBox(”Nothing to collapse. You must have an open solution.”)

            Return

        End If

        ‘ Get the top node (the name of the solution)

        Dim UIHSolutionRootNode As UIHierarchyItem

        UIHSolutionRootNode = UIHSolutionExplorer.UIHierarchyItems.Item(1)

        UIHSolutionRootNode.DTE.SuppressUI = True

        ‘ Collapse each project node

        Dim UIHItem As UIHierarchyItem

        For Each UIHItem In UIHSolutionRootNode.UIHierarchyItems

            ‘UIHItem.UIHierarchyItems.Expanded = False

            If UIHItem.UIHierarchyItems.Expanded Then

                Collapse(UIHItem)

            End If

        Next

        ‘ Select the solution node, or else when you click

        ‘ on the solution window

        ‘ scrollbar, it will synchronize the open document

        ‘ with the tree and pop

        ‘ out the corresponding node which is probably not what you want.

        UIHSolutionRootNode.Select(vsUISelectionType.vsUISelectionTypeSelect)

        UIHSolutionRootNode.DTE.SuppressUI = False

    End Sub

 

    Private Sub Collapse(ByVal item As UIHierarchyItem)

        For Each eitem As UIHierarchyItem In item.UIHierarchyItems

            If eitem.UIHierarchyItems.Expanded AndAlso eitem.UIHierarchyItems.Count > 0 Then

                Collapse(eitem)

            End If

        Next

        item.UIHierarchyItems.Expanded = False

    End Sub

 

End Module

Based on code from Edwin Evans

Here, the macro is so popular that it is a part of our default developer’s build for every new machine, and is conveniently assigned to a toolbar button. The default button icon list contains an Up Arrow (in the Change Button Image menu when customizing the toolbar) that seems quite appropriate. That little button has saved us all from a lot of pain, five seconds at a time.

Wednesday, May 31, 2006 9:19:55 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0] -
Programming | Tools
 Tuesday, May 02, 2006

Recently, here at the ranch, we have been experiencing a few issues with Internet Explorer’s javascript functionality. It’s not that IE is doing anything wrong, but rather that it performs unexpectedly. When opening a new window in javascript [window.open()], the height and width dimensions are relative to the size of the canvas / stage / content area (depending on what discipline you are from), all commonly referred to as innerHeight and innerWidth. However, when you execute a resize function in javascript [window.resizeTo()], the height and width dimensions are relative to the size of the entire window, including any chrome, commonly referred to as outerHeight and outerWidth.

Thus, if you create a window (500px x 300px), then resize it to (505px x 305px), the window will actually get smaller, since the chrome adds more than 5 pixels to height and width.

The problem: SCOs (Courseware) can be of any size, depending on the specifications, requirements, and whims of the original clients and developers. To keep courses in their most visual-appealing state, we need to size the content window to precise innerHeight and innerWidth pixel dimensions. Due to our site’s design, the link that launches the Course Shell window has no idea what the size of the SCO is. The Course Shell (LMS) knows how big the SCO is, but it is loaded into the Course Shell window, which is obviously done after the window is created and initially sized. We need a way to size the window to content-dimensions after the window is created.

The catch: Internet Explorer has no native support for innerHeight and innerWidth, let alone a way to resize to those dimensions. Furthermore, the difference between the inner- and outer-dimensions due to window chrome can change from OS to OS and from theme to theme. For example, in Windows XP’s default “bubbly” themes, the title and status bars are much taller than in Windows “Classic” themes. Internet Explorer has no native way to identify the difference in inner- and outer-dimensions, making it difficult to resize to an inner size using an outer size command.

I hacked together some (perhaps mediocre, but still effective) javascript to resize a window to its inner dimensions rather than the outer dimensions, regardless of the amount of chrome that the OS adds.

HTML

<div id=”resizeReference”

    style=”position: absolute; top: 0px; left: 0px; width: 100%; height: 100%; z-index: -1;”>

    &nbsp;

</div>

Javascript

function resizeWindow(iWidth, iHeight){

    var resizeRef = document.getElementById(’resizeReference’);

    var iOuterWidth = iWidth + 10;

    var iOuterHeight = iHeight + 29;

 

    if (resizeRef) {

        var iPreWidth = resizeRef.offsetWidth;

        var iPreHeight = resizeRef.offsetHeight;

        window.resizeTo(iPreWidth,iPreHeight);

        var iPostWidth = resizeRef.offsetWidth;

        var iPostHeight = resizeRef.offsetHeight;

        iOuterWidth = iWidth + (iPreWidth-iPostWidth);

        iOuterHeight = iHeight + (iPreHeight-iPostHeight);

    }

    window.resizeTo(iOuterWidth, iOuterHeight);

}

The HTML tag creates a hidden DIV whose height and width match the window. This provides innerHeight and innerWidth. The JS takes the dimensions of that DIV and resizes the window to those measured dimensions. Since this transfers the inner-dimensions to the outer-dimensions, this provides the exact size of the window chrome. We can now resize to the input parameter height and width, plus the height and width of window chrome, to give us a resize to inner-dimensions.

Execute resizeWindow no sooner than below the closing Body tag, so that the DIV is rendered.

It is a bit of a hack, but it works for now.

Tuesday, May 02, 2006 9:23:23 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0] -
Programming | JavaScript
 Wednesday, February 15, 2006

NAnt hates .Net’s resource files, or .resx. Don’t get me wrong–it handles them just fine–but large quantities of resx will really bog it down.

Visual Studio loves resx. The IDE will automatically create a resource file for you when you open pages and controls in the ‘designer’ view. Back when we still used Visual SourceSafe as our SCM, Visual Studio happily checked the file in and forgot about it. Now, our 500+ page application has 500+ resource files. Most of these 500+ resource files contain zero resources, making them useless, pointless, and a detriment to the build.

This morning I went through the build log, noting every resx that contained zero resources, and deleted all of these useless files.

The compile time dropped by 5 minutes.

Moral of the story: Be weary of Visual Studio. With regards to resx, VS is a malware program that’s just filling your hard drive with junk. If you use resx, great, but if you don’t, delete them all. NAnt will love you for it.

Wednesday, February 15, 2006 11:31:31 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0] -
ASP.Net | Continuous Integration | NAnt | Programming
 Friday, October 28, 2005

“It compiles! Ship it!”

Microsoft has sent Visual Studio 2005 to the printers. That brings .Net 2.0 to the table in all of its glory. The official release date is still November 7, and though it is available now to all of us MSDN subscribers (though the site is too flooded to ping, let alone download), there is still some question on if the media will be ready in time to go in all of the pretty little VS05 boxes at your local Microsoft store.

Friday, October 28, 2005 12:40:03 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0] -
ASP.Net | Programming | Tools
 Monday, August 08, 2005

The default settings of NUnit, TestRunner, and Test Driven Development all want different copies of the app.config at different locations. If ProjectName creates ProjectName.dll, then NUnit wants ProjectName.config, TR wants ProjectName.dll.config, and TDD wants TargetDir\ProjectName.dll.config. This is a lot of work to put in the post-build event of every unit test project, and can be even more work when another testing tool comes along that wants yet a new config filename. The best way to manage all of these file copies is through a common post-build event call.

Many probably opt for a NAnt script, but we found that passing in the required paths can sometimes cause NAnt to get confused, and it won’t properly parse the parameter listing. So, we went with a command file, instead.

CopyConfigs.cmd

rem for nunit

copy “%~1App.config” “%~1%~2.config”

 

rem for testrunner

copy “%~1App.config” “%~1%~2.dll.config”

 

rem for testdrivendevelopment

copy “%~1App.config” “%~3.config”

VS.Net Post Build Event

call “C:\MyPath\CopyConfigs.cmd” “$(ProjectDir)” “$(ProjectName) “$(TargetPath)”

VS.Net already includes a series of NAnt-like properties for project names, project directories, target [assembly] filenames, etc; these come in handy for creating a universal script. Placing the path references in quotes allows for spaces and other characters (Except more quotes) in the path. Executing the command file through a call allows us a little more versatility with the argument references (%~1 removes the surrounding quotes from the argument value, allowing us to append a few together without jacking the subsequent path).

Monday, August 08, 2005 12:48:20 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0] -
ASP.Net | Programming | Task Automation
 Wednesday, July 27, 2005

Scott Hanselman is my new hero. He is filling the hole—the one thing preventing Watir from becoming real competitor in the automated functional test market: script recording. Watch out Mercury; by creating WatirMaker, Scott is opening the flood gates, and Watir is going to come pouring through.

This changes everything.

I started out my career as a developer, but as I noted in an earlier blog, I get much more enjoyment from breaking things than I do building things, so I jumped ship. With my development experience I can delve in to making some rather wicked scripts for QTP, LoadRunner, and lately, Watir. However, my testers don’t share my skill set. My biggest hurdle in ousting QTP and making Watir our standard is the lack of recording; I can not expect every tester to start coding away in Ruby. It should come as no surprise that when I opened Scott’s blog this morning, I was so excited that I nearly wet myself.

It is a work in progress, but soon Scott hopes to have a fully functional recording tool for Watir. With WatirMaker, my testers can hit a button and start clicking away in IE; the tool will happily watch like a little kid on the sidelines, learning every move. My testers can all adopt Watir with open arms, and we can wave goodbye to that Mercury maintenance contract.

The only thing left to say is: “Scott…thanks!”

Wednesday, July 27, 2005 12:55:50 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0] -
Programming | Testing | Tools | Watir
 Friday, July 22, 2005

Scott Hanselman has a good post today about the HttpOnly cookie attribute. It secures the cookie from access via the DOM. “The value of this property is questionable since any sniffer or Fiddler could easily remove it. That said, it could slow down the average script kiddie for 15 seconds.”

Read Scott’s full blog entry.

Here’s the meat-and-potatoes of what Scott came up with; it’s for your global.asax:

protected void Application_EndRequest(Object sender, EventArgs e)
{
foreach(string cookie in Response.Cookies)
{
const string HTTPONLY = ";HttpOnly";
string path = Response.Cookies[cookie].Path;
if (path.EndsWith(HTTPONLY) == false)
{
//force HttpOnly to be added to the cookie
Response.Cookies[cookie].Path += HTTPONLY;
}
}
}
Friday, July 22, 2005 1:01:58 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0] -
ASP.Net | Programming
 Monday, July 18, 2005

Years ago, way back when the web first started to become universally popular–and I’m talking about popular with all demographics and not just geeks like me–there was the 30KB rule, and it was a cardinal sin to break it. The entire request, including your HTML, your images, and everything else your page contained, had to come in under 30 kilobytes. Most homes were surfing through the web on a 28.8kbps modem, which pulled 30KB in about 10 seconds. Beyond that 10 seconds, and your users were too bored, frustrated, or confused to wait another moment, and were off to pursue the next site in your WebRing. 30KB. That was the limit. It was universally accepted. And, save a few ransom notes on GeoCities, everyone followed it.

Whatever happened to the 30KB rule?

Today constantly see pages that are 100KB or more, and those are even compressed responses. Everyone is so caught up in broadband, and developing on their 100mbps LAN, that they forget about the little guy. What about grandma? My poor grandma still surfs the internet with a good ol’ 57.6kbps modem. And even if she could pull off that speed (US restrictions limit to 53, max) it would still take 20 seconds to yank that monster through the pipe. My poor grandma shouldn’t have to wait that long.

Often times if I wade through the muck that makes up the offending request, I see 60KB style sheets, references to JS files that contain functions not even used in this page, big honkin’ j-pegs, useless JavaScript comment blocks that easily pile on a few K, and my nemesis: ViewState. (I hate ViewState. ViewState hates me. It’s a good relationship.)

My company is making an application, and the primary audience is a bunch o’ satellite offices stuck in the 20th century. They plug in to a whopping dual ISDN which maxes out at a whopping 128kbps. That’s 16KB/sec for you young folk. That 100KB page will take 7 seconds to pull across the wire. Toss that fact in to the 10-second rule, and you only have 3 seconds to process the request. I have visions of little ones and zeros flying towards the light screaming “We’re not gonna make it!!”

Get a haircut. Trim those bushes. Bring that response size down a few K. Here’s a few ways to tame the beast:

Reduce ViewState
“Remember that ViewState is evil.”
It adds a big, encrypted string to a hidden form variable in your HTML. However, this beast gets bigger with every web control that you have. Explicitly turn off viewstate on every control that does not use it, or better yet, turn of viewstate for the entire page. Of course, realize that the not-dot-net crowd is laughing at you while you do it.

Eliminate Comments in Release Code
“Keep your comments to yourself.”
It is great to comment your code. It is fabulous. Every developer should bow to you if you comment your code, because not enough do it themselves. However, unless it is compiled code or in code-behind that isn’t sent to the client, it has to go. You can keep your comments in the version stored in SVN, VSS, or whatever your favorite source control tool is, but your release code should contain no client-side comments. Your client doesn’t read them, their browser doesn’t care about them, and all it does is slow everything down, so give them the axe. Your network administrator will love you for it, too.

Optimize Images
“Phenomenal, Artistic Imagery, Itty-Bitty Living Space.”
Compress your images. Get them as small as your image editor can get them (small: file size, not small: pixel size) without degrading the image beyond acceptable levels. And if you use a GIF, lower the number of colors (which will lower the number of bytes). When your images get smaller, people get happy.

Eliminate Whitespace
“One Program: One Line of Code.”
This is a cheap trick to squeeze out those last few bytes. If you have a news article that’s 9 pages long, open it up in notepad and turn off word-wrap, it becomes one big long line that stretches out forever and is impossible to read. But, your browser could care less. Take out all of the horizontal white space that you use to make your code readable, and then take out all the line breaks to make your HTML one big line, and your browser couldn’t tell the difference. However, you just chopped a few more bits.

Enable Compression
“GZip it, and GZip it good.”
If all else fails, and you’ve gotten your pages as whittled down as you can, and they are still big, compress it. Then again, even if they are small, compress it. It will add a few more CPU cycles on both ends to compress and decompress the response, but the time lost is greatly countered by the time saved in data transfer. Typical compression is around 40%, which takes that 100KB file down to 60KB, and saves my grandma nearly 8 seconds. She’ll give you a kiss and squeeze your cheeks for that one.

Monday, July 18, 2005 1:10:35 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0] -
Programming | Usability
 Friday, July 15, 2005

In case you haven’t heard of it yet, Watir is the greatest thing to hit automated functional testing since…well…ever. Watir (pronounced “water”), or Web Application Testing In Ruby, is an open source automated functional testing tool powered by Ruby. My company has been living off QuickTest Pro, and it is not much of a leap to Watir. Much like QTP, it automates an instance of Internet Explorer and navigates its way around your web site, however unlike QTP, it doesn’t hijack your computer when you do it; with Watir, the IE window doesn’t have to be the foreground window, so you can get something else done while your test is executing. Watir also allows various checks much like QTP, but though programming includes the capability of checking much more, such as object hierarchy or object style. (Yes, Watir can make sure that your validation messages are red!)

Your money manager will love Watir, too. Our switch from QTP will save us thousands of dollars per year from Mercury’s annual support costs. For a moment, I think our company president’s pupils turned to dollar signs like a cartoon.

If you are like me, and spend your QTP days in ‘Expert’ view (Source code), you will pick Watir up quickly. I even find it better than QTP. Additionally, since it is just a source code file, edited in Notepad if you like, it can be stored in your favorite source control application AND (this is a big ‘and’) your developers can execute the automated tests themselves without proprietary software like QTP. Its easy integration with NUnit will also tie your automated functional tests in with applications like Nant and CruiseControl.

More Information
Read all about Watir.
Read Bret Pettichord’s (a Watir creator) blog entry about Watir.

Friday, July 15, 2005 1:19:59 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0] -
Programming | Testing | Tools | Watir
 Friday, July 01, 2005

I like to think that my development team is full of competent and capable people, and not one of them was aware of this: Internet Explorer has a limitation on the number of cookies per domain (MSDN Reference).

From: “Number and size limits of a cookie in Internet Explorer”
http://support.microsoft.com/default.aspx?scid=kb;en-us;306070

Microsoft Internet Explorer complies with the following RFC 2109 recommended minimum limitations:

  • at least 300 cookies
  • at least 4096 bytes per cookie (as measured by the size of the characters that comprise the cookie non-terminal in the syntax description of the Set-Cookie header)
  • at least 20 cookies per unique host or domain name

We recently started having random authentication problems with our eLearning platform. It turns out that our application, plus everyones favorite Single-Sign On, plus SCORM, plus courseware created by third-party vendors created enough cookies to blow the top off the cookie jar. IE can only handle 20 cookies. Create a 21st cookie, and the oldest cookie is given the axe, which is generally an authentication cookie, a session ID, or some other very important cookie (as the ‘elders’ usually are).

So, be aware of your cookie jar. Monitor the number of existing client-side cookies in use when testing that new application. Harass other developers if they start using too many. Keep yours hands out of the cookie jar!

Oh, and don’t forget to encrypt them (but that’s a different post topic).

Friday, July 01, 2005 1:21:40 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0] -
Programming
 Friday, May 20, 2005

It’s not all about Internet Explorer any more. Yet, I am surprised at the number of web houses still coding specifically to IE. Much to my dismay, even my own company does it. Though we have a little bit of an excuse—our client only supports IE in their organization, and the app is internal—it still bothers me that we are abandoning everyone else.

New figures released a week ago place IE’s market share at 89%. That means more than 1 in 10 users are not using IE. (Read the Article) By coding specific to Microsoft, you are abandoning 11% of your potential users. That is astonishing and disturbing.

Pay particular attention to Firefox. Its user-base is growing exponentially, and doubling every 9 months. I’m a fan of the application. It is much easier to use than IE, and much more solid. I’ve converted all of my friends and almost all of my family. I even have my in-laws using Firefox. (Get Firefox)

As the IE behemoth continues to fall, you and your organization should be paying more and more attention to standards and multiple-browser testing. Check that your HTML is compliant, and test your sites in at least IE and Firefox, if not others. Don’t force your users to use a particular browser; chances are that if they can, they will just go somewhere else for their information.

Friday, May 20, 2005 12:34:48 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0] -
Business | Mush | Programming
 Tuesday, May 10, 2005

So your wonderful little creation is finished, and it does exactly what it was designed to do. But, have you prevented it from doing what it’s not supposed to do?

Enter the forgotten art of negative testing. This is the safeguard from user error, malicious attacks, and blatant developer oversight. Negative testing is taking your calculator application and trying to add “Hello” and “Goodnight”. Negative testing is trying to supply an invalid email address–.anything@something.q–into your mailing list form. Negative testing is trying to cause a buffer overflow on your lead-developer’s computer because you were able to sneak in a script injection.

The key word here is “try.”

If everyone has done their job, you will get nowhere. Unfortunately, rarely is this job done right. In 3 minutes I could considerably alter my best friend’s blog, and he doesn’t even know it. In 10 minutes I could corrupt the online database of a Fortune 500’s web site–both company and URL to remain anonymous. And, what scares me the most, in 20 minutes I could download the entire database of a certain benefits company, including the complete identity–SSN included–of a few thousand people.

For years, I have been paid to break things as much as build them. When that calculator finally adds 2 and 2 correctly, don’t be satisfied. Try to add “Hello” and “Goodnight”. Will it give you a neatly handled error message informing you that it couldn’t complete the procedure, or did it return a fatal exception and die a miserable death because it expected a Double and you gave it a String? Optimally, it shouldn’t allow you to even type characters into the input area unless you are working in hex; even then, only A-F.

If instructions tell you to do one thing, enter the opposite. If you see a value in the URL, change it. If a field asks for an integer between 0 and 5, try 0, 2, 5, -1, 9, 3.5, and “Q”, and see how it handles “unexpected inputs.” If a querystring is “?UserID=6″, change the 6 to a 7, to see if you get information on User 7, and try invalid items like 3.5 and “Q” to see if it fails on unexpected inputs. If a client-side cookie has a value of “User”, try changing it to “Admin” or “Administrator” and see if your access-level is increased.

Find the weaknesses, find the holes, and find the bugs so that they can get fixed. You are the demolition man. You get paid to blow things up. Do it. Do it with purpose. Pretend you are a hacker trying to get into the system. Pretend you are a teenager-hacker-wannabe trying to screw with the system. Pretend you are a grandma that doesn’t know what to do with the system. Do all of the things that you aren’t supposed to do to the application and do them on purpose, because if by ignorance or intelligence, your users will find what was missed.

Tuesday, May 10, 2005 1:55:41 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0] -
Programming | Testing
 Saturday, May 07, 2005

All too often, we forget about usability. We get so caught up in fixing functionality and enhancing performance that we forget about the most important part: how easy is it to use this thing we have just created. Sure. That new super-gigantic Humvee will go in any direction you want, can climb a 21-inch vertical, and can pull small houses with ease, but who cares? It drools at the sight of a gas station, it is impossible to parallel park, and most importantly, how do you expect grandma to climb in and out of that thing?

What would grandma do?

Imagine that poor old lady trying to raise her little leg up onto the running board, and then pull herself up into the cab with those little arms. She’s a GRANDMA! She isn’t 20 anymore. Or 50, for that matter. We forget about grandma in our software testing, too. How would she use that application you just made? How would she react to that detailed error message your creation just spit out?

My poor father; he just got his first computer, and I’ve been trying to teach him how to do instant messaging. He knows enough about Windows XP to be familiar with the big ‘X’ in upper-right corner. Click it and everything goes away. But, Trillian is different. In the upper-left of the contact list is an upside-down triangle that minimizes the window to the system tray. Right below that is a little small ‘x’. Unfortunately, that ‘x’ removes your contacts from within your Trillian window. You have to play around in your ‘View’ menu to get the list to come back, again. However, my father doesn’t know upside-down triangles, and he certainly doesn’t know about the ‘View’ menu, yet. He just knows the ‘x’. So that’s what he does. He clicks the little ‘x’. And every time he does, his contacts go *poof*, and he has to call me to help him get his contacts back. My grandmother would do the same thing. I don’t think Trillian did any usability testing on that feature.

What would grandma do? You know that she’s going to want to click the ‘x’, no matter what, because the ‘x’ is what she knows, just like my father. So why not make the upside-down triangle an ‘x’? It can still minimize to the system tray. The ‘x’ isn’t a cast-in-stone rule that the application must quit all-together. If you don’t believe me, try the ‘x’ on your MSN Messenger window. It minimizes to the system tray. Why did Microsoft brake their own tradition? I bet what they really did was a little usability testing, and discovered that new users always want to click the ‘x’. To new users, the ‘x’ is a big “CLICK HERE” sign to make that window go away. They don’t care if it closes; new users just want it to go away. And if she were still around, Violet–my grandmother–would always be a new user when it came to computers. Just make the window go away. Like clearing the dishes after dinner: it didn’t matter if you threw the plate out, just get it off the table.

So, we have this problem. Now, what do we do about it? Ask yourself:What would grandma do? “Fatal error: Userdata insert failed. Connection to database unavailable. \\jedimaster\yoda\greenlightsaber\sqlserver2000 not found.” If she saw that, what would grandma do? Stare blankly at the computer? “Unable to save your contact information. Please try again later.” Grandma can understand that. So, think of your grandma when you test that new application. Think of your grandma when you write your error messages. Think of grandma when you draw pretty graphics or design a button icon. Your program will be much more friendly, and much easier to use. Even grandma could use it. If you need help remembering, put a picture of grandma on your desk at work, right next to your monitor. And if you don’t have a grandma, substitute that sweet old lady down the street that bought all of your raffle tickets when you were 12 and baked you cookies because you were such a good little kid.

Remember grandma.
What would grandma do? She’d tell you that she’s proud of you, because that’s what grandmas do.

Saturday, May 07, 2005 7:53:33 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0] -
Programming | Usability
 Thursday, May 05, 2005

Imagine a world where no one had a name. Instead of John Doe, you would know “the 185lb, long black haired, 5-foot-11 guy that lives on the corner of 43rd and 5th.” What happened if that guy got a crew cut? To his close friends, he would now be “the 185lb, short black haired, 5-foot-11 guy that lives on the corner of 43rd and 5th.” But not-so-close acquaintances, ex-girlfriends, the florist, cabbie, and the IRS would all know him as his former name. Few would know this new guy. There would be confusion when one group tries to talk to the other about this guy. What happened if he gained a few pounds, too, and moved over to 54th? No one would know who he was, anymore.

That’s why we have names. They are a constant in a dynamic life. They are the dependable value that gives the world security when all else changes. If John dyed his hair blue, moved to Phoenix, and got a sunburn, people would still know who he is. He’s John Doe.

ID attributes do for web objects what names do for humanity. In a world where static web sites are the ones your 12-year-old makes on Geocities, automated QA tools need a little help. Do you have a link to your favorite news site? Today, your automated tool can find that link to <a href=”http://www.cnn.com”>CNN.com</a>, but tomorrow’s <a href=”http://www.msnbc.com”>MSNBC</a> link is lost; the tool is still looking for CNN. So, give the link an ID. That’s its John Doe. The tool can find your link whether it is <a id=”favNewsLink” href=”http://www.cnn.com”>, <a id=”favNewsLink” href=”http://www.msnbc.com”>, or any other link that floats your boat. All it has to do is look for the name. favNewsLink. John Doe.

Be nice to your automated tools: give your web objects a name. Rename your ‘Comments’ link to ‘Feedback’? John Doe. Change your image of your dog to an image of your cat? John Doe. Multilingual site with translated text? John Doe. It will help you automate your QA process, and you will spend less time retooling your automation scripts and more time downing that Corona. Just don’t forget the lime.

Happy Cinco de Mayo.

Thursday, May 05, 2005 2:01:29 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0] -
Programming
Navigation
Archive
<May 2008>
SunMonTueWedThuFriSat
27282930123
45678910
11121314151617
18192021222324
25262728293031
1234567
Blogroll
About the author/Disclaimer

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

© Copyright 2008
Jason Harris
Sign In
Statistics
Total Posts: 63
This Year: 3
This Month: 1
This Week: 0
Comments: 1
Themes
Pick a theme:
All Content © 2008, Jason Harris
DasBlog theme 'Business' created by Christoph De Baene (delarou)