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.