Since I added a lot of Ajax support into the project I've been using Selenium to execute these Ajax tests. At first I couldn't find any best-practices for doing a lot of Ajax testing with it, especially from PHPUnit, but today I managed to come up with a couple of things that work pretty well.
1. Selenium IDE
First off, the Selenium IDE is a fantastic tool. It installs as a Firefox extension, and adds a "Selenium IDE" option to the "Tools" menu. Once you pull up the IDE window, you can just hit "record" and run your app, recording tests along the way by right-clicking interesting objects and then choosing the test you want to perform on that object. You can tweak tests and run them in-browser via the IDE window.
Even cooler is the "clipboard integration." First, click on the IDE window, then choose your language under the "Options->Clipboard Format" menu item. Then, you can select all of the steps, hit "copy", and then "paste" into your text editor, and boom you have valid code for your test framework that will execute the steps you just entered.
NOTE: You might notice that the code created doesn't always exactly mirror the steps in the Selenium IDE. That's because the IDE has test functions that don't exist in Selenium Core (the part that actually runs the test). I think this is weird architecturally, but hey it is what it is. So certain tests like "waitForText" get expanded into really ugly loops in PHP, but they do work.
2. Cleaner Javascript Testing
While the automated setup was nice, I don't like sloppy code, and plus I still wanted to be able to assert things in Javascript. That's when I figured out a good way to use the "waitForCondition" test. This test is supported by the language drivers (ie PHPUnit) and allows you to simply execute a javascript statement which will automatically re-run periodically until the result of the expression is true, or it times out. Perfect for Ajax stuff.
How's it look? Here's an example PHPUnit test:
public function testWFRPCRequestShouldProcessWFActionResponsePhocoaUIUpdater()
{
$this->open("/webapp/test/requests/wfrpc");
$this->click("runTest");
$this->waitForCondition("selenium.browserbot.getCurrentWindow().$('testResult').innerHTML === 'PHOCOA Ajax Response'");
}
Since my framework has Prototype loaded, I can use all of Prototype's goodness to write my tests. Just be sure to use the "selenium.browserbot.getCurrentWindow()" syntax to get to the proper "window" object for your page under test.
1 comments: