Global Variables
allocator_instance | type | |
base_allocator_instance | undefined | |
failing_allocator_instance | undefined | |
log_level | undefined | TODO https://github.com/ziglang/zig/issues/5738 |
Functions
fn checkAllAllocationFailures(backing_allocator: std.mem.Allocator, comptime test_fn: anytype, extra_args: anytype) !void
Exhaustively check that allocation failures within
test_fn
are handled without…Exhaustively check that allocation failures within
test_fn
are handled without introducing memory leaks. If used with thetesting.allocator
as thebacking_allocator
, it will also be able to detect double frees, etc (when runtime safety is enabled).The provided
test_fn
must have astd.mem.Allocator
as its first argument, and must have a return type of!void
. Any extra arguments oftest_fn
can be provided via theextra_args
tuple.Any relevant state shared between runs of
test_fn
must be reset withintest_fn
.The strategy employed is to:
- Run the test function once to get the total number of allocations.
- Then, iterate and run the function X more times, incrementing the failing index each iteration (where X is the total number of allocations determined previously)
Expects that
test_fn
has a deterministic number of memory allocations:- If an allocation was made to fail during a run of
test_fn
, buttest_fn
didn’t returnerror.OutOfMemory
, thenerror.SwallowedOutOfMemoryError
is returned fromcheckAllAllocationFailures
. You may want to ignore this depending on whether or not the code you’re testing includes some strategies for recovering fromerror.OutOfMemory
. - If a run of
test_fn
with an expected allocation failure executes without an allocation failure being induced, thenerror.NondeterministicMemoryUsage
is returned. This error means that there are allocation points that won’t be tested by the strategy this function employs (that is, there are sometimes more points of allocation than the initial run oftest_fn
detects).
Here’s an example using a simple test case that will cause a leak when the allocation of
bar
fails (but will pass normally):test { const length: usize = 10; const allocator = std.testing.allocator; var foo = try allocator.alloc(u8, length); var bar = try allocator.alloc(u8, length); allocator.free(foo); allocator.free(bar); }
The test case can be converted to something that this function can use by doing:
fn testImpl(allocator: std.mem.Allocator, length: usize) !void { var foo = try allocator.alloc(u8, length); var bar = try allocator.alloc(u8, length); allocator.free(foo); allocator.free(bar); } test { const length: usize = 10; const allocator = std.testing.allocator; try std.testing.checkAllAllocationFailures(allocator, testImpl, .{length}); }
Running this test will show that
foo
is leaked when the allocation ofbar
fails. The simplest fix, in this case, would be to use defer like so:fn testImpl(allocator: std.mem.Allocator, length: usize) !void { var foo = try allocator.alloc(u8, length); defer allocator.free(foo); var bar = try allocator.alloc(u8, length); defer allocator.free(bar); }
fn expect(ok: bool) !void
This function is intended to be used only in tests. When
ok
is false, returns…This function is intended to be used only in tests. When
ok
is false, returns a test failure error.fn expectApproxEqAbs(expected: anytype, actual: @TypeOf(expected), tolerance: @TypeOf(expected)) !void
This function is intended to be used only in tests. When the actual value is no…
This function is intended to be used only in tests. When the actual value is not approximately equal to the expected value, prints diagnostics to stderr to show exactly how they are not equal, then returns a test failure error. See
math.approxEqAbs
for more information on the tolerance parameter. The types must be floating-point.fn expectApproxEqRel(expected: anytype, actual: @TypeOf(expected), tolerance: @TypeOf(expected)) !void
This function is intended to be used only in tests. When the actual value is no…
This function is intended to be used only in tests. When the actual value is not approximately equal to the expected value, prints diagnostics to stderr to show exactly how they are not equal, then returns a test failure error. See
math.approxEqRel
for more information on the tolerance parameter. The types must be floating-point.fn expectEqual(expected: anytype, actual: @TypeOf(expected)) !void
This function is intended to be used only in tests. When the two values are not …
This function is intended to be used only in tests. When the two values are not equal, prints diagnostics to stderr to show exactly how they are not equal, then returns a test failure error.
actual
is casted to the type ofexpected
.fn expectEqualDeep(expected: anytype, actual: @TypeOf(expected)) !void
This function is intended to be used only in tests. When the two values are not …
This function is intended to be used only in tests. When the two values are not deeply equal, prints diagnostics to stderr to show exactly how they are not equal, then returns a test failure error.
actual
is casted to the type ofexpected
.Deeply equal is defined as follows: Primitive types are deeply equal if they are equal using
==
operator. Struct values are deeply equal if their corresponding fields are deeply equal. Container types(like Array/Slice/Vector) deeply equal when their corresponding elements are deeply equal. Pointer values are deeply equal if values they point to are deeply equal.Note: Self-referential structs are not supported (e.g. things like std.SinglyLinkedList)
fn expectEqualSentinel(comptime T: type, comptime sentinel: T, expected: [:sentinel]const T, actual: [:sentinel]const T) !void
This function is intended to be used only in tests. Checks that two slices or tw…
This function is intended to be used only in tests. Checks that two slices or two arrays are equal, including that their sentinel (if any) are the same. Will error if given another type.
fn expectEqualSlices(comptime T: type, expected: []const T, actual: []const T) !void
This function is intended to be used only in tests. When the two slices are not …
This function is intended to be used only in tests. When the two slices are not equal, prints diagnostics to stderr to show exactly how they are not equal (with the differences highlighted in red), then returns a test failure error. The colorized output is optional and controlled by the return of
std.io.tty.detectConfig()
. If your inputs are UTF-8 encoded strings, consider callingexpectEqualStrings
instead.fn expectError(expected_error: anyerror, actual_error_union: anytype) !void
This function is intended to be used only in tests. It prints diagnostics to std…
This function is intended to be used only in tests. It prints diagnostics to stderr and then returns a test failure error when actual_error_union is not expected_error.
fn expectFmt(expected: []const u8, comptime template: []const u8, args: anytype) !void
This function is intended to be used only in tests. When the formatted result of…
This function is intended to be used only in tests. When the formatted result of the template and its arguments does not equal the expected text, it prints diagnostics to stderr to show how they are not equal, then returns an error.
fn expectStringEndsWith(actual: []const u8, expected_ends_with: []const u8) !void
No documentation provided.
fn expectStringStartsWith(actual: []const u8, expected_starts_with: []const u8) !void
No documentation provided.
fn refAllDecls(comptime T: type) void
Given a type, references all the declarations inside, so that the semantic analy…
Given a type, references all the declarations inside, so that the semantic analyzer sees them.
fn refAllDeclsRecursive(comptime T: type) void
Given a type, recursively references all the declarations inside, so that the se…
Given a type, recursively references all the declarations inside, so that the semantic analyzer sees them. For deep types, you may use
@setEvalBranchQuota
.
Values
allocator | undefined | This should only be used in temporary test programs. |
failing_allocator | undefined |