views:

755

answers:

2

I will soon be working on AJAX driven web pages that have a lot of content generated from a Web Service (WCF).

I've tested this sort of thing in the past (and found it easy) but not with this level of dynamic content.

I'm developing in .NET 3.5 using Visual Studio 2008. I envisage this testing in:

  1. TestDriven.NET
  2. MBUnit (this is not Unit testing though)
  3. Some sort of automation tool to control browsers (Maybe Selenium, though it might be SWEA or Watin. I'm thinking IE,Firefox, and likely Opera and Safari.)

In the past I've used delays when testing the browser. I don't particularly like doing that and it wastes time.

What experience and practice is there for doing things better, than using waits. Maybe introducing callbacks and a functional style of programming to run the tests in?


Notes 1. More detail after reviewing first 3 replies.

1) Thanks Alan, Eran and marxidad, your replies have set me on the track to getting my answer, hopefully without too much time spent.

2) Another detail, I'm using jQuery to run the Ajax, so this is not built in Asp.NET AJAX.

3) I found an article which illustrates the situation nicely. It's from http://adamesterline.com/2007/04/23/watin-watir-and-selenium-reviewed/

3.1) Selenium Sample (This and the next, WatiN, code sample do not show up in the original web page (on either IE or Firefox) so I've extracted them and listed them here.)

public void MinAndMaxPriceRestoredWhenOpenedAfterUsingBackButton(){
  OpenBrowserTo("welcome/index.rails");
  bot.Click("priceDT");
  WaitForText("Price Range");
  WaitForText("515 N. County Road");
  bot.Select("MaxDropDownList", "$5,000,000");
  WaitForText("Prewar 8 Off Fifth Avenue");
  bot.Select("MinDropDownList", "$2,000,000");
  WaitForText("of 86");
  bot.Click("link=Prewar 8 Off Fifth Avenue");
  WaitForText("Rarely available triple mint restoration");
  bot.GoBack();
  Thread.Sleep(20000);
  bot.Click("priceDT");
  WaitForText("Price Range");
  Assert.AreEqual("$5,000,000", bot.GetSelectedLabel("MaxDropDownList"));
  Assert.AreEqual("$2,000,000", bot.GetSelectedLabel("MinDropDownList"));}

3.2) WatiN sample

public void MinAndMaxPriceRestoredWhenOpenAfterUsingBackButton(){
  OpenBrowserTo("welcome/index.rails");
  ClickLink("Price");
  SelectMaxPrice("$5,000,000");
  SelectMinPrice("$2,000,000");
  ClickLink("Prewar 8 Off Fifth Avenue");
  GoBack();
  ClickLink("Price");
  Assert.AreEqual("$5,000,000", SelectedMaxPrice());
  Assert.AreEqual("$2,000,000", SelectedMinPrice());}

3.3) If you look at these, apparently equivalent, samples you can see that the WatiN sample has abstracted away the waits.

3.4) However it may be that WatiN needs additional support for values changed by Ajax calls as noted in http://watinandmore.blogspot.com/2008/01/using-watin-to-test-select-lists-in.html. In that article the page is given an additional field which can be used to synthesize a changed event, like so:

// Wait until the value of the watintoken attribute is changed
ie.SelectList("countries").WaitUntil(!Find.By("watintoken",watintoken));

4) Now what I'm after is a way to do something like what we see in the WatiN code without that synthesized event. It could be a way to directly hook into events, like changed events. I wouldn't have problems with callbacks either though that could change the way tests are coded. I also think we'll see alternate ways of writing tests as the implications of new features in C# 3, VB 9 and F# start to sink in (and wouldn't mind exploring that).

5) marxidad, my source didn't have a sample from WebAii so I haven't got any comments on this, interesting looking, tool.


Notes 2. 2008-09-29. After some feedback independent of this page.

5) I attempted to get more complete source for the WatiN sample code above. Unfortunately it's no longer available, the link is dead. When doing that I noticed talk of a DSL, presumably a model that maps between the web page and the automation tool. I found no details on that.

6) For the WebAii it was suggested code like this (it's not tested) would be used:

public void MinAndMaxPriceRestoredWhenOpenAfterUsingBackButton(){
  ActiveBrowser.NavigateTo("welcome/index.rails"); 
  Find.ByContent<HtmlAnchor>("Price").Click();
  HtmlSelect maxPrice = Find.ById<HtmlSelect>("MaxDropDownList"); 
  HtmlSelect minPrice = Find.ById<HtmlSelect>("MinDropDownList");
  maxPrice.SelectByText("$5,000,000"); 
  minPrice.SelectByText("$2,000,000");
  Find.ByContent<HtmlAnchor>("Prewar 8 Off Fifth Avenue").Click(); 
  ActiveBrowser.GoBack();
  Find.ByContent<HtmlAnchor>("Price").Click(); 
  maxPrice.AssertSelect().SelectedText("$5,000,000"); 
  minPrice.AssertSelect().SelectedText("$2,000,000");}

6) From the code I can clearly avoid waits and delays, with some of the frameworks, but I will need to spend more time to see whether WatiN is right for me.

+1  A: 

Most automation frameworks have some synchronizationfunctions built in. Selenium is no exception, and includes functionality like waitForText, waitForElementPresent,etc.

I just realized that you mentioned "waits" above, which I interpreted as Sleeps (which aren't good in automation). Let me know if I misinterpreted, and I can talk more about wait* functions or alternatives.

Alan
A: 

WebAii has a WaitForElement(s) method that lets you specify the parameters of the elements to wait for.

Mark Cidade