Showing posts with label qa. Show all posts
Showing posts with label qa. 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.

10/18/2011

Continuous integration for iOS app with Cucumber, Frank and Bamboo

It's been a while since I had written latest post and it's just because I have too little time and too little readers, so I wasn't sure it worthies spending time. But after this post by Marlena Compton I've decided to keep it on.

So, this post is about building continuous integration for iOS application with Cucumber + Frank as acceptance testing framework and Bamboo as CI server.

3/27/2011

Continuos Integration of Android apps

While looking for a way to implement this, I've found several how-tos, but they all used Maven, which didn't look great for me for several reasons. That's why I decided to set it up with myself. Here is the short manual if you are interested.
  1. Install Apache Ant
  2. Install Android SDK and its components (Tools and Platform Tools)
  3. Install Jenkins (formerly Hudson)
  4. Install Android Emulator Plugin for Jenkins and configure it with path to Android SDK
  5. Install Python Plugin for Jenkins
  6. Download android-junit-report.jar and place it to your tests lib/ directory (we need this as long as default Android test-runner doesn't generate XML report needed by Jenkins).
  7. Download build script and change variables section to fit your project (directories to application and tests, path to Android SDK, target version of Android, package name, use emulator or real device etc.). You don't need to add any modifications to AndroidManifest.xml or create build.xml - script will do this for you
  8. Create new job
  9. Add Python script as build step and paste modified version of build script there
  10. Try it!
That's supposed to be all. If you have any problems, feel free to comment/open issues at GitHub. Hope this will help you.

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.

12/04/2010

Drupal and cookies domain caching

From time to time anyone experience some problems with non-fresh Drupal installations (e.g. some project from SCM). The major one for me was some strange cookie setting and handling - when I tried to login Drupal replied with correct Set-Cookie header, but cookies were not saved within browser, i.e. after login the page was just reloaded with login prompt. No message or anything to help me. So I just started commenting and editing related code by random. Finally, I got it. The problem is that Drupal was installed first with hostname A and I tried to work with it on hostname B. Don't know why sometimes it's okay and sometimes it's not. However, you just need to uncomment $cookie_domain and set it to your hostname in settings.php. Just like this:

$cookie_domain = 'your.domain';

11/01/2010

Using Hudson variables in Python

While moving my continuous integration build script to Python (using Python Plugin for Hudson), I faced a problem of using Hudson environment variables. I am new to Python and get used just to place variables in shell script like $WORKSPACE or ${WORKSPACE}. Still, it didn't work in case of Python. So, if you met such a problem, you should use os.eviron() method. For example:

#!/usr/bin/python

import os

workspace = os.environ['WORKSPACE']
print workspace