Link Search Menu Expand Document

Testing with Fuzzers

Fuzzing is current only supported for GdScripts!

Definition

Fuzz Testing or Fuzzing is a software testing technique of putting invalid or random data called FUZZ into software system to discover coding errors and security loopholes. The purpose of fuzz testing is inserting data using automated or semi-automated techniques and testing the system for various exceptions like system crashing or failure of built-in code, etc.

  •     func test_my_test(fuzzer := <Fuzzer>, <fuzzer_iterations>, <fuzzer_seed>):
    

Using Fuzzers

To use a fuzzer you only need to extend you test by the argument ‘fuzzer = '.

  • The fuzzer argument name must always start with a prefix fuzzer, allowed pattern is ['_', 'a-z', 'A_Z', '0-9'].

        func test_name(fuzzer := <Fuzzer>, <fuzzer_iterations>, <fuzzer_seed>):
    
  •     ..
    

If your test is configured with an fuzzer argument it will be now iterate multiple times with an new value given by the fuzzer implementation.

The default iteration is set to 1000 and can by configured by the optional argument ‘fuzzer_iterations’. If you want to have the same fuzzer results you can configure a seed by the optional argument ‘fuzzer_seed’

    func test_name(fuzzer := <Fuzzer>, <fuzzer_iterations>, <fuzzer_seed>):

Here an example to use a fuzzer where produces random values in a range from -23 to 22 and iterates 100 times

    func test_fuzzer_inject_value(fuzzer := Fuzzers.rangei(-23, 22), fuzzer_iterations = 100):
        assert_int(fuzzer.next_value()).is_in_range(-23, 22)

multiple fuzzers are allowed

    func test_fuzzer_inject_value(fuzzer_a := Fuzzers.rangei(-23, 22), fuzzer_b := Fuzzers.rangei(0, 42), fuzzer_iterations = 100):
        assert_int(fuzzer_a.next_value()).is_in_range(-23, 22)
        assert_int(fuzzer_b.next_value()).is_in_range(-23, 22)

Configure Fuzzer Iterations

If you want to iterate more than the default of 1000 iterations you can do this by set the amount of iteration by the ‘fuzzer_iterations’ argument.

    # execute this test 5000 times
    func test_fuzzer_inject_value(fuzzer := Fuzzers.rangei(-100000, 100000), fuzzer_iterations=5000):

Setting Fuzzer Seed

If you want to have always the same test results for a random generating fuzzer you can specifiy a seed by the ‘fuzzer_seed’ argument.

    # execute this test with a seed value of 123456
    func test_fuzzer_inject_value(fuzzer := Fuzzers.rangei(-100000, 100000), fuzzer_seed=123456):

Fuzzers

For now GdUnit provides only this very small set of Fuzzer implementations and will be extend later!

Fuzzer Description
rangei(from, to) Generates an random integer in a range form to
eveni(from, to) Generates an integer in a range form to that can be divided exactly by 2
oddi(from, to) Generates an integer in a range form to that cannot be divided exactly by 2
rangev2(from, to) Generates an random Vector2 in a range form to
rangev3(from, to) Generates an random Vector3 in a range form to
rand_str(min_length, max_length, charset) Generates an random string value by a given min_length and max_length and specified charset

Create Custom Fuzzer

If you need a custom fuzzer you do this by extend from class ‘Fuzzer’ and implement the function ‘next_value’

    # Base interface for fuzz testing
    # https://en.wikipedia.org/wiki/Fuzzing
    class_name Fuzzer
    extends Resource

        # generates the next fuzz value
        # needs to be implement 
        func next_value():
            push_error("Invalid vall. Fuzzer not implemented 'next_value()'")
            return null

Here a small example custom fuzzer implementation

    # a simple test fuzzer where provided a hard coded value set
    class TestFuzzer extends Fuzzer:
        var _data := [2, 3, 5, 7, 11, 13, 17, 19, 23, 29]

        func next_value():
            return _data[randi_range(0, _data.size())]

Copyright © 2021-2022 Mike Schulze. Distributed by an MIT license.