Testing And Benchmarking in Elixir
Here’s the translation of the Go testing and benchmarking example to Elixir:
defmodule IntUtils do
@moduledoc """
This module contains utility functions for integer operations.
"""
@doc """
Returns the minimum of two integers.
"""
def int_min(a, b) do
if a < b, do: a, else: b
end
end
defmodule IntUtilsTest do
use ExUnit.Case
doctest IntUtils
test "basic int_min test" do
assert IntUtils.int_min(2, -2) == -2
end
test "table driven tests" do
test_cases = [
{0, 1, 0},
{1, 0, 0},
{2, -2, -2},
{0, -1, -1},
{-1, 0, -1}
]
for {a, b, expected} <- test_cases do
assert IntUtils.int_min(a, b) == expected,
"int_min(#{a}, #{b}) = #{IntUtils.int_min(a, b)}; want #{expected}"
end
end
end
defmodule IntUtilsBenchmark do
use Benchfella
bench "int_min" do
IntUtils.int_min(1, 2)
end
end
Unit testing is an important part of writing principled Elixir programs. The ExUnit
module provides the tools we need to write unit tests, and the mix test
command runs tests.
For the sake of demonstration, this code is in a single file, but it could be split into separate files. Testing code typically lives in a test
directory, while the code being tested is in the lib
directory.
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 lib/int_utils.ex
, and the test file for it would then be named test/int_utils_test.exs
.
A test is created by writing a function with test
macro in a module that uses ExUnit.Case
.
We can use assert
to check for equality and report test failures. If an assertion fails, the test will fail, but execution will continue to the next test.
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 list and a single loop walks over them and performs the test logic.
Benchmark tests in Elixir are typically created using a library like benchfella
. The bench
macro defines a benchmark, which will be run multiple times to get accurate measurements.
To run all tests in the current project in verbose mode:
$ mix test --trace
To run all benchmarks in the current project:
$ mix bench
Elixir’s testing and benchmarking ecosystem provides powerful tools for ensuring code correctness and performance. The ExUnit
framework makes it easy to write and run tests, while libraries like benchfella
allow for precise performance measurements.