Introducing Sauce AI: Intelligent Agents for Next-Gen Software Quality

x

SaucelabsSaucelabs
Saucelabs
Back to Resources

Blog

Posted April 2, 2010

Running your Selenium tests in parallel: Perl

quote

The Test::WWW::Selenium does a good integration of Selenium with Perl testing framework. However by default, tests runs in sequence. One easy solution is to use the Thread::Pool::Simple module to run the test functions in parallel. Short testing showed that this parallel version ran for 19 seconds vs 39 seconds for the serial run.

#!/usr/bin/env perl

use Thread::Pool::Simple;
use Test::More "no_plan";
use Test::WWW::Selenium;

sub test_page() {
my ($url, $input, $button) = @_;

my $sel = Test::WWW::Selenium->new(
host => "localhost",
port => 4444,
browser => "*firefox",
browser_url => $url,
);

$sel->open($url);
$sel->type_ok($input, "Sauce Labs");
$sel->click_ok($button);
$sel->wait_for_page_to_load_ok(5000);
$sel->body_text_like(qr/Selenium/);
$sel->close();
}

sub test_google() {
&test_page("http://google.com", "q", "btnG");
}

sub test_yahoo() {
&test_page("http://yahoo.com", "p", "search-submit");
}

sub test_bing() {
&test_page("http://www.bing.com", "q", "go");
}

sub worker() {
my $func = shift;
# We can't pass CODE items to a pool, so we use eval
eval("&$func();");
}

my @names = (
"test_google",
"test_yahoo",
"test_bing",
);

my $pool = Thread::Pool::Simple->new(
min => 3,
max => 10,
do => [\&worker],
);

foreach $name (@names) {
print "Adding $name\n";
$pool->add($name);
}

$pool->join();

Converting the code to work with Sauce OnDemand is a breeze as well, we will also use the job-name attribute to assign name for our jobs.

#!/usr/bin/env perl

use Thread::Pool::Simple;
use Test::More "no_plan";
use Test::WWW::Selenium;

# Replace username and access-key with your real
# Sauce OnDemand username and access-key

my $settings = qq(
{
"username" : "YOUR-SAUCE-USER-NAME",
"access-key" : "YOUR-SAUCE-ACCESS-KEY",
"os" : "Linux",
"browser" : "firefox",
"browser-version" : ""
"job-name" : "_JOB_NAME_"
}
);

sub test_page() {
my ($name, $url, $input, $button) = @_;

my $opts = $settings;
$opts =~ s/_JOB_NAME_/$name/; # Add job name

my $sel = Test::WWW::Selenium->new(
host => "ondemand.saucelabs.com",
port => 80,
browser => $opts,
browser_url => $url,
);

$sel->open($url);
$sel->type_ok($input, "Sauce Labs");
$sel->click_ok($button);
$sel->wait_for_page_to_load_ok(5000);
$sel->body_text_like(qr/Selenium/);
$sel->close();
}

sub test_google() {
&test_page("Google", "http://google.com", "q", "btnG");
}

sub test_yahoo() {
&test_page("Yahoo", "http://yahoo.com", "p", "search-submit");
}

sub test_bing() {
&test_page("Bing", "http://www.bing.com", "q", "go");
}

sub worker() {
my $func = shift;
# We can't pass CODE items to a pool, so we use eval
eval("&$func();");
}

my @names = (
"test_google",
"test_yahoo",
"test_bing",
);

my $pool = Thread::Pool::Simple->new(
min => 3,
max => 10,
do => [\&worker],
);

foreach $name (@names) {
print "Adding $name\n";
$pool->add($name);
}
$pool->join();

Published:
Apr 2, 2010
Share this post
Copy Share Link
robot
quote