As part of our ongoing effort to maintain our test suite's performance, I've just added the following quick hack to source control (it needs a lot of work):
#!/usr/bin/env perl
use strict;
use warnings;
use App::Prove::State;
use List::Util 'sum';
use Lingua::EN::Numbers 'num2en';
my $prove = '.prove';
unless (-f $prove && -r _) {
die "Cannot find or read $prove file";
}
my $state = App::Prove::State->new({ store => $prove });
my $generation = $state->{_}{generation};
my $tests = $state->{_}{tests};
my $total = sum(map { $_->{elapsed} } values %$tests);
my $minutes = int($total / 60);
my $seconds = int($total % 60);
my $num_tests = shift || 5;
if ($num_tests > keys %$tests) {
$num_tests = keys %$tests;
}
my $num_word = num2en($num_tests);
my %time_for;
while (my ($test, $data) = each %$tests) {
$time_for{$test} = $data->{elapsed};
}
my @sorted_by_time_desc
= sort { $time_for{$b} <=> $time_for{$a} } keys %time_for;
print "Generation $generation\n";
print "Total runtime approximately $minutes minutes $seconds seconds\n";
print "\u$num_word slowest tests:\n";
for (0 .. $num_tests) {
my $test = $sorted_by_time_desc[$_];
print "\t$time_for{$test} seconds -> $test\n";
}
Basically, if you use the '--state=save' option with prove, it will save the state of your tests in a .prove file. This code reads the file, tells you which generation the file is, total test suite run time in minutes and seconds and your 5 slowest tests. Pass it a number and it will tell you the X slowest tests.
Update. Here's the output from the current branch I'm working on (a slightly updated version from above):
Generation 18
Number of test programs: 58
Total runtime approximately 17 minutes 35 seconds
Five slowest tests:
482.732247114182 seconds -> t/acceptance.t
234.499103069305 seconds -> t/aggregate.t
96.313854932785 seconds -> t/standards/strict.t
66.6500070095062 seconds -> t/unit/db/migrations.t
56.7010760307312 seconds -> t/unit/piptest/pprove/testdb.t
13.5212490558624 seconds -> t/unit/api/builder/brand-promotions.t
That's great. I've just dumped it in my ~/bin as slowt. Thanks
I'm not sure I understand why. Arrays in Perl are indexed from 0, not 1, so that would skip the longest running test. Did I misunderstand you?
Re:I'm confused
fireartist on 2008-03-05T13:51:50
It's currently printing 6 lines when `$num_tests = 5`
Should it maybe be `for (0.. $num_tests-1)` ?
Re:I'm confused
Ovid on 2008-03-05T13:56:51
Oh, duh
:)