Testing
Every BEAM language ships (or borrows) a unit-testing story, and the shared task is the smallest one possible: assert that add(2, 3) equals 5. Notice how the assertion macro shapes each style - Erlang's EUnit recognises any function named *_test, Elixir's ExUnit wraps cases in test "..." blocks, Gleam's gleeunit auto-discovers *_test functions and uses a should pipeline, and LFE reuses EUnit through (deftest ...). Lua (Luerl) has no test framework on board, so a test is just an assert call you write yourself.
-module(math_tests).
-include_lib("eunit/include/eunit.hrl").
add(A, B) -> A + B.
%% EUnit auto-discovers any zero-arity function whose name
%% ends in _test; ?assertEqual reports Expected vs Actual on failure.
add_test() ->
?assertEqual(5, add(2, 3)).
%% Run with: eunit:test(math_tests).
%% Test passed.
EUnit is part of Erlang/OTP: including eunit.hrl turns every name_test/0 function into a test case, and the ?assertEqual(Expected, Actual) macro prints both sides when they differ.
defmodule MathTest do
use ExUnit.Case
defp add(a, b), do: a + b
# `test` defines a case; `assert` introspects the expression
# so a failure shows the actual left/right values.
test "add/2 sums its arguments" do
assert add(2, 3) == 5
end
end
# Run with: mix test
# 1 test, 0 failures
ExUnit ships with Elixir: use ExUnit.Case brings in the test "..." macro and a single magic assert, which rewrites the == expression to report both operands on failure.
import gleeunit
import gleeunit/should
pub fn main() {
gleeunit.main()
}
fn add(a: Int, b: Int) -> Int {
a + b
}
// gleeunit discovers every public *_test function in the module.
pub fn add_test() {
add(2, 3)
|> should.equal(5)
}
// Run with: gleam test
// 1 tests, 0 failures
gleeunit wraps EUnit for Gleam: gleeunit.main() auto-discovers each pub fn *_test, and the should.equal helper is piped onto the value under test, staying fully type-checked with no exceptions.
(defmodule math-tests
(behaviour ltest-unit)
(export all))
(include-lib "ltest/include/ltest-macros.lfe")
(defun add (a b) (+ a b))
;; (deftest name ...) expands to an EUnit name_test function;
;; (is-equal Expected Actual) is the LFE wrapper over ?assertEqual.
(deftest add
(is-equal 5 (add 2 3)))
;; Run with: (eunit:test 'math-tests)
;; Test passed.
LFE rides on Erlang's EUnit through the ltest library: after (include-lib "ltest/include/ltest-macros.lfe"), the (deftest add ...) macro generates the add_test/0 function EUnit looks for, and (is-equal ...) is the Lisp-friendly form of ?assertEqual.
-- Lua has no built-in test runner, so a unit test is just
-- a function that calls assert() and reports its own result.
local function add(a, b)
return a + b
end
local function test_add()
-- assert(condition, message): raises with the message when false.
assert(add(2, 3) == 5, "add(2, 3) should equal 5")
print("ok - add")
end
test_add()
-- prints: ok - add
-- (a failing assert would raise the message and abort the run)
Plain Lua leans on the standard assert(condition, message), which throws the message when the condition is false; a "test" is simply a function that asserts and prints, with no framework involved.