Saturday, April 19, 2008

Usability Case Study: Facebook Advertising

A short case study on usability. It is all of a sudden relevant to me (because everyone is doing it wrong) and because I myself have learnt more about usability over the past six weeks than I thought I would. Therefore I feel I have an obligation to share my knowledge with you.

The other day I was investigating Facebook’s social advertising mechanism. Half of it was business related, the other half curiosity. I clicked the "advertise" link and was taken to a screen that pitched their advertising. After scanning that I clicked the “create ad now” button.

This took me to stage 1 of 4 of creating an ad.



This is also where I started to groan. All I wanted to know was how much it would cost to advertise on Facebook. I am not ready to start advertising, I am not even convinced that Facebook advertising is even a viable alternative.

The last step is called “Set Budget”. So I figured I could skip past the first three steps to find out. No Dice! I had to supply my URL, name and a brief description before I could continue.

Page 2 wanted my expected audience and the third, images and the advertising text. Luckily you can supply an image later, but dummy values in the advertising text were rejected as illegal words. At this point I quit. Seriously I said, fuck off.

Some advice to people who are looking to solicit services via the Internet. I don’t care who you are or what you think you know about what I want. You don’t. Secondly, I am not going to give you real information if I am looking for a quote. I just want a quote, be thankful I even know who you are and that I am interested in your services.

In my opinion this application would fail usability testing. It's target audience is businesses. What do businesses want from your service?
  • They want to know what it is you do
  • They want to know how much it costs
  • They want to be able to purchase the services when the time has come
  • They don’t want to wait to find an answer out.
The last point holds true for anyone, anywhere. It’s not like I can’t just click somewhere else. Seriously, realise how far your competitor is away in Internet terms and then meet them.

So, how should the Facebook advertising web-app have been written?

If prices are fixed based on simple conditions, put them on the second page or have a link called “prices”. If the prices are based on a complex algorithm, then place all the controls on a single page and let the user tweak the setup to match their needs. It is not that hard.

My reasoning is so, firstly from a business perspective you are being open about your pricing policies. Honesty is good. Dishonesty equals zero business.

Secondly, as a user I want, when I want. I don’t have to jump through your hoops to achieve my goal. I don’t care about your hoops. I only care about my goals.

Thirdly, if you only display one price at the end of four pages of clicking one of three things will occur.
  • The price is less than the budget for the advertiser. They may sign-up, but you may not be maximising your business potential. Secondly, they may have been willing to spend more but don’t know how to get those services from you.
  • The price matches their budget. Not likely.
  • The price is over their budget. Without a means to reduce their expectations to value they will go somewhere else.
If you display all the controls on one page then the following can occur:
  • The user will tweak the control to what they wanted from you at a service level and the cost comes under their budget. This would have happened anyway using your existing setup.
  • The user will tweak the controls to the absolute maximum of their budget. This is a win for both parties.
  • The user will play with the figures and may end up spending just a little bit more if they can justify a potential benefit from it. This is a double win for you and a win for them.
  • The user can’t find anything they like and they leave. However, they now know all about what you offer and what you cost. This is in their mind now and they won’t forget. There is a chance they will come back in the future.
By tailoring the application to the user’s needs rather than your own you do the following:
  • You increase your chance of doing business.
  • You appear to be a honest business entity.
  • Your application
  • Your application won’t piss people off and build a burning resentment within them.
Usability starts at the very beginning of software development and flows all the way through to User Acceptance Testing. You have to have in mind who you are developing the software for the end users before you write a line of code, before you write down a single requirement. For without a user, you have no need for an application.

Happy to discuss this delightful topic further, just drop me a line,

Thursday, April 17, 2008

The sweetest thing

Every now and again I have a moment of realisation where I am thankful that somebody else thought of something before I did. I had one of these just the other day. They are a little bit like this xkcd comic.

I was trying to find a bug in a binary tree and the problem would not manifest itself immediately. The code worked for a seemingly arbitrary period of time, but at a depth of N a get out clause needed to be true and it wasn't. Therefore it kept on recursing until it either could not create any more branch-nodes or it generated a stack-overflow.

