The function would fail if test_func(x_lo) has the same sign as test_func(x_hi). Otherwise it could compute a first derivative from these points to estimate the intersection with the x axis. Having got a first estimate of the root it could then compute a new first derivative at that point and then iterate until stable.