Testing complex Ajax content

Started by dhilipkumar, Mar 12, 2009, 02:56 PM

Previous topic - Next topic

dhilipkumar

Testing complex Ajax content

One of the biggest pains when testing web applications is hitting the wall with Ajax and client-side dynamic content. The big problem from an architectural standpoint is that at a DOM level it is incredibly difficult to determine a significant action from an insignificant action. If one were to record every minor browser DOM mutation, the output Test Case would be hundreds of lines long, which whilst amusing for about 5 seconds, is completely unmaintainable.

The Ajax page:

Why Google Finance: because it has an Ajax push model and it is not a "soft target". Ajax is utilized when one enters text into the textfield (an Ajax powered drop-down is shown with many different stocks). The Ajax powered textfield is below in all its glory;

The test-steps..

We recorded a Test Case with LiquidTest using the Firefox browser with the following actions;

load finance.google.com]http://finance.google.com
Click in textfield and type BH
Click second BHP response in Ajax drop-down
When page loads assert that ASX:BHP is in the textfield

What we got:

The Test Case that LiquidTest generated is below (notice the concise actions):

@Test 
@Browsers("Firefox2.0") 
public void testMethod() 

    browser.load("finance.google.com"); 
    browser.click("searchbox", 0); 
    browser.type("B"); 
    browser.expectingModificationsTo("ac-list").type("H"); 
    browser.expectingLoad().click("id('ac-list')/DIV[2]/DIV/SPAN[2]"); 
    assertEquals("ASX:BHP", browser.getValue("searchbox")); 

And?

What is the big deal? Well, it replays the actions exactly as described above. But the more interesting question is why? LiquidTest is built upon an Expectation Model. An Expectation model is a model that "expects" significant actions before proceeding. There are no random sleeps involved. If LiquidTest does not get the Expected Event it does not proceed. What this means is that with Expectations test cases are robust. How? LiquidTest has deep hooks into the target browser and a complex rules engine. We keep the complexities internal to LiquidTest to provide you, the user with robust and succinct (if they are not succinct they are difficult to maintain!) Test Cases.

In the example above, you can clearly see that as the user types significant events occur (Ajax) and LiquidTest records an expectingModificationsTo on the relevant element;

browser.expectingModificationsTo("ac-list").type("H");
 
Next an expectation (expectingLoad) is set on the Drop-down selector. This expectation states that when the click is sent, a page is expected to load (note: If you enable URL validation, you will see the full URL of the expected page in the expectingLoad("http://www.google.com/finance")).

browser.expectingLoad().click("id('ac-list')/DIV[2]/DIV/SPAN[2]"); 
Then finally there is the assert to ensure the content is present.

DONE!

LiquidTest has been a long time in development. We could have released the product 12 months ago. In-fact submitted a JavaOne paper covering LiquidTest over 12 months ago. We decided to hold back the LiquidTest release a year to improve the internal rules engine (it is not perfect, but you can bet your backside we are doing our best to get it there).