Testing And Benchmarking in Perl

Here’s the translation of the Go testing and benchmarking example to Perl:

use strict;
use warnings;
use Test::More;
use Benchmark qw(:all);

# We'll be testing this simple implementation of an
# integer minimum. Typically, the code we're testing
# would be in a source file named something like
# intutils.pl, and the test file for it would then
# be named intutils.t.

sub int_min {
    my ($a, $b) = @_;
    return $a < $b ? $a : $b;
}

# A test is created by writing a function with a name
# beginning with 'test_'.

sub test_int_min_basic {
    my $ans = int_min(2, -2);
    is($ans, -2, "int_min(2, -2) should return -2");
}

# Writing tests can be repetitive, so it's idiomatic to
# use a table-driven style, where test inputs and
# expected outputs are listed in a table and a single loop
# walks over them and performs the test logic.

sub test_int_min_table_driven {
    my @tests = (
        [0, 1, 0],
        [1, 0, 0],
        [2, -2, -2],
        [0, -1, -1],
        [-1, 0, -1],
    );

    for my $test (@tests) {
        my ($a, $b, $want) = @$test;
        my $ans = int_min($a, $b);
        is($ans, $want, "int_min($a, $b) should return $want");
    }
}

# Run the tests
test_int_min_basic();
test_int_min_table_driven();

# Benchmark tests are typically created using the Benchmark module

sub benchmark_int_min {
    timethis(1000000, sub { int_min(1, 2) });
}

done_testing();
benchmark_int_min();

To run the tests and benchmarks, you would typically save this code in a file with a .t extension (e.g., int_min.t) and then run it using the prove command:

$ prove -v int_min.t

This will run all the tests in verbose mode. The output might look something like this:

int_min.t .. 
ok 1 - int_min(2, -2) should return -2
ok 2 - int_min(0, 1) should return 0
ok 3 - int_min(1, 0) should return 0
ok 4 - int_min(2, -2) should return -2
ok 5 - int_min(0, -1) should return -1
ok 6 - int_min(-1, 0) should return -1
1..6
ok
All tests successful.
Files=1, Tests=6,  0 wallclock secs
Result: PASS

After the tests, the benchmark will run:

timethis 1000000: 0 wallclock secs ( 0.13 usr +  0.00 sys =  0.13 CPU) @ 7692307.69/s (n=1000000)

This output shows how many times per second the int_min function was called during the benchmark.

In Perl, we use the Test::More module for writing tests, which provides functions like is() for making assertions. For benchmarking, we use the Benchmark module, which offers various functions for timing code execution.

The structure of Perl tests is somewhat different from Go tests, but the basic concepts of unit testing and benchmarking are similar. Perl doesn’t have a built-in way to run “subtests” like Go’s t.Run(), but you can achieve similar organization by using nested subtest blocks from Test::More if needed.