I attempted to step through my code trying to find my bug, but I find it hard to debug recursive code. You’re never too sure how deep you need to go before the problem manifests. After missing the bug I pondered how I could represent the tree to find the bug. One of the things I have been teaching myself to do of late, is when I have a hard to reproduce bug, ask myself the question "How can I best model my data to visualise the bug?". It is not quite changing my work practices to stop bugs before they occur, but it really helps once they do manifest.

XML came to my rescue. I added a dump routine that iterated the tree dumping it out in well formed xml. I then used Notepad++ to display the xml with indenting and the bug was immediately visible.

So the moral of the story is: I love xml and am glad somebody else thought of it a long time ago. It’s a sweet way to visualise certain types of data and with the assistance of text indentation it is even better.


Just so you don’t think I’m blinded by xml-lust: Xml for network messaging formats is still a bad idea. Seriously, any format where you spend 50% of your bandwidth describing the data being sent is wasteful.

p.s. I am aware that this is a bit of an odd post.

Please Sir, Can I have some more?

Facebook has a “More Ads” button. Who in their right mind would willingly request more advertising? Is this insanity of the highest order by the developers, or perhaps naivety?

Tuesday, April 8, 2008

QuickTest : Applying major changes to a repository

There are times when major changes need to be applied to a repository. Such an example is when a deployed application is moved from a local test server to a server in a pre-production environment. Nothing should change except for the URL, which unfortunately is hard-coded into every single object in your repository.
  1. Open Object Repository Manager [Resources > Object Repository Manager]
  2. Open your project repository [File > Open] Export to XML [File > Export to XML]
  3. Enter a filename [exported.xml]
  4. [ok]
  5. Open you’re favourite XML editor (i.e. Notepad++)
  6. Find and Replace on the current path to the new path
  7. Do any other maintenance work
  8. [Save xml-doc]
  9. ensure document is well-formed
  10. [Close xml-doc]
  11. Meanwhile… Back in Object Repository Manager
  12. Import from XML [File > Import from XML]
  13. Save your Imported repository [imported.tsr]
  14. In the file system, delete repository.tsr and exported.xml
  15. Rename: imported.tsr to repository.tsr
Note: You will need to open a different QuickTest project and then reopen your current project for the results of the merge to be visible in the Object Repository. It’s a pain, but that’s the way of things.

QuickTest and CruiseControl for Continuous Integration

Originally I was working on the QuickTest CI setup with CruiseControl.NET (will work just as well for .java). This never got this completed for obvious reasons, but I thought I would share my notes with you.

Here is my original post detailing the qt2NUnit xsl and QuickTest structure


You need to launch QT remotely and I suspect this is more involved than what Grant did with TeamBuild. Look at what he did, and here is a reference to someone who executed QT remotely. I recommend using Grant's C# code to correct the repository references at run-time.

After that you just need a NAnt task to transform the results.xml doc. Here is a quicktest.build Nant task.
Then merge the results with your other result files. This works well if you have unit tests being produced in the same format. All the tests cases live together in harmony. This is a good thing.

Here is an excerpt of the publishers node within a CruiseControl build file.

You should now do some cleanup of temporary files, etc.


Note: Apologies for the images of xml. Blogger chucks a hissy fit if you include xml markup inside a post. What is this? The Nineties?

Monday, April 7, 2008

QuickTest and TeamBuild for Continuous Integration

A while ago Grant posted about integrating QuickTest (QT) into a Team Build continuous integration server. I said I would post about my half of the process. I’ve have been a bit busy of late to organise all my notes and publish this post. However it’s all organised now so, without further stalling for time…

The first part of the process is to ensure that you have a good QuickTest project setup This is what I did and why:


Organisation of Projects
An automated functional testing project (known to QuickTest as a Test) in my opinion should represent a single system. All test cases that actively test this system should be stored in this project. This ensures that our tests are all stored together.

A project should have a name and to simplify the integration with TeamBuild the project should be called “quick-test”. The folder that the quick-test project is in should be named after the Branch in source-control.

Example:
-The test team branch
|-The Name of the System
| |-quick-test

The common naming conventions will help ensure a close correlation between the code that is used to build a system and the automation code used to test it. This is especially relevant if the QT code is in a different branch to the app-code.

Note: Here there were two primary ways to configure the projects within TFS. The first is to put the functional testing code in the same branch as the code that it tests. The unit tests are also in that branch structure and with the code and all related content are together.

