Testing And Benchmarking in D Programming Language

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

import std.stdio;
import std.format;
import core.time;

// 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.d`, and the test file for it would then
// be named `intutils_test.d`.

int intMin(int a, int b) {
    return a < b ? a : b;
}

// A test is created by writing a function with the
// @("test") attribute.

@("test")
void testIntMinBasic() {
    int ans = intMin(2, -2);
    assert(ans == -2, format("intMin(2, -2) = %d; want -2", ans));
}

// 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.

@("test")
void testIntMinTableDriven() {
    struct TestCase {
        int a, b;
        int want;
    }

    TestCase[] tests = [
        {0, 1, 0},
        {1, 0, 0},
        {2, -2, -2},
        {0, -1, -1},
        {-1, 0, -1},
    ];

    foreach (tt; tests) {
        int ans = intMin(tt.a, tt.b);
        assert(ans == tt.want, format("got %d, want %d", ans, tt.want));
    }
}

// Benchmark tests in D typically use the std.datetime.stopwatch
// module to measure execution time. We'll create a simple
// benchmark function here.

void benchmarkIntMin() {
    import std.datetime.stopwatch : benchmark;

    auto result = benchmark!({
        intMin(1, 2);
    })(10_000_000);

    writefln("BenchmarkIntMin: %s", result[0]);
}

void main() {
    // Run the tests
    testIntMinBasic();
    testIntMinTableDriven();

    // Run the benchmark
    benchmarkIntMin();
}

To run the tests and benchmark in D, you would typically use a testing framework like dub or manually compile and run the program. Here’s how you might run it:

$ dmd -unittest test_intmin.d
$ ./test_intmin

This will compile the program with unit tests enabled and then run it. The output might look something like this:

All unit tests have been run successfully.
BenchmarkIntMin: 11.2 ms, 892 μs, and 3 hnsecs

In D, the built-in unit testing framework automatically runs all functions marked with the @("test") attribute. The assert function is used for test assertions.

For benchmarking, D doesn’t have a built-in benchmarking tool like Go’s testing package. Instead, we use the std.datetime.stopwatch module to measure execution time. The benchmark function runs the intMin function multiple times and reports the total time taken.

Note that D’s approach to testing and benchmarking is somewhat different from Go’s, but this example demonstrates similar concepts adapted to D’s conventions and standard library.