5.1.42. Testing Tools (faker + fuzzer)

This tutorial covers two testing modules: daslib/faker for generating random test data, and daslib/fuzzer for running stress tests that detect crashes and invariant violations.

Prerequisites: Testing with dastest (Tutorial 27), Random Numbers (Tutorial 38).

require daslib/faker
require daslib/fuzzer

5.1.42.1. Faker basics

A Faker struct produces random values for every built-in type. It wraps an infinite random uint iterator internally:

var fake <- Faker()

print("{fake |> random_int}\n")      // random int (full range)
print("{fake |> random_uint}\n")     // random uint (full range)
print("{fake |> random_float}\n")    // random float (raw bits)
print("{fake |> random_double}\n")   // random double (raw bits)

// Random bool (derived from random_uint)
let b = (fake |> random_uint) % 2u == 0u

delete fake

Note

random_float and random_double generate raw bit patterns — the values can be NaN, Inf, or denormalized. This is intentional for fuzz testing.

5.1.42.2. Random strings and file names

var fake <- Faker()
let s = fake |> any_string()         // random characters
let fn = fake |> any_file_name       // alphanumeric + underscore + dot
let ls = fake |> long_string()       // up to max_long_string bytes
delete fake
  • any_string — random characters up to the regex generator limit

  • any_file_name — file-name-safe characters

  • long_string — may be very long (configurable via fake.max_long_string)

5.1.42.3. Random vectors

Faker generates vectors of all sizes for every numeric type:

var fake <- Faker()
print("{fake |> random_int2}\n")
print("{fake |> random_int3}\n")
print("{fake |> random_float2}\n")
print("{fake |> random_float3}\n")
delete fake

5.1.42.4. Random dates

Faker generates random dates within a configurable year range:

var fake <- Faker()
print("{fake |> date}\n")    // "DayOfWeek, MonthName DD, YYYY"
print("{fake |> day}\n")     // "DayOfWeek"
delete fake

5.1.42.5. Customizing Faker

Faker has configurable fields to control the output:

var fake <- Faker()
fake.min_year = 2020u          // restrict year range
fake.total_years = 5u          // 2020-2025
fake.max_long_string = 32u     // limit long_string length
delete fake

5.1.42.6. fuzz — silent crash detection

fuzz(count, block) runs a block count times, catching any panics. Use it to test that your code handles arbitrary input gracefully:

def safe_divide(a, b : int) : int {
    if (b == 0) {
        return 0
    }
    return a / b
}

var fake <- Faker()
fuzz(100) {
    let a = fake |> random_int
    let b = fake |> random_int
    safe_divide(a, b)
}
delete fake

If any iteration panics, fuzz catches it silently and continues.

5.1.42.7. fuzz_debug — verbose crash detection

fuzz_debug is identical to fuzz but does NOT catch panics. Replace fuzz with fuzz_debug when you need to see the actual error message and stack trace:

var fake <- Faker()
fuzz_debug(50) {
    let a = fake |> random_int
    let b = fake |> random_int
    safe_divide(a, b)
}
delete fake

5.1.42.8. Property-based testing

Combine faker + fuzzer for property-based testing: generate random inputs and verify that invariants always hold:

def clamp_value(x, lo, hi : int) : int {
    if (x < lo) {
        return lo
    }
    if (x > hi) {
        return hi
    }
    return x
}

var fake <- Faker()
var violations = 0
fuzz(1000) {
    let x = fake |> random_int
    let result = clamp_value(x, -100, 100)
    if (result < -100 || result > 100) {
        violations ++
    }
}
print("violations: {violations}/1000\n")    // 0
delete fake

5.1.42.9. Testing string operations

Faker’s any_string is useful for testing string-processing functions:

var fake <- Faker()
var failures = 0
fuzz(100) {
    let s = fake |> any_string()
    let reversed = reverse_string(s)
    let double_rev = reverse_string(reversed)
    if (double_rev != s) {
        failures ++
    }
}
delete fake

5.1.42.10. Summary

Function

Description

Faker()

Create faker with default RNG

fake |> random_int

Random int (full range)

fake |> random_uint

Random uint (full range)

fake |> random_float

Random float (raw bits — may be NaN/Inf)

fake |> any_string()

Random string

fake |> any_file_name

Random file-name-safe string

fake |> long_string()

Random byte string (up to max_long_string)

fake |> date

Random date string

fake |> day

Random day-of-week string

fuzz(n) <| block

Run block n times, catch panics

fuzz_debug(n) <| block

Run block n times, panics propagate

See also

Testing — testing framework tutorial.

Random Numbers — random number generation.

Full source: tutorials/language/42_testing_tools.das

Previous tutorial: Serialization (archive)

Next tutorial: Interfaces