The second method is to have a separate branch for the Testing Team and then under each, a folder for each project. For convenience sake we named the sub-folder the same name as the code branch. Under this was our quick-test folder. Load-runner or any other tool that tests this same project would also be stored at this level.

We went with the second method because QT repository files can get quite large and this would have been a problem for the developers on an already strained TFS server. I also understand that workspace mappings may alleviate this problem further. I’m not 100% here as SVN is my source control system of choice (don’t tell Grant).

From an access management perspective, giving testers, who will probably be unfamiliar with the processes around source control, access to only one branch may make their lives simpler.

Even though we went with the second method, I would investigate the first method for your organisation to see if it fits. It’s a better logical structure.


Organisation of Repositories
The repository is where the objects that are used by QuickTest to control your application are stored. There are three levels of repositories:
  • Local – Attached to an asset
  • Project – All objects for a project
  • Global – Merge of all project repositories
I recommend not using a local repository as it is a maintenance nightmare. As you develop your automation test cases, continually push your objects into the project level repository and associate all actions with the project one. It’s much easier to maintain that duplicating objects into each local repository.

Furthermore I don’t recommend using a global repository either. Your objects should relate to the project you are testing. Once again this is primarily a hassle to maintain. If you have dedicated individuals managing the merging of object repositories then go for it. Otherwise give it a miss.

Now, with the current setup, projects are very isolated and it is not possible to write automated scenarios that interact across separate systems. For this I would suggest having a common project that is basically the same as a global repository. The difference being that it only contains the objects needed for cross system test cases are included in this branch. This involves less merging maintenance than merging all objects.

If you require a common repository, put it into a separate branch. This will make it easier for the build script to pull in the common repository when running a continuous integration instance.

The repository should be called repository.tsr in all scenarios. The location of the repository will determine whether it is project, global or common repository. Once again this makes it easier for the build script as it can expect a particular file rather than the name of the file being explicitly configured.


Actions and Quick Test
My definition of actions in QuickTest differs from standard usage. Personally I don’t like their setup and put some rules around when actions should be used. This in my opinion makes their usage cleaner.

An action to QuickTest is a single script that can be executed in isolation. To use, an action will represent either a single test scenario or a reusable test scenario. Scripts can call other actions. However, for the sake of simplicity down the track a script should only call reusable actions.

I’ll define some terminology to make this consistent:

  • Action – a single script that represents a single test case. Like all good test cases it should have single objective. If you are testing more than one thing, write two actions. See my post on the action-test-scenario naming convention for information on succinct naming of test cases and reasons for singular testing scope.
  • Reusable Action – An action in QT that you can be flagged to be “reusable”. To me this should not generate and pass or fail counts. It should merely ensure a state when called.
The first action of a project should be called zzRepository and we can use that to edit and mange our project repository in a local space. This action is deliberately excluded from CI results.

Reusable actions should start with the word ensure. They are required to establish a state on behalf of the calling action (they ensure a state). Once again these actions are not included in the CI results.


Back to Continuous Integration
Once you have set up your structure. Talk with your TFS guy to get the code checked in an in the right format. Once again this link to Grant's work will cover the next step.

In summary: the build script will pull in the launch QT pulling in the repository.tsr. If you use a common repository, pull that in as well. Then pipe in all actions one at a time to execute them.

After the build occurs QT produces a results.xml document. We need to take this and make it look even slightly better than the default QT one to make it useful. I really like the way CruiseControl.NET presents the NUnit xml format. So I wrote a xsl transform to make the QT -> NUnit transform.

Qt2NUnit.xsl

Finally you will need to adjust the CruiseControl
.NET xsl for presenting NUnit xml-docs to reference TeamBuild images. You can use my version here




It was funny then and is just as funny now

Many years ago I had a subscription to FHM. When I first subscribed I but my title as Sir. Once a month I would get a magazine delivered to Sir Chad Stone. I thought it was pretty funny.

FHM are currently going through a re-marketing phase to appear as more of a "thinking man's" magazine. A part of this campaign appears to be sending sample magazines to existing subscribers in an effort to get them to resubscribe.

In my letter box today was an FHM magazine address to Sir Chad Stone. It was even funnier today than it was back then because I had forgotten the punch line.