Showing posts with label selenium. Show all posts
Showing posts with label selenium. Show all posts

1/21/2012

Polymorphous page objects

I'm a big fan of page object pattern used for developing Selenium tests and I like the whole approach it follows. However, there are some points which can be improved in this approach. Let's talk about them.

Imagine that we have profile page for authenticated user. It has navigation menu with a set of links: "Home", "Profile", "Messages". Typical page class will look like this:

class ProfilePage

  def click_home_link
    @browser.find_element(:id => 'home_link').click
    HomePage.new
  end

  def click_profile_link
    @browser.find_element(:id => 'profile_link').click
    ProfilePage.new
  end

  def click_messages_link
    @browser.find_element(:id => 'message_link').click
    MessagesPage.new
  end

end # ProfilePage

Home and Messages pages are rather different page, but still have navigation menu. So they should have the same set of methods. We shouldn't duplicate code, so we need to extract these methods into a separate module.

10/25/2011

Little cheat to speed up your WebDriver tests

While most examples for Selenium WebDriver use creating new instance of browser on setUp() and closing it on tearDown(), it is not that fast really. So, in most cases, you only need to clear cookies and open homepage. Fortunately, WebDriver allows this. Such a little cheat will significantly decrease the time your tests take to run.

You can clear cookies by driver.manage.delete_all_cookies (Ruby bindings). In Watir-WebDriver there is also cute clear_cookies() method. Just create a new instance of WebDriver before all the tests and clear cookies in setUp(). That's it.

2/07/2011

Verify methods for PHPUnit (like Selenium)

If you have ever used Selenium RC + PHPUnit and used in your tests a lot of verfiy* assertions (i.e. non-strict assertions), you should have seen that they are actually look like:

try {
  $this->assert...();
} catch (PHPUnit_Framework_AssertionFailedError $e) {
  array_push($this->verificationErrors, $e->toString());
}

When you have around 100 verifications the code becomes a mess. That's when you should write your own verify* methods and instead use them.

I thought it would be useful for other PHPUnit + Selenium testers, so here is an example I of verifyEquals() as I guess it's the most used method:

class PHPUnit_Selenium_Verifications extends PHPUnit_Extensions_SeleniumTestCase {

  /**
   * Non-strictly asserts that two variables are equal.
   *
   * @param  mixed   $expected
   * @param  mixed   $actual
   * @param  string  $message
   * @param  float   $delta
   * @param  integer $maxDepth
   * @param  boolean $canonicalize
   * @param  boolean $ignoreCase
   */
  public static function verifyEquals($expected, $actual, $message = '', $delta = 0, $maxDepth = 10, $canonicalize = FALSE, $ignoreCase = FALSE) {
    // try assertion
    try {
      $this->assertEquals($expected, $actual, $message, $delta, $maxDepth, $canonicalize, $ignoreCase);
    // print exception and line number of assertion
    } catch (PHPUnit_Framework_AssertionFailedError $e) {
      array_push($this->verificationErrors, $e->toString(), "  on "  . __LINE__ . " line.");
    }
  }

Now you can just use $this->verifyEquals() instead of try-catch constructions.
I will keep on adding other methods if somebody finds this useful.

UPD: PHPUnit has built-in verifyCommand() method, which resolves all the problems.