It is non-decreasing monotonic. fib(n) <= fib(n+1)
It is increasing monotonic after 1. fib(n) < fib(n+1)
Its domain and codomain are non-negative integers.
fib(n) + fib(n+1) == fib(n+2) Notice this is like the recursive solution except going the other way (addition not subtraction) and is missing the base case.
a, b, c = fib(n), fib(n+1), fib(n+2)
assert abs(c / b - phi) < abs(b / a - phi)You can also test that the sequence is increasing like `fib(n+2) > fib(n+1) > fib(n)`.
Unit testing elegant functions has no value.
(fib is often used as an example. But you asked how to test it.)
This is just an example of course but elegant functions might need to be tested.
Eg if you coded up an O(n) version of the Fibonacci calculation, you can check against the naive recursive one (or if you are feeling confident, you can check against the O(log n) solution via repeated squaring of matrices.)
let fib2 n =
let sq5 = sqrt(5.0)
((1.0 + sq5)/2.0)**(float n)/sq5
|> round |> intThese are fine for property-based testing, so long as you restrict yourself to the range in which you have a correct value. But at that point, you might as well just hard-code the first 93 fibonacci numbers (the most that will fit in a uint64_t) and be done with it.
Complex systems use that system everywhere. Why aren't we doing it for our code?
But you don't always have an oracle. So other properties still make sense.
As a simple example: if you code up a quantum mechanics simulator, that's hard, and I wouldn't be able to code up an oracle for you straight away. But I can tell you that you probably want to check that things like momentum and energy better be conserved.