Testing with Fuzzers
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>):
-
Fuzzers Overview
For now GdUnit provides only this very small set of Fuzzer implementations and will be extend later!
Fuzzer | Description |
---|---|
rangei(from, to) | Generates a random integer in the range from from to to , inclusive. |
eveni(from, to) | Generates an even integer in the range from from to to , inclusive. |
oddi(from, to) | Generates an odd integer in the range from from to to , inclusive. |
rangev2(from, to) | Generates a random 2D vector with each component in the range from from to to , inclusive. |
rangev3(from, to) | Generates a random 3D vector with each component in the range from from to to , inclusive. |
rand_str(min_length, max_length, charset) | Generates a random string with a length between min_length and max_length , inclusive, using characters from the specified charset . |
Using Fuzzers
To use a fuzzer, you only need to add the argument ‘fuzzer =
If your test is configured with a fuzzer argument, it will iterate multiple times with a new value generated by the fuzzer implementation.
The default number of iterations is set to 1000 and can be configured with the optional argument fuzzer_iterations
. If you want to have the same fuzzer results, you can set a seed with the optional argument fuzzer_seed
.
-
func test_name(fuzzer := <Fuzzer>, <fuzzer_iterations>, <fuzzer_seed>):
-
..
Here is an example of using a fuzzer that generates random values in the 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)
# using multiple fuzzers in test 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)
-
fuzzer_iterations
If you want to iterate more or less than the default of 1000 iterations, you can set the number of iterations using thefuzzer_iterations
argument.# execute this test 5000 times func test_fuzzer_inject_value(fuzzer := Fuzzers.rangei(-100000, 100000), fuzzer_iterations=5000):
-
fuzzer_seed
If you want to ensure consistent test results for a random generating fuzzer, you can specify a seed using thefuzzer_seed
argument.# execute this test with a seed value of 123456 func test_fuzzer_inject_value(fuzzer := Fuzzers.rangei(-100000, 100000), fuzzer_seed=123456):
Create a 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
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 a random value of a hard coded set of values is provided
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())]