Using Selenium2 with PHPUnit
So I've taken it upon myself to do a bit of reading and messing around with the Selenium Extension for PHPUnit and I wanted to share a bit of what I learned. Looking around on the internet, I didn't find a whole lot of real good information on the Selenium2TestCase API so I want to provide a little bit of depth in some of those areas. I'm going to cover a few areas of interest and provide some code examples where relevant.
Getting set up
I have to admit, this is the one area where I probably didn't go as deep as I should have. I interacted with the the setBrowser and setBrowserUrl methods as a way to get started, but here's a little run down of what some of these methods look like.
setBrowser(String $browser) - Set the browser that Selenium will launch setBrowserUrl(String $url) - Set the base URL for the tests, allows you to refer to relative paths in the tests setHost(String $host) - Set the hostname for the connection of the Selenium Server setPort(int $port) - Set the port for the connection to the Selenium Server
Selecting items
The coolest part of Selenium is that you can programmatically interact with a web browser, you get to tell it what to do and where to go. That being said, we first need to know how we're going to be selecting items. Most everyone is familiar with jQuery, so this concept shouldn't be new to many. There are a couple ways to select elements on the page that you're working on and here they are.
byId(String $id) - this will select the element that matches the id attribute that you provide byClassName(String $className) - this will select the element the matches the class attribute you provide byName(String $name) - this method matches on the name attribute you provide byXPath(String $xpath) - returns based on XPath pattern you provide byCssSelector(String $selector) - returns based on the CSS Selector (uses # -for ids, . for classes, etc) byLinkText(String $linkText) - not entirely sure, just stumbled upon this in the source, going to guess it matches link text
Interacting with items
Now comes the fun stuff, here's where we specify the actions we want to perform on our items. I'm certainly not going to go through all the available options here, but I'm going to try to touch on some of the commonly used, or what I perceive to be commonly used, items and get you started there.
click() - performs a click clear() - clears the value of the element value() - returns the value of the element value($value) - sets the value of the element to $value text() - returns the text of the element submit() - submits the element
$username = $this->byId('username');
$password = $this->byId('password');
$submit = $this->byId('submit');
$body = $this->byCssSelector('body');
$username->value('test');
$password->value('password');
$submit->click();
$this->assertNotContains($body->text(),'Invalid Login');
Getting around quicker
While it certainly is cool to drive around with a series of programmatic clicks, it can be tedious; so if you keep your tests focused on a single area of your application you can get to the starting point of your test by using the url() method. It took me a while to find this, because SeleniumTestCase has an open(String $url) method that makes more sense to me from a naming standpoint. url() will navigate your browser to the url that you provide, which means you don't have to spend a ton of time faux-clicking through your navigation menus and things of that nature.
Conclusion
Hopefully you found this somewhat helpful, please know that there are other options available for interacting with Selenium. WebDriver is a common one, perhaps when I get a chance to look into it more closely, I'll be able to write a post similar to this one. As always, I'm interested to hear your comments, concerns and corrections that you may have for this post. Thanks for checking it out!




Comments
2012-09-19
Nice post (- :
setting the browser in the setup method is valid if you want to test only one browser or write seperate tests for every browser you want to test.
One topic i had some trouble with is testing ajax stuff. (for example the login form would load via ajax) i ended up using this method: git://gist.github.com/3749188.git
Also links to selenium2 and the full api would be nice as you mention more then once that you are talking only about a subset of the api
regards, michael
2012-09-21
I'm the maintainer and current main developer of the extension, thanks for the post. The api you're using here *is* the WebDriver one, which has been merged with Selenium2 during development.
So that's why open() has been changed to url(): to conform to the new API (google for JSON Wire Protocol).
If you want to contribute to either the documentation or the code, you're welcome to open pull requests on github. :)