mirror of
https://codeberg.org/ziglings/exercises.git
synced 2026-06-08 07:50:00 +00:00
Insert space for additional async exercises
This commit is contained in:
96
exercises/105_testing.zig
Normal file
96
exercises/105_testing.zig
Normal file
@@ -0,0 +1,96 @@
|
||||
//
|
||||
// A big advantage of Zig is the integration of its own test system.
|
||||
// This allows the philosophy of Test Driven Development (TDD) to be
|
||||
// implemented perfectly. Zig even goes one step further than other
|
||||
// languages, the tests can be included directly in the source file.
|
||||
//
|
||||
// This has several advantages. On the one hand it is much clearer to
|
||||
// have everything in one file, both the source code and the associated
|
||||
// test code. On the other hand, it is much easier for third parties
|
||||
// to understand what exactly a function is supposed to do if they can
|
||||
// simply look at the test inside the source and compare both.
|
||||
//
|
||||
// Especially if you want to understand how e.g. the standard library
|
||||
// of Zig works, this approach is very helpful. Furthermore it is very
|
||||
// practical, if you want to report a bug to the Zig community, to
|
||||
// illustrate it with a small example including a test.
|
||||
//
|
||||
// Therefore, in this exercise we will deal with the basics of testing
|
||||
// in Zig. Basically, tests work as follows: you pass certain parameters
|
||||
// to a function, for which you get a return - the result. This is then
|
||||
// compared with the EXPECTED value. If both values match, the test is
|
||||
// passed, otherwise an error message is displayed.
|
||||
//
|
||||
// testing.expect(foo(param1, param2) == expected);
|
||||
//
|
||||
// Also other comparisons are possible, deviations or also errors can
|
||||
// be provoked, which must lead to an appropriate behavior of the
|
||||
// function, so that the test is passed.
|
||||
//
|
||||
// Tests can be run via Zig build system or applied directly to
|
||||
// individual modules using "zig test xyz.zig".
|
||||
//
|
||||
// Both can be used script-driven to execute tests automatically, e.g.
|
||||
// after checking into a Git repository. Something we also make extensive
|
||||
// use of here at Ziglings.
|
||||
//
|
||||
const std = @import("std");
|
||||
const testing = std.testing;
|
||||
|
||||
// This is a simple function that builds a sum from the passed parameters and
|
||||
// returns.
|
||||
fn add(a: f16, b: f16) f16 {
|
||||
return a + b;
|
||||
}
|
||||
|
||||
// The associated test. It always starts with the keyword "test", followed by a
|
||||
// description of the tasks of the test. This is followed by the test cases in
|
||||
// curly brackets.
|
||||
test "add" {
|
||||
|
||||
// The first test checks if the sum of '41' and '1' gives '42', which is
|
||||
// correct.
|
||||
try testing.expect(add(41, 1) == 42);
|
||||
|
||||
// Another way to perform this test is as follows:
|
||||
try testing.expectEqual(42, add(41, 1));
|
||||
|
||||
// This time a test with the addition of a negative number:
|
||||
try testing.expect(add(5, -4) == 1);
|
||||
|
||||
// And a floating point operation:
|
||||
try testing.expect(add(1.5, 1.5) == 3);
|
||||
}
|
||||
|
||||
// Another simple function that returns the result of subtracting the two
|
||||
// parameters.
|
||||
fn sub(a: f16, b: f16) f16 {
|
||||
return a - b;
|
||||
}
|
||||
|
||||
// The corresponding test is not much different from the previous one. Except
|
||||
// that it contains an error that you need to correct.
|
||||
test "sub" {
|
||||
try testing.expect(sub(10, 5) == 6);
|
||||
|
||||
try testing.expect(sub(3, 1.5) == 1.5);
|
||||
}
|
||||
|
||||
// This function divides the numerator by the denominator. Here it is important
|
||||
// that the denominator must not be zero. This is checked and if it occurs an
|
||||
// error is returned.
|
||||
fn divide(a: f16, b: f16) !f16 {
|
||||
if (b == 0) return error.DivisionByZero;
|
||||
return a / b;
|
||||
}
|
||||
|
||||
test "divide" {
|
||||
try testing.expect(divide(2, 2) catch unreachable == 1);
|
||||
try testing.expect(divide(-1, -1) catch unreachable == 1);
|
||||
try testing.expect(divide(10, 2) catch unreachable == 5);
|
||||
try testing.expect(divide(1, 3) catch unreachable == 0.3333333333333333);
|
||||
|
||||
// Now we test if the function returns an error if we pass a zero as
|
||||
// denominator. But which error needs to be tested?
|
||||
try testing.expectError(error.???, divide(15, 0));
|
||||
}
|
||||
Reference in New Issue
Block a user