std.testing(テストユーティリティ)
『Zig』の標準ライブラリ std.testing は、test ブロックと組み合わせて使うユニットテスト用のユーティリティを提供します。expect や expectEqual などの関数でアサーションを記述し、zig test コマンドで一括実行できます。外部フレームワーク不要でソースファイルに直接テストを書けるため、小さな関数から複雑なデータ構造まで気軽にテストできます。
構文
// -----------------------------------------------
// std.testing の主要関数の構文まとめ
// -----------------------------------------------
const std = @import("std");
const testing = std.testing;
// -----------------------------------------------
// test ブロック — テストの宣言
// -----------------------------------------------
// test "説明文" { ... } の形式でテストを宣言します
// zig test ファイル名.zig で全テストが実行されます
test "テストの説明" {
// アサーションが失敗すると error.TestUnexpectedResult が返ります
try testing.expect(1 + 1 == 2);
}
// -----------------------------------------------
// expect — 条件が true であることを確認します
// -----------------------------------------------
// expect(ok) — ok が false なら失敗します
try testing.expect(some_value == expected_value);
// -----------------------------------------------
// expectEqual — 値が等しいことを確認します
// -----------------------------------------------
// expectEqual(expected, actual) — 型と値が一致することを確認します
try testing.expectEqual(@as(u32, 42), some_u32);
// -----------------------------------------------
// expectEqualStrings — 文字列が等しいことを確認します
// -----------------------------------------------
// expectEqualStrings(expected, actual) — []const u8 を比較します
// 失敗時は差分を表示します
try testing.expectEqualStrings("伏黒恵", name);
// -----------------------------------------------
// expectEqualSlices — スライスが等しいことを確認します
// -----------------------------------------------
// expectEqualSlices(T, expected, actual) — 要素単位で比較します
try testing.expectEqualSlices(u8, &.{ 1, 2, 3 }, slice);
// -----------------------------------------------
// expectError — エラーが返ることを確認します
// -----------------------------------------------
// expectError(expected_error, actual_error_union) — 期待するエラーと一致するか確認します
try testing.expectError(error.SomeError, failing_fn());
// -----------------------------------------------
// allocator — テスト用のアロケータを取得します
// -----------------------------------------------
// testing.allocator はリークを自動検出するアロケータです
// テスト終了後にリークがあればエラーを報告します
const allocator = testing.allocator;
主な関数まとめ
| 関数 / 識別子 | 概要 |
|---|---|
test "説明" { } | テストブロックを宣言します。zig test 実行時に全テストが順番に実行されます。 |
testing.expect(ok) | 引数が true であることを確認します。false の場合はテストが失敗します。 |
testing.expectEqual(expected, actual) | 二つの値が型・値ともに等しいことを確認します。失敗時は期待値と実測値を表示します。 |
testing.expectEqualStrings(expected, actual) | 二つの文字列スライスが等しいことを確認します。失敗時は差分を表示します。 |
testing.expectEqualSlices(T, expected, actual) | 同じ型のスライスを要素単位で比較します。長さが異なる場合も失敗します。 |
testing.expectError(err, value) | エラーユニオンが指定のエラーを返すことを確認します。エラーなし、または別のエラーの場合は失敗します。 |
testing.expectApproxEqAbs(expected, actual, tolerance) | 浮動小数点数を絶対誤差の範囲内で比較します。 |
testing.expectApproxEqRel(expected, actual, tolerance) | 浮動小数点数を相対誤差の範囲内で比較します。 |
testing.allocator | テスト専用のアロケータです。テスト終了後にメモリリークが残っていれば自動的にエラーを報告します。 |
testing.refAllDecls(T) | 型 T の全宣言をコンパイル時に参照します。デッドコードの検出に使います。 |
サンプルコード
jujutsu_std_testing.zig
// jujutsu_std_testing.zig — 呪術廻戦のキャラクターを使って
// std.testing の主要なアサーション関数を確認します
//
// 実行方法:
// zig test jujutsu_std_testing.zig
const std = @import("std");
const testing = std.testing;
// -----------------------------------------------
// テスト対象の関数群
// -----------------------------------------------
// 呪師のランクを文字列で返します
fn getCursedRank(grade: u8) []const u8 {
return switch (grade) {
1 => "特級",
2 => "1級",
3 => "2級",
4 => "3級",
else => "不明",
};
}
// 呪力量を加算します(オーバーフロー時は error.Overflow を返します)
fn addCursedEnergy(a: u32, b: u32) error{Overflow}!u32 {
return std.math.add(u32, a, b);
}
// 呪師の名前リストを動的に生成します(呼び出し元が解放する必要があります)
fn buildSorcererList(allocator: std.mem.Allocator) ![][]const u8 {
var list = try allocator.alloc([]const u8, 3);
list[0] = "虎杖悠仁";
list[1] = "伏黒恵";
list[2] = "釘崎野薔薇";
return list;
}
// 呪霊の強さが閾値を超えているか判定します
fn isSpecialGrade(power: f64) bool {
return power >= 9000.0;
}
// -----------------------------------------------
// testing.expect — 条件の確認
// -----------------------------------------------
test "isSpecialGrade: 五条悟は特級相当の強さを持つ" {
// 五条悟の呪力値は閾値を大幅に超えます
const gojo_power: f64 = 99999.9;
try testing.expect(isSpecialGrade(gojo_power));
}
test "isSpecialGrade: 釘崎野薔薇は閾値未満" {
// 釘崎の呪力値は特級閾値には届きません(成長中)
const nobara_power: f64 = 3500.0;
try testing.expect(!isSpecialGrade(nobara_power));
}
// -----------------------------------------------
// testing.expectEqual — 値の等値確認
// -----------------------------------------------
test "getCursedRank: grade=1 は '特級' を返す" {
// 宿儺(両面宿儺)は grade 1 = 特級呪霊です
const rank = getCursedRank(1);
try testing.expectEqualStrings("特級", rank);
}
test "getCursedRank: grade=2 は '1級' を返す" {
// 七海建人は1級呪師です
const rank = getCursedRank(2);
try testing.expectEqualStrings("1級", rank);
}
test "getCursedRank: 不明なgrade は '不明' を返す" {
// 定義外の値は '不明' になります
const rank = getCursedRank(99);
try testing.expectEqualStrings("不明", rank);
}
// -----------------------------------------------
// testing.expectEqual — 数値の等値確認
// -----------------------------------------------
test "addCursedEnergy: 虎杖と伏黒の呪力を合算する" {
// 虎杖: 4800、伏黒: 3200 → 合計 8000
const result = try addCursedEnergy(4800, 3200);
try testing.expectEqual(@as(u32, 8000), result);
}
// -----------------------------------------------
// testing.expectError — エラーの確認
// -----------------------------------------------
test "addCursedEnergy: オーバーフロー時は error.Overflow を返す" {
// u32 の最大値を超える計算は Overflow エラーになります
const max = std.math.maxInt(u32);
// expectError は try なしで呼び出します(エラーを「期待」しているため)
try testing.expectError(error.Overflow, addCursedEnergy(max, 1));
}
// -----------------------------------------------
// testing.expectEqualSlices — スライスの等値確認
// -----------------------------------------------
test "buildSorcererList: 3名の呪師リストが正しく生成される" {
// testing.allocator はリーク検出機能付きのアロケータです
const allocator = testing.allocator;
const list = try buildSorcererList(allocator);
// テスト終了後にメモリを解放します(defer で確実に実行します)
defer allocator.free(list);
// リストの長さを確認します
try testing.expectEqual(@as(usize, 3), list.len);
// 各要素の内容を確認します
try testing.expectEqualStrings("虎杖悠仁", list[0]);
try testing.expectEqualStrings("伏黒恵", list[1]);
try testing.expectEqualStrings("釘崎野薔薇", list[2]);
}
// -----------------------------------------------
// testing.expectApproxEqAbs — 浮動小数点数の近似比較
// -----------------------------------------------
test "五条悟の呪力スコアは誤差 0.1 以内で 99999.9 に近い" {
// 浮動小数点の計算誤差を吸収して比較します
const calculated: f64 = 99999.85 + 0.05; // 演算後の値
try testing.expectApproxEqAbs(@as(f64, 99999.9), calculated, 0.1);
}
zig test jujutsu_std_testing.zig All 9 tests passed.
概要
『Zig』の std.testing は、test ブロックと組み合わせて使うシンプルなユニットテストモジュールです。基本的なアサーションには testing.expect(条件確認)と testing.expectEqual(値の等値比較)を使います。文字列の比較には testing.expectEqualStrings、スライス全体の比較には testing.expectEqualSlices が便利で、失敗時に差分を表示してくれます。エラーを期待するテストには testing.expectError を使い、エラーユニオンが指定のエラーを返すことを確認します。動的メモリを使うテストでは testing.allocator を利用するとメモリリークを自動検出できます。テストは zig test ファイル名.zig で実行し、全テストが通れば All N tests passed. と表示されます。エラーハンドリングの詳細は エラーハンドリング を、メモリ管理については アロケータの基本 を合わせて参照してください。
記事の間違いや著作権の侵害等ございましたらお手数ですがこちらまでご連絡頂ければ幸いです。