Testing And Benchmarking in Crystal
Here’s the translation of the Go testing and benchmarking example to Crystal:
# Unit testing is an important part of writing principled Crystal programs.
# Crystal comes with a built-in testing framework that provides the tools
# we need to write unit tests.
# For the sake of demonstration, this code is in the global namespace,
# but it could be in any module. Testing code typically lives in the
# same file as the code it tests, in a separate `spec` block.
# We'll be testing this simple implementation of an integer minimum.
def int_min(a : Int32, b : Int32) : Int32
a < b ? a : b
end
# Tests are created by writing specs inside a `describe` block.
describe "IntMin" do
# A basic test
it "returns the minimum of two numbers" do
int_min(2, -2).should eq(-2)
end
# Writing tests can be repetitive, so it's idiomatic to use
# a data-driven style, where test inputs and expected outputs
# are listed in an array and a single loop walks over them
# and performs the test logic.
[
{a: 0, b: 1, expected: 0},
{a: 1, b: 0, expected: 0},
{a: 2, b: -2, expected: -2},
{a: 0, b: -1, expected: -1},
{a: -1, b: 0, expected: -1},
].each do |test_case|
it "returns #{test_case[:expected]} for #{test_case[:a]} and #{test_case[:b]}" do
int_min(test_case[:a], test_case[:b]).should eq(test_case[:expected])
end
end
end
# Benchmark tests in Crystal are typically created using the `Benchmark` module.
# Here's an example of how you might benchmark the `int_min` function:
require "benchmark"
Benchmark.ips do |x|
x.report("int_min") { int_min(1, 2) }
end
To run the tests, you would typically save this code in a file with a .cr
extension (e.g., int_min_spec.cr
) and then use the crystal spec
command:
$ crystal spec int_min_spec.cr
This will run all the tests and display the results.
To run the benchmark, you would typically put the benchmark code in a separate file (e.g., int_min_benchmark.cr
) and run it with:
$ crystal run int_min_benchmark.cr
This will execute the benchmark and display the results, showing how many iterations per second the int_min
function can perform.
Note that Crystal’s testing and benchmarking approach is quite different from Go’s. Crystal uses a behavior-driven development (BDD) style for testing, which is more similar to RSpec in Ruby. For benchmarking, Crystal provides the Benchmark
module, which is different from Go’s testing.B approach but serves a similar purpose.
Crystal Spec Runner