Created
February 2, 2015 22:11
-
-
Save alexander-brett/36f688a0dd8419d286bc to your computer and use it in GitHub Desktop.
Run unit tests with WWW::SFDC
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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