123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112 |
- //
- // 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(add(41, 1), 42);
- // 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));
- }
|