Socialify

Folder ..

Viewing 102_testing.zig
112 lines (100 loc) • 3.7 KB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
//
// 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));
}