Skip to content

Instantly share code, notes, and snippets.

@alexander-brett
Created February 2, 2015 22:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alexander-brett/36f688a0dd8419d286bc to your computer and use it in GitHub Desktop.
Save alexander-brett/36f688a0dd8419d286bc to your computer and use it in GitHub Desktop.
Run unit tests with WWW::SFDC
#!/usr/bin/env perl
use Modern::Perl '2013';
use Getopt::Long;
use WWW::SFDC::Tooling;
use Data::Dumper;
=head1 NAME
runUnitTests.pl - run SFDC unit tests and output jUnit formatted results
=head1 USAGE
perl runUnitTests.pl --output TEST_RESULTS.xml --username my.username@name.com \
--password passwordsecuritytoken --url https://test.salesforce.com
=cut
sub jUnitFormat {
my $result = shift;
my $className = $$result{ApexClass}{Name};
my $methodName = $$result{MethodName} eq "<compile>" ? "CompileFailed" : $$result{MethodName};
return "<testcase name='$methodName' classname='$className' status='$$result{Outcome}'>"
. (defined $$result{Message} ? "<failure><![CDATA[$$result{StackTrace}\n$$result{Message}]]></failure>" : "")
. "</testcase>";
}
sub retryQuery {
my $query = shift;
my @result;
for (0..5) {
eval { @result = WWW::SFDC::Tooling->instance()->query($query); };
next if $@;
return (scalar @result == 1 and not defined $result[0] ? undef : @result);
}
die "There was an error retrieving the information from Salesforce\nQuery: $query\nError: $@";
}
sub isTestModified {
my $thing = shift;
defined $thing->{modifiers} and (
$thing->{modifiers} eq 'TEST'
or (
ref $thing->{modifiers} eq 'ARRAY' and grep {$_ eq 'TEST'} @{$thing->{modifiers}}
)
);
}
sub filterTests {
defined $_->{SymbolTable}->{methods} and (
(
ref $_->{SymbolTable}->{methods} eq 'ARRAY'
and grep {isTestModified($_)} @{$_->{SymbolTable}->{methods}}
) or (
ref $_->{SymbolTable}->{methods} eq 'HASH'
and isTestModified($_->{SymbolTable}->{methods})
)
);
}
MAIN: {
my ($username, $password, $url, $output);
GetOptions
"username:s" => \$username,
"password:s" => \$password,
"url:s" => \$url,
"output:s" => \$output;
WWW::SFDC::Tooling->instance(creds => {
username => $username,
password => $password,
url => $url
});
my $parentJobId = WWW::SFDC::Tooling->instance()->runTestsAsynchronous(
map { $_->{Id} } grep { filterTests } map {
retryQuery("SELECT Id, SymbolTable FROM ApexClass WHERE NamespacePrefix = '' LIMIT 200 OFFSET $_")
} grep { $_%200 == 0 } 0..(scalar retryQuery("Select Id FROM ApexClass WHERE NamespacePrefix = ''") - 1)
);
sleep 60 while retryQuery(
"SELECT Id FROM ApexTestQueueItem"
. " WHERE ParentJobId = '$parentJobId'"
. " AND (Status='Queued' OR Status='Processing' OR Status='Preparing' OR Status='Holding')"
);
{
open my $fh, ">", $output;
print $fh join "\n",
'<?xml version="1.0" encoding="UTF-8"?>',
'<testsuite name="SFDC Unit Tests">',
(
map {jUnitFormat($_)} WWW::SFDC::Tooling->instance()->query(
"SELECT Id, Outcome, MethodName, Message, StackTrace, ApexClass.Name"
. " FROM ApexTestResult WHERE AsyncApexJobId = '$parentJobId'"
)
),
'</testsuite>';
close $fh;